public class BackPressureStatsTrackerImpl implements BackPressureStatsTracker {
   private static final Logger LOG = LoggerFactory.getLogger(BackPressureStatsTrackerImpl.class);
   /** Maximum stack trace depth for samples. */
   static final int MAX_STACK_TRACE_DEPTH = 3;
   /** Expected class name for back pressure indicating stack trace element. */
   static final String EXPECTED_CLASS_NAME = "org.apache.flink.runtime.io.network.buffer.LocalBufferPool";
   /** Expected method name for back pressure indicating stack trace element. */
   static final String EXPECTED_METHOD_NAME = "requestBufferBuilderBlocking";
   /** Lock guarding trigger operations. */
   private final Object lock = new Object();
   /* Stack trace sample coordinator. */
   private final StackTraceSampleCoordinator coordinator;
@Override
public BufferBuilder requestBufferBuilderBlocking() throws IOException, InterruptedException {
   return toBufferBuilder(requestMemorySegment(true));
}
private MemorySegment requestMemorySegment(boolean isBlocking) throws InterruptedException, IOException {
   synchronized (availableMemorySegments) {
      returnExcessMemorySegments();
      boolean askToRecycle = owner
!= null;
      // fill
availableMemorySegments with at least one element, wait if required
      while (availableMemorySegments.isEmpty())
{
         if (isDestroyed) {
            throw new IllegalStateException("Buffer
pool is destroyed.");
         }
         if (numberOfRequestedMemorySegments
< currentPoolSize) {
            final MemorySegment segment = networkBufferPool.requestMemorySegment();
            if (segment != null) {
               numberOfRequestedMemorySegments++;
               return segment;
            }
         }
         if (askToRecycle)
{
            owner.releaseMemory(1);
         }
         if (isBlocking)
{
            availableMemorySegments.wait(2000);
         }
         else {
            return null;
         }
      }
      return availableMemorySegments.poll();
   }
/**
 * Returns back pressure statistics for a operator. Automatically triggers stack trace sampling
 * if statistics are not available or outdated.
 *
 * @param vertex Operator to get the stats for.
 * @return Back pressure statistics for an operator
 */
public Optional<OperatorBackPressureStats> getOperatorBackPressureStats(ExecutionJobVertex vertex) {
   synchronized (lock) {
      final OperatorBackPressureStats stats = operatorStatsCache.getIfPresent(vertex);
      if (stats == null || backPressureStatsRefreshInterval <= System.currentTimeMillis() - stats.getEndTimestamp()) {
         triggerStackTraceSampleInternal(vertex);
      }
      return Optional.ofNullable(stats);
   }
}
/**
 * Triggers a stack trace sample for a operator to gather the back pressure
 * statistics. If there is a sample in progress for the operator, the call
 * is ignored.
 *
 * @param vertex Operator to get the stats for.
 * @return Flag indicating whether a sample with triggered.
 */
private boolean triggerStackTraceSampleInternal(final ExecutionJobVertex vertex) {
   assert(Thread.holdsLock(lock));
   if (shutDown) {
      return false;
   }
   if (!pendingStats.contains(vertex) &&
      !vertex.getGraph().getState().isGloballyTerminalState()) {
      Executor executor = vertex.getGraph().getFutureExecutor();
      // Only trigger if still active job
      if (executor != null) {
         pendingStats.add(vertex);
         if (LOG.isDebugEnabled()) {
            LOG.debug("Triggering stack trace sample for tasks: " + Arrays.toString(vertex.getTaskVertices()));
         }
         CompletableFuture<StackTraceSample> sample = coordinator.triggerStackTraceSample(
            vertex.getTaskVertices(),
            numSamples,
            delayBetweenSamples,
            MAX_STACK_TRACE_DEPTH);
         sample.handleAsync(new StackTraceSampleCompletionCallback(vertex), executor);
         return true;
      }
   }
   return false;
}