code: public CompletableFuture<CloseableResource<T>> getResource() {
          CompletableFuture<CloseableResource<T>> future;
          boolean tryCreateNewResource = false;
          synchronized (lock) {
              T t = idleResources.poll();
              if (t != null) {
                  // return the object from the queue
                  future = CompletableFuture.completedFuture(new CloseableResource<>(t, this));
              } else {
                  future = new CompletableFuture<>();
                  WaitingRequest<T> request = new WaitingRequest<>(future);
                  waitQueue.add(request);
                  tryCreateNewResource = true;
              }
          }
  
          if (tryCreateNewResource) {
              tryCreateNewResource();
          }
  
          return future;
      }
docs: Method to get a resource initialized with supplied arg.
  This method attempts to find an existing available resource.
  If not found, it submits a new waiting request for whenever a resource becomes available. A resource could become available
  because such a resource was returned to the pool or a new resource was created.
  It also opportunistically submits a request to create a new resource if required.
  
  @return A completableFuture which when completed will have the resource object that the caller requested.