private boolean addSlowAckData(DatanodeInfo datanodeInfo, long dataLength, long processTime) {
    Deque<PacketAckData> slowDNQueue = datanodeSlowDataQueue.getUnchecked(datanodeInfo);
    long current = EnvironmentEdgeManager.currentTime();
    while (
      !slowDNQueue.isEmpty() && (current - slowDNQueue.getFirst().getTimestamp() > slowDataTtl
        || slowDNQueue.size() >= minSlowDetectCount)
    ) {
      slowDNQueue.removeFirst();
    }
    slowDNQueue.addLast(new PacketAckData(dataLength, processTime));
    return slowDNQueue.size() >= minSlowDetectCount;
  }
Check if the packet process time shows that the relevant datanode is a slow node.
@param datanodeInfo     the datanode that processed the packet
@param packetDataLen    the data length of the packet (in bytes)
@param processTimeMs    the process time (in ms) of the packet on the datanode,
@param lastAckTimestamp the last acked timestamp of the packet on another datanode
@param unfinished       if the packet is unfinished flushed to the datanode replicas
hbase-asyncfs/src/main/java/org/apache/hadoop/hbase/io/asyncfs/monitor/StreamSlowMonitor.java