@SuppressWarnings({"squid:S3776", "squid:S2446"}) // Suppress high Cognitive Complexity warning
  private ISession getSession() throws IoTDBConnectionException {
    ISession session = queue.poll();
    if (closed) {
      throw new IoTDBConnectionException(SESSION_POOL_IS_CLOSED);
    }
    if (session != null) {
      return session;
    }

    boolean shouldCreate = false;

    long start = System.currentTimeMillis();
    while (session == null) {
      synchronized (this) {
        if (size < maxSize) {
          // we can create more session
          size++;
          shouldCreate = true;
          // but we do it after skip synchronized block because connection a session is time
          // consuming.
          break;
        }

        // we have to wait for someone returns a session.
        try {
          this.wait(1000);
          long timeOut = Math.min(waitToGetSessionTimeoutInMs, 60_000);
          if (System.currentTimeMillis() - start > timeOut) {
            LOGGER.warn(
                "the SessionPool has wait for {} seconds to get a new connection: {} with {}",
                (System.currentTimeMillis() - start) / 1000,
                formattedNodeUrls,
                user);
            LOGGER.warn(
                "current occupied size {}, queue size {}, considered size {} ",
                occupied.size(),
                queue.size(),
                size);
            if (System.currentTimeMillis() - start > waitToGetSessionTimeoutInMs) {
              throw new IoTDBConnectionException(
                  String.format("timeout to get a connection from %s", formattedNodeUrls));
            }
          }
        } catch (InterruptedException e) {
          LOGGER.warn("Interrupted!", e);
          Thread.currentThread().interrupt();
          // wake up from this.wait(1000) by this.notify()
        }

        session = queue.poll();

        // for putBack or size--
        this.notify();

        if (closed) {
          throw new IoTDBConnectionException(SESSION_POOL_IS_CLOSED);
        }
      }
    }

    if (shouldCreate) {
      // create a new one.

      session = constructNewSession();

      try {
        session.open(
            enableCompression,
            connectionTimeoutInMs,
            deviceIdToEndpoint,
            tableModelDeviceIdToEndpoint,
            availableNodes);
        // avoid someone has called close() the session pool
        synchronized (this) {
          if (closed) {
            // have to release the connection...
            session.close();
            throw new IoTDBConnectionException(SESSION_POOL_IS_CLOSED);
          }
        }
      } catch (IoTDBConnectionException e) {
        // if exception, we will throw the exception.
        // Meanwhile, we have to set size--
        synchronized (this) {
          size--;
          // we do not need to notifyAll as any waited thread can continue to work after waked up.
          this.notify();
        }
        throw e;
      }
    }

    return session;
  }
Timeout of query can be set by users. A negative number means using the default configuration
of server. And value 0 will disable the function of query timeout.
iotdb-client/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java