Example usage for io.netty.channel ChannelOutboundBuffer totalPendingWriteBytes

List of usage examples for io.netty.channel ChannelOutboundBuffer totalPendingWriteBytes

Introduction

In this page you can find the example usage for io.netty.channel ChannelOutboundBuffer totalPendingWriteBytes.

Prototype

public long totalPendingWriteBytes() 

Source Link

Usage

From source file:com.addthis.meshy.ChannelState.java

License:Apache License

public boolean send(final ByteBuf sendBuffer, final SendWatcher watcher, final int reportBytes) {
    int attempts = 1;
    while (channel.isActive()) {
        final boolean inEventLoop = channel.eventLoop().inEventLoop();
        // if this thread is the io loop for this channel: make sure it is allowed to do writes
        if (inEventLoop && !channel.isWritable()) {
            channel.unsafe().forceFlush();
        }/*from   w ww  .j a va  2  s.c  o m*/
        if (channel.isWritable() || (attempts >= 500)
        // if this thread is the io loop for this channel: block writes only based on the actual socket queue;
        // channel writability factors in queued writes from other threads that we can't get to until we finish.
                || (inEventLoop
                        && (channel.unsafe().outboundBuffer().size() < estimateMaxQueued(sendBuffer)))) {
            if (attempts >= 500) {
                log.warn(
                        "Forcing write despite channel being backed up to prevent possible distributed deadlock");
            }
            ChannelFuture future = channel.writeAndFlush(sendBuffer);
            future.addListener(ignored -> {
                meshy.sentBytes(reportBytes);
                if (watcher != null) {
                    watcher.sendFinished(reportBytes);
                }
            });
            return true;
        } else {
            if ((attempts % 100) == 0) {
                ChannelOutboundBuffer outboundBuffer = channel.unsafe().outboundBuffer();
                if (outboundBuffer != null) {
                    log.info(
                            "Sleeping write because channel is unwritable. Attempt: {}, Pending Bytes: {}, State: {}",
                            attempts, outboundBuffer.totalPendingWriteBytes(), this);
                }
            }
            sleepUninterruptibly(10, TimeUnit.MILLISECONDS);
            writeSleeps.incrementAndGet();
            sleepMeter.mark();
        }
        attempts += 1;
    }
    if (reportBytes > 0) {
        /**
         * if bytes == 0 then it's a sendComplete() and
         * there are plenty of legit cases when a client would
         * disconnect before sendComplete() makes it back. best
         * example is StreamService when EOF framing tells the
         * client we're done before sendComplete() framing does.
         */
        log.debug("{} writing [{}] to dead channel", this, reportBytes);
        if (watcher != null) {
            /**
             * for accounting, rate limiting reasons, we have to report these as sent.
             * no need to report 0 bytes since it's an accounting no-op.
             */
            watcher.sendFinished(reportBytes);
        }
    }
    sendBuffer.release();
    return false;
}