Example usage for io.netty.channel ChannelPromise addListener

List of usage examples for io.netty.channel ChannelPromise addListener

Introduction

In this page you can find the example usage for io.netty.channel ChannelPromise addListener.

Prototype

@Override
    ChannelPromise addListener(GenericFutureListener<? extends Future<? super Void>> listener);

Source Link

Usage

From source file:dorkbox.network.connection.registration.remote.RegistrationRemoteHandler.java

License:Apache License

final void cleanupPipeline(final MetaChannel metaChannel, final Runnable onConnectFinishRunnable) {
    final int idleTimeout = this.registrationWrapper.getIdleTimeout();

    try {/* ww w .j a va  2s  . c  om*/
        // REMOVE our channel wrapper (only used for encryption) with the actual connection
        ChannelHandler handler = metaChannel.connection = ((ConnectionRegistrationImpl) metaChannel.connection).connection;

        Channel channel;
        if (metaChannel.tcpChannel != null) {
            channel = metaChannel.tcpChannel;
        } else {
            channel = metaChannel.udpChannel;
        }

        // channel should NEVER == null! (we will always have TCP or UDP!)
        // we also ONLY want to add this to a single cleanup, NOT BOTH, because this must only run once!!
        final ChannelPromise channelPromise = channel.newPromise();
        channelPromise.addListener(new FutureListener<Void>() {
            @Override
            public void operationComplete(final Future<Void> future) throws Exception {
                EventLoop loop = channelPromise.channel().eventLoop();
                loop.execute(new Runnable() {
                    @Override
                    public void run() {
                        logger.trace("Notify Connection");

                        // safe cast, because it's always this way...
                        registrationWrapper.connectionConnected0((ConnectionImpl) metaChannel.connection);

                        // run things AFTER the onConnect() method is called...
                        // CLIENT - runs the deferred 'onMessage' events in the connection as needed
                        // SERVER - send 'onConnect' bounce back message to client
                        onConnectFinishRunnable.run();
                    }
                });
            }
        });

        if (metaChannel.tcpChannel != null) {
            cleanupPipeline0(idleTimeout, handler, metaChannel.tcpChannel, channelPromise, true);
        }

        if (metaChannel.udpChannel != null) {
            cleanupPipeline0(idleTimeout, handler, metaChannel.udpChannel, channelPromise, false);
        }
    } catch (Exception e) {
        logger.error("Error during pipeline replace", e);
    }
}

From source file:io.grpc.netty.NettyClientHandler.java

License:Apache License

/**
 * 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.
 *//*from  w w w.j  a va 2 s.c om*/
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;
                }
            }
        }
    });
}

From source file:io.grpc.netty.NettyServer.java

License:Apache License

@Override
public void start(ServerListener serverListener) throws IOException {
    listener = checkNotNull(serverListener, "serverListener");

    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup);/*from  w  ww .  jav a 2  s.com*/
    b.channelFactory(channelFactory);
    // For non-socket based channel, the option will be ignored.
    b.option(SO_BACKLOG, 128);
    b.childOption(SO_KEEPALIVE, true);

    if (channelOptions != null) {
        for (Map.Entry<ChannelOption<?>, ?> entry : channelOptions.entrySet()) {
            @SuppressWarnings("unchecked")
            ChannelOption<Object> key = (ChannelOption<Object>) entry.getKey();
            b.childOption(key, entry.getValue());
        }
    }

    b.childHandler(new ChannelInitializer<Channel>() {
        @Override
        public void initChannel(Channel ch) {

            ChannelPromise channelDone = ch.newPromise();

            long maxConnectionAgeInNanos = NettyServer.this.maxConnectionAgeInNanos;
            if (maxConnectionAgeInNanos != MAX_CONNECTION_AGE_NANOS_DISABLED) {
                // apply a random jitter of +/-10% to max connection age
                maxConnectionAgeInNanos = (long) ((.9D + Math.random() * .2D) * maxConnectionAgeInNanos);
            }

            NettyServerTransport transport = new NettyServerTransport(ch, channelDone, protocolNegotiator,
                    streamTracerFactories, transportTracerFactory.create(), maxStreamsPerConnection,
                    flowControlWindow, maxMessageSize, maxHeaderListSize, keepAliveTimeInNanos,
                    keepAliveTimeoutInNanos, maxConnectionIdleInNanos, maxConnectionAgeInNanos,
                    maxConnectionAgeGraceInNanos, permitKeepAliveWithoutCalls, permitKeepAliveTimeInNanos);
            ServerTransportListener transportListener;
            // This is to order callbacks on the listener, not to guard access to channel.
            synchronized (NettyServer.this) {
                if (channel != null && !channel.isOpen()) {
                    // Server already shutdown.
                    ch.close();
                    return;
                }
                // `channel` shutdown can race with `ch` initialization, so this is only safe to increment
                // inside the lock.
                eventLoopReferenceCounter.retain();
                transportListener = listener.transportCreated(transport);
            }

            /**
             * Releases the event loop if the channel is "done", possibly due to the channel closing.
             */
            final class LoopReleaser implements ChannelFutureListener {
                private boolean done;

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!done) {
                        done = true;
                        eventLoopReferenceCounter.release();
                    }
                }
            }

            transport.start(transportListener);
            ChannelFutureListener loopReleaser = new LoopReleaser();
            channelDone.addListener(loopReleaser);
            ch.closeFuture().addListener(loopReleaser);
        }
    });
    // Bind and start to accept incoming connections.
    ChannelFuture future = b.bind(address);
    try {
        future.await();
    } catch (InterruptedException ex) {
        Thread.currentThread().interrupt();
        throw new RuntimeException("Interrupted waiting for bind");
    }
    if (!future.isSuccess()) {
        throw new IOException("Failed to bind", future.cause());
    }
    channel = future.channel();
    Future<?> channelzFuture = channel.eventLoop().submit(new Runnable() {
        @Override
        public void run() {
            InternalInstrumented<SocketStats> listenSocket = new ListenSocket(channel);
            listenSocketStats.set(listenSocket);
            channelz.addListenSocket(listenSocket);
        }
    });
    try {
        channelzFuture.await();
    } catch (InterruptedException ex) {
        throw new RuntimeException("Interrupted while registering listen socket to channelz", ex);
    }
}

From source file:io.grpc.netty.NettyServerHandler.java

License:Apache License

private void closeStreamWhenDone(ChannelPromise promise, int streamId) throws Http2Exception {
    final NettyServerStream.TransportState stream = serverStream(requireHttp2Stream(streamId));
    promise.addListener(new ChannelFutureListener() {
        @Override/*  ww w  .j  a  v a 2 s  .  c o  m*/
        public void operationComplete(ChannelFuture future) {
            stream.complete();
        }
    });
}

From source file:io.grpc.netty.WriteBufferingAndExceptionHandler.java

License:Apache License

/**
 * Connect failures do not show up as {@link #channelInactive} or {@link #exceptionCaught}, so
 * it needs to be watched.//from   w ww .j a  va2  s  . co m
 */
@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
        ChannelPromise promise) throws Exception {
    final class ConnectListener implements ChannelFutureListener {
        @Override
        public void operationComplete(ChannelFuture future) {
            if (!future.isSuccess()) {
                failWrites(future.cause());
            }
        }
    }

    super.connect(ctx, remoteAddress, localAddress, promise);
    promise.addListener(new ConnectListener());
}

From source file:io.jsync.impl.ExceptionDispatchHandler.java

License:Open Source License

@Override
public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise)
        throws Exception {
    ctx.bind(localAddress, promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE));
}

From source file:io.jsync.impl.ExceptionDispatchHandler.java

License:Open Source License

@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
        ChannelPromise promise) throws Exception {
    ctx.connect(remoteAddress, localAddress,
            promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE));
}

From source file:io.jsync.impl.ExceptionDispatchHandler.java

License:Open Source License

@Override
public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
    ctx.disconnect(promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE));
}

From source file:io.jsync.impl.ExceptionDispatchHandler.java

License:Open Source License

@Override
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
    ctx.close(promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE));
}

From source file:io.jsync.impl.ExceptionDispatchHandler.java

License:Open Source License

@Override
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
    ctx.deregister(promise.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE));
}