Java Code Examples for io.netty.channel.ChannelPromise#addListener()

The following examples show how to use io.netty.channel.ChannelPromise#addListener() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ClientConnectionImpl.java    From pravega with Apache License 2.0 6 votes vote down vote up
private void write(Append cmd) throws ConnectionFailedException {
    Channel channel = nettyHandler.getChannel();
    EventLoop eventLoop = channel.eventLoop();
    ChannelPromise promise = channel.newPromise();
    promise.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
            throttle.release(cmd.getDataLength());
            nettyHandler.setRecentMessage();
            if (!future.isSuccess()) {
                future.channel().pipeline().fireExceptionCaught(future.cause());
            }
        }
    });
    // Work around for https://github.com/netty/netty/issues/3246
    eventLoop.execute(() -> {
        try {
            if (!closed.get()) {
                channel.write(cmd, promise);
            }
        } catch (Exception e) {
            channel.pipeline().fireExceptionCaught(e);
        }
    });
    Exceptions.handleInterrupted(() -> throttle.acquire(cmd.getDataLength()));
}
 
Example 2
Source File: ClientConnectionImpl.java    From pravega with Apache License 2.0 6 votes vote down vote up
private void write(WireCommand cmd) throws ConnectionFailedException {
    Channel channel = nettyHandler.getChannel();
    EventLoop eventLoop = channel.eventLoop();
    ChannelPromise promise = channel.newPromise();
    promise.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
            nettyHandler.setRecentMessage();
            if (!future.isSuccess()) {
                future.channel().pipeline().fireExceptionCaught(future.cause());
            }
        }
    });
    // Work around for https://github.com/netty/netty/issues/3246
    eventLoop.execute(() -> {
        try {
            if (!closed.get()) {
                channel.write(cmd, promise);
            }
        } catch (Exception e) {
            channel.pipeline().fireExceptionCaught(e);
        }
    });
}
 
Example 3
Source File: ChannelMetricsHandler.java    From reactor-netty with Apache License 2.0 6 votes vote down vote up
@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,
		SocketAddress localAddress, ChannelPromise promise) throws Exception {
	long connectTimeStart = System.nanoTime();
	super.connect(ctx, remoteAddress, localAddress, promise);
	promise.addListener(future -> {
		ctx.pipeline().remove(this);

		String status;
		if (future.isSuccess()) {
			status = SUCCESS;
		}
		else {
			status = ERROR;
		}
		recorder.recordConnectTime(
				remoteAddress,
				Duration.ofNanos(System.nanoTime() - connectTimeStart),
				status);
	});
}
 
Example 4
Source File: ConnectInterceptingHandler.java    From java-dcp-client with Apache License 2.0 6 votes vote down vote up
/**
 * Intercept the connect phase and store the original promise.
 */
@Override
public void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress,
                    final SocketAddress localAddress, final ChannelPromise promise) throws Exception {
  originalPromise = promise;
  ChannelPromise inboundPromise = ctx.newPromise();
  inboundPromise.addListener(new GenericFutureListener<Future<Void>>() {
    @Override
    public void operationComplete(Future<Void> future) throws Exception {
      if (!future.isSuccess() && !originalPromise.isDone()) {
        originalPromise.setFailure(future.cause());
      }
    }
  });
  ctx.connect(remoteAddress, localAddress, inboundPromise);
}
 
Example 5
Source File: HttpsRelayServiceHandler.java    From nomulus with Apache License 2.0 6 votes vote down vote up
/** Terminates connection upon outbound exception. */
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
    throws Exception {
  promise.addListener(
      (ChannelFuture channelFuture) -> {
        if (!channelFuture.isSuccess()) {
          Throwable cause = channelFuture.cause();
          if (NON_FATAL_OUTBOUND_EXCEPTIONS.contains(Throwables.getRootCause(cause).getClass())) {
            logger.atWarning().withCause(channelFuture.cause()).log(
                "Outbound exception caught for channel %s", channelFuture.channel());
          } else {
            logger.atSevere().withCause(channelFuture.cause()).log(
                "Outbound exception caught for channel %s", channelFuture.channel());
          }
          ChannelFuture unusedFuture = channelFuture.channel().close();
        }
      });
  super.write(ctx, msg, promise);
}
 
Example 6
Source File: WriteStreamSubscriberFutureListenersTest.java    From servicetalk with Apache License 2.0 6 votes vote down vote up
public WriteStreamSubscriberFutureListenersTest() {
    listeners = new LinkedBlockingQueue<>();
    channel = new EmbeddedChannel(new ChannelOutboundHandlerAdapter() {
        @Override
        public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise)
                throws Exception {
            ChannelFutureListener listener = mock(ChannelFutureListener.class);
            listeners.add(listener);
            promise.addListener(listener);
            super.write(ctx, msg, promise);
        }
    });
    WriteDemandEstimator estimator = WriteDemandEstimators.newDefaultEstimator();
    TestCompletableSubscriber completableSubscriber = new TestCompletableSubscriber();
    subscriber = new WriteStreamSubscriber(channel, estimator, completableSubscriber,
            UNSUPPORTED_PROTOCOL_CLOSE_HANDLER);
    TestSubscription subscription = new TestSubscription();
    subscriber.onSubscribe(subscription);
    assertThat("No items requested.", subscription.requested(), greaterThan(0L));
}
 
Example 7
Source File: ClientConnectionImpl.java    From pravega with Apache License 2.0 6 votes vote down vote up
@Override
public void sendAsync(List<Append> appends, CompletedCallback callback) {
    Channel ch;
    try {
        checkClientConnectionClosed();
        ch = nettyHandler.getChannel();
    } catch (ConnectionFailedException e) {
        callback.complete(new ConnectionFailedException("Connection to " + connectionName + " is not established."));
        return;
    }
    PromiseCombiner combiner = new PromiseCombiner(ImmediateEventExecutor.INSTANCE);
    for (Append append : appends) {
        combiner.add(ch.write(append));
    }
    ch.flush();
    ChannelPromise promise = ch.newPromise();
    promise.addListener(future -> {
        nettyHandler.setRecentMessage();
        Throwable cause = future.cause();
        callback.complete(cause == null ? null : new ConnectionFailedException(cause));
    });
    combiner.finish(promise);
}
 
Example 8
Source File: NettyIoSession.java    From termd with Apache License 2.0 6 votes vote down vote up
@Override
public IoWriteFuture write(Buffer buffer) {
  ByteBuf buf = Unpooled.buffer(buffer.available());
  buf.writeBytes(buffer.array(), buffer.rpos(), buffer.available());
  NettyIoWriteFuture msg = new NettyIoWriteFuture();
  ChannelPromise next = context.newPromise();
  prev.addListener(whatever -> {
    if (context != null) {
      context.writeAndFlush(buf, next);
    }
  });
  prev = next;
  next.addListener(fut -> {
    if (fut.isSuccess()) {
      msg.setValue(Boolean.TRUE);
    } else {
      msg.setValue(fut.cause());
    }
  });
  return msg;
}
 
Example 9
Source File: Http2MultiplexCodecTest.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
@Test
public void channelClosedWhenCloseListenerCompletes() {
    LastInboundHandler inboundHandler = streamActiveAndWriteHeaders(inboundStream);
    Http2StreamChannel childChannel = (Http2StreamChannel) inboundHandler.channel();

    assertTrue(childChannel.isOpen());
    assertTrue(childChannel.isActive());

    final AtomicBoolean channelOpen = new AtomicBoolean(true);
    final AtomicBoolean channelActive = new AtomicBoolean(true);

    // Create a promise before actually doing the close, because otherwise we would be adding a listener to a future
    // that is already completed because we are using EmbeddedChannel which executes code in the JUnit thread.
    ChannelPromise p = childChannel.newPromise();
    p.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) {
            channelOpen.set(future.channel().isOpen());
            channelActive.set(future.channel().isActive());
        }
    });
    childChannel.close(p).syncUninterruptibly();

    assertFalse(channelOpen.get());
    assertFalse(childChannel.isActive());
}
 
Example 10
Source File: PassportStateHttpServerHandler.java    From zuul with Apache License 2.0 5 votes vote down vote up
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception
{
    CurrentPassport passport = passport(ctx);
    
    // Set into the SENDING state.
    if (msg instanceof HttpResponse) {
        passport.add(PassportState.OUT_RESP_HEADERS_SENDING);
        promise.addListener(new PassportStateListener(passport, 
                PassportState.OUT_RESP_HEADERS_SENT,
                PassportState.OUT_RESP_HEADERS_ERROR_SENDING));
    }

    if (msg instanceof LastHttpContent) {
        passport.add(PassportState.OUT_RESP_LAST_CONTENT_SENDING);
        promise.addListener(new PassportStateListener(passport, 
                PassportState.OUT_RESP_LAST_CONTENT_SENT,
                PassportState.OUT_RESP_LAST_CONTENT_ERROR_SENDING));
    }
    else if (msg instanceof HttpContent) {
        passport.add(PassportState.OUT_RESP_CONTENT_SENDING);
        promise.addListener(new PassportStateListener(passport, 
                PassportState.OUT_RESP_CONTENT_SENT, 
                PassportState.OUT_RESP_CONTENT_ERROR_SENDING));
    }
    
    // Continue with the write.
    super.write(ctx, msg, promise);
}
 
Example 11
Source File: WhoisServiceHandler.java    From nomulus with Apache License 2.0 5 votes vote down vote up
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
    throws Exception {
  // Close connection after a response is received, per RFC-3912
  // https://tools.ietf.org/html/rfc3912
  checkArgument(msg instanceof HttpResponse);
  promise.addListener(ChannelFutureListener.CLOSE);
  super.write(ctx, msg, promise);
}
 
Example 12
Source File: MessageEncoder.java    From openzaly with Apache License 2.0 5 votes vote down vote up
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
	promise.addListener(new GenericFutureListener<Future<? super Void>>() {

		public void operationComplete(Future<? super Void> future) throws Exception {
			if (!future.isSuccess()) {
				logger.error("write data to client fail ", future.cause());
			}
		}
	});

	super.write(ctx, msg, promise);
}
 
Example 13
Source File: NettyServerHandler.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
private void closeStreamWhenDone(ChannelPromise promise, int streamId) throws Http2Exception {
  final NettyServerStream.TransportState stream = serverStream(requireHttp2Stream(streamId));
  promise.addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) {
      stream.complete();
    }
  });
}
 
Example 14
Source File: KeyValueErrorMapHandler.java    From couchbase-jvm-core with Apache License 2.0 5 votes vote down vote up
@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
                    ChannelPromise promise) throws Exception {
    originalPromise = promise;
    ChannelPromise downPromise = ctx.newPromise();
    downPromise.addListener(new GenericFutureListener<Future<Void>>() {
        @Override
        public void operationComplete(Future<Void> future) throws Exception {
            if (!future.isSuccess() && !originalPromise.isDone()) {
                originalPromise.setFailure(future.cause());
            }
        }
    });
    ctx.connect(remoteAddress, localAddress, downPromise);
}
 
Example 15
Source File: NettyServerHandler.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
private void closeStreamWhenDone(ChannelPromise promise, int streamId) throws Http2Exception {
  final NettyServerStream.TransportState stream = serverStream(requireHttp2Stream(streamId));
  promise.addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) {
      stream.complete();
    }
  });
}
 
Example 16
Source File: NetworkEventHandlerServer.java    From SynchronizeFX with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Override
public void write(final ChannelHandlerContext ctx, final Object msg,
        final ChannelPromise promise) throws Exception {
    promise.addListener(new GenericFutureListener<Future<? super Void>>() {
        @Override
        public void operationComplete(final Future<? super Void> future) throws Exception {
            Throwable cause = future.cause();
            if (cause != null) {
                exceptionCaught(ctx, cause);
            }
        }
    });
    ctx.write(msg, promise);
}
 
Example 17
Source File: MessageEncoder.java    From wind-im with Apache License 2.0 5 votes vote down vote up
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
	promise.addListener(new GenericFutureListener<Future<? super Void>>() {

		public void operationComplete(Future<? super Void> future) throws Exception {
			if (!future.isSuccess()) {
				logger.error("write data to client fail ", future.cause());
			}
		}
	});

	super.write(ctx, msg, promise);
}
 
Example 18
Source File: NettyClientHandler.java    From grpc-java with Apache License 2.0 4 votes vote down vote up
/**
 * Sends a PING frame. If a ping operation is already outstanding, the callback in the message is
 * registered to be called when the existing operation completes, and no new frame is sent.
 */
private void sendPingFrameTraced(ChannelHandlerContext ctx, SendPingCommand msg,
    ChannelPromise promise) {
  // Don't check lifecycleManager.getShutdownStatus() since we want to allow pings after shutdown
  // but before termination. After termination, messages will no longer arrive because the
  // pipeline clears all handlers on channel close.

  PingCallback callback = msg.callback();
  Executor executor = msg.executor();
  // we only allow one outstanding ping at a time, so just add the callback to
  // any outstanding operation
  if (ping != null) {
    promise.setSuccess();
    ping.addCallback(callback, executor);
    return;
  }

  // Use a new promise to prevent calling the callback twice on write failure: here and in
  // NettyClientTransport.ping(). It may appear strange, but it will behave the same as if
  // ping != null above.
  promise.setSuccess();
  promise = ctx().newPromise();
  // set outstanding operation
  long data = USER_PING_PAYLOAD;
  Stopwatch stopwatch = stopwatchFactory.get();
  stopwatch.start();
  ping = new Http2Ping(data, stopwatch);
  ping.addCallback(callback, executor);
  // and then write the ping
  encoder().writePing(ctx, false, USER_PING_PAYLOAD, promise);
  ctx.flush();
  final Http2Ping finalPing = ping;
  promise.addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
      if (future.isSuccess()) {
        transportTracer.reportKeepAliveSent();
      } else {
        Throwable cause = future.cause();
        if (cause instanceof ClosedChannelException) {
          cause = lifecycleManager.getShutdownThrowable();
          if (cause == null) {
            cause = Status.UNKNOWN.withDescription("Ping failed but for unknown reason.")
                .withCause(future.cause()).asException();
          }
        }
        finalPing.failed(cause);
        if (ping == finalPing) {
          ping = null;
        }
      }
    }
  });
}
 
Example 19
Source File: HttpObjectEncoder.java    From servicetalk with Apache License 2.0 4 votes vote down vote up
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
    if (msg instanceof HttpMetaData) {
        if (state != ST_INIT) {
            throw new IllegalStateException("unexpected message type: " + simpleClassName(msg));
        }
        T metaData = castMetaData(msg);

        // We prefer a direct allocation here because it is expected the resulted encoded Buffer will be written
        // to a socket. In order to do the write to the socket the memory typically needs to be allocated in direct
        // memory and will be copied to direct memory if not. Using a direct buffer will avoid the copy.
        ByteBuf byteBuf = ctx.alloc().directBuffer((int) headersEncodedSizeAccumulator);
        Buffer stBuf = newBufferFrom(byteBuf);

        // Encode the message.
        encodeInitialLine(stBuf, metaData);
        state = isContentAlwaysEmpty(metaData) ? ST_CONTENT_ALWAYS_EMPTY :
                isTransferEncodingChunked(metaData.headers()) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;

        sanitizeHeadersBeforeEncode(metaData, state == ST_CONTENT_ALWAYS_EMPTY);

        encodeHeaders(metaData.headers(), byteBuf, stBuf);
        writeShortBE(byteBuf, CRLF_SHORT);
        closeHandler.protocolPayloadBeginOutbound(ctx);
        if (shouldClose(metaData)) {
            closeHandler.protocolClosingOutbound(ctx);
        }
        headersEncodedSizeAccumulator = HEADERS_WEIGHT_NEW * padSizeForAccumulation(byteBuf.readableBytes()) +
                                        HEADERS_WEIGHT_HISTORICAL * headersEncodedSizeAccumulator;
        ctx.write(byteBuf, promise);
    } else if (msg instanceof Buffer) {
        final Buffer stBuffer = (Buffer) msg;
        if (stBuffer.readableBytes() == 0) {
            // Bypass the encoder in case of an empty buffer, so that the following idiom works:
            //
            //     ch.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
            //
            // See https://github.com/netty/netty/issues/2983 for more information.
            // We can directly write EMPTY_BUFFER here because there is no need to worry about the buffer being
            // already released.
            ctx.write(EMPTY_BUFFER, promise);
        } else {
            switch (state) {
                case ST_INIT:
                    throw new IllegalStateException("unexpected message type: " + simpleClassName(msg));
                case ST_CONTENT_NON_CHUNK:
                    final long contentLength = calculateContentLength(stBuffer);
                    if (contentLength > 0) {
                        ctx.write(encodeAndRetain(stBuffer), promise);
                        break;
                    }

                    // fall-through!
                case ST_CONTENT_ALWAYS_EMPTY:
                    // Need to produce some output otherwise an IllegalStateException will be thrown as we did
                    // not write anything Its ok to just write an EMPTY_BUFFER as if there are reference count
                    // issues these will be propagated as the caller of the encodeAndRetain(...) method will
                    // release the original buffer. Writing an empty buffer will not actually write anything on
                    // the wire, so if there is a user error with msg it will not be visible externally
                    ctx.write(EMPTY_BUFFER, promise);
                    break;
                case ST_CONTENT_CHUNK:
                    PromiseCombiner promiseCombiner = new PromiseCombiner();
                    encodeChunkedContent(ctx, stBuffer, calculateContentLength(stBuffer), promiseCombiner);
                    promiseCombiner.finish(promise);
                    break;
                default:
                    throw new Error();
            }
        }
    } else if (msg instanceof HttpHeaders) {
        closeHandler.protocolPayloadEndOutbound(ctx);
        promise.addListener(f -> {
            if (f.isSuccess()) {
                // Only writes of the last payload that have been successfully written and flushed should emit
                // events. A CloseHandler should not get into a completed state on a failed write so that it can
                // abort and close the Channel when appropriate.
                closeHandler.protocolPayloadEndOutboundSuccess(ctx);
            }
        });
        final int oldState = state;
        state = ST_INIT;
        if (oldState == ST_CONTENT_CHUNK) {
            encodeAndWriteTrailers(ctx, (HttpHeaders) msg, promise);
        } else {
            ctx.write(EMPTY_BUFFER, promise);
        }
    }
}
 
Example 20
Source File: NettyClientHandler.java    From grpc-nebula-java with Apache License 2.0 4 votes vote down vote up
/**
 * Sends a PING frame. If a ping operation is already outstanding, the callback in the message is
 * registered to be called when the existing operation completes, and no new frame is sent.
 */
private void sendPingFrame(ChannelHandlerContext ctx, SendPingCommand msg,
    ChannelPromise promise) {
  // Don't check lifecycleManager.getShutdownStatus() since we want to allow pings after shutdown
  // but before termination. After termination, messages will no longer arrive because the
  // pipeline clears all handlers on channel close.

  PingCallback callback = msg.callback();
  Executor executor = msg.executor();
  // we only allow one outstanding ping at a time, so just add the callback to
  // any outstanding operation
  if (ping != null) {
    promise.setSuccess();
    ping.addCallback(callback, executor);
    return;
  }

  // Use a new promise to prevent calling the callback twice on write failure: here and in
  // NettyClientTransport.ping(). It may appear strange, but it will behave the same as if
  // ping != null above.
  promise.setSuccess();
  promise = ctx().newPromise();
  // set outstanding operation
  long data = USER_PING_PAYLOAD;
  Stopwatch stopwatch = stopwatchFactory.get();
  stopwatch.start();
  ping = new Http2Ping(data, stopwatch);
  ping.addCallback(callback, executor);
  // and then write the ping
  encoder().writePing(ctx, false, USER_PING_PAYLOAD, promise);
  ctx.flush();
  final Http2Ping finalPing = ping;
  promise.addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
      if (future.isSuccess()) {
        transportTracer.reportKeepAliveSent();
      } else {
        Throwable cause = future.cause();
        if (cause instanceof ClosedChannelException) {
          cause = lifecycleManager.getShutdownThrowable();
          if (cause == null) {
            cause = Status.UNKNOWN.withDescription("Ping failed but for unknown reason.")
                .withCause(future.cause()).asException();
          }
        }
        finalPing.failed(cause);
        if (ping == finalPing) {
          ping = null;
        }
      }
    }
  });
}