code: private void await() {
      try {
        // Clean up all filter join leaf nodes that have been converted
        boolean nodeRemoved = this.removeConvertedNodes(root);
        // If some nodes were removed, it means that we converted in the previous iteration
        // at least one filter join into a field data terms query. We don't have to wait since
        // we might have new filter join leaf nodes.
        if (!nodeRemoved && root.hasChildren()) {
          logger.debug("Visitor thread block - blocking queue size: {}", blockingQueue.size());
          this.blockingQueue.take();   // block until one async action is completed
          this.blockingQueue.offer(0); // add back the element to the queue, it will be removed after the node conversion
          logger.debug("Visitor thread unblock - blocking queue size: {}", blockingQueue.size());
        }
      }
      catch (InterruptedException e) {
        logger.warn("Filter join visitor thread interrupted while waiting");
        Thread.currentThread().interrupt();
      }
    }
docs: Await for the completion of an async action.