List of usage examples for io.netty.util.concurrent Future addListener
Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
From source file:com.linecorp.armeria.server.Server.java
License:Apache License
private void stop1(CompletableFuture<Void> future, EventLoopGroup bossGroup) { // FIXME(trustin): Shutdown and terminate the blockingTaskExecutor. // Could be fixed while fixing https://github.com/line/armeria/issues/46 final Future<?> bossShutdownFuture; if (bossGroup != null) { bossShutdownFuture = bossGroup.shutdownGracefully(); this.bossGroup = null; } else {/*from w w w .j a va2 s .c o m*/ bossShutdownFuture = ImmediateEventExecutor.INSTANCE.newSucceededFuture(null); } bossShutdownFuture.addListener(f1 -> { // All server ports have been unbound. primaryActivePort = null; activePorts.clear(); // Shut down the workers. final EventLoopGroup workerGroup = this.workerGroup; final Future<?> workerShutdownFuture; if (workerGroup != null) { workerShutdownFuture = workerGroup.shutdownGracefully(); this.workerGroup = null; } else { workerShutdownFuture = ImmediateEventExecutor.INSTANCE.newSucceededFuture(null); } workerShutdownFuture.addListener(f2 -> { stateManager.enter(State.STOPPED); completeFuture(future); }); }); }
From source file:com.mobicage.rogerthat.plugins.news.NewsChannel.java
License:Apache License
public void connect() { if (TestUtils.isRunningTest()) { return;//w w w . j av a2 s . com } T.NEWS(); if (mIsConnected) { L.d("Already connected to news channel"); return; } else if (!mService.getNetworkConnectivityManager().isConnected()) { L.d("Cannot connect to news channel: no internet connection."); return; } else if (mHost == null) { L.d("Not connecting to news channel because no host was found"); return; } else if (mPort == -1) { L.d("Not connecting to news channel because no port was found"); return; } mIsRetryingToConnect = true; L.d("Attemping to connect to news channel..."); final SslContext sslCtx; if (CloudConstants.NEWS_CHANNEL_SSL) { try { if (CloudConstants.NEWS_CHANNEL_MUST_VALIDATE_SSL_CERTIFICATE) { TrustManagerFactory factory = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore keyStore = KeyStore.getInstance("AndroidCAStore"); // Gets the default system keystore keyStore.load(null, null); factory.init(keyStore); sslCtx = SslContextBuilder.forClient().trustManager(factory).build(); } else { sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE) .build(); } } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) { L.bug(e); return; } } else { sslCtx = null; } if (mEventLoopGroup == null) { mEventLoopGroup = new NioEventLoopGroup(); } Bootstrap b = new Bootstrap(); b.group(mEventLoopGroup).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); if (sslCtx != null) { SslHandler sslHandler = sslCtx.newHandler(ch.alloc(), mHost, mPort); Future<Channel> handshakeDone = sslHandler.handshakeFuture(); handshakeDone.addListener(new GenericFutureListener<Future<? super Channel>>() { @Override public void operationComplete(Future<? super Channel> future) throws Exception { authenticate(); } }); p.addLast(sslHandler); } // decoder p.addLast(new DelimiterBasedFrameDecoder(102400, Delimiters.lineDelimiter())); p.addLast(new StringDecoder(Charset.forName("UTF-8"))); //encoder p.addLast(new StringEncoder(Charset.forName("UTF-8"))); p.addLast(NewsChannel.this); } }); // Bind and start to accept incoming connections. mChannel = b.connect(mHost, mPort).channel(); }
From source file:com.relayrides.pushy.apns.ApnsClient.java
License:Open Source License
/** * <p>Sends a push notification to the APNs gateway.</p> * * <p>This method returns a {@code Future} that indicates whether the notification was accepted or rejected by the * gateway. If the notification was accepted, it may be delivered to its destination device at some time in the * future, but final delivery is not guaranteed. Rejections should be considered permanent failures, and callers * should <em>not</em> attempt to re-send the notification.</p> * * <p>The returned {@code Future} may fail with an exception if the notification could not be sent. Failures to * <em>send</em> a notification to the gatewayi.e. those that fail with exceptionsshould generally be considered * non-permanent, and callers should attempt to re-send the notification when the underlying problem has been * resolved.</p>/*from w w w .j a v a2 s.c o m*/ * * <p>In particular, attempts to send a notification when the client is not connected will fail with a * {@link ClientNotConnectedException}. If the client was previously connected and has not been explicitly * disconnected (via the {@link ApnsClient#disconnect()} method), the client will attempt to reconnect * automatically. Callers may wait for a reconnection attempt to complete by waiting for the {@code Future} returned * by the {@link ApnsClient#getReconnectionFuture()} method.</p> * * @param notification the notification to send to the APNs gateway * * @param <T> the type of notification to be sent * * @return a {@code Future} that will complete when the notification has been either accepted or rejected by the * APNs gateway * * @since 0.8 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public <T extends ApnsPushNotification> Future<PushNotificationResponse<T>> sendNotification( final T notification) { final Future<PushNotificationResponse<T>> responseFuture; final long notificationId = this.nextNotificationId.getAndIncrement(); // Instead of synchronizing here, we keep a final reference to the connection ready promise. We can get away // with this because we're not changing the state of the connection or its promises. Keeping a reference ensures // we won't suddenly "lose" the channel and get a NullPointerException, but risks sending a notification after // things have shut down. In that case, though, the returned futures should fail quickly, and the benefit of // not synchronizing for every write seems worth it. final ChannelPromise connectionReadyPromise = this.connectionReadyPromise; if (connectionReadyPromise != null && connectionReadyPromise.isSuccess() && connectionReadyPromise.channel().isActive()) { final Channel channel = connectionReadyPromise.channel(); final Promise<PushNotificationResponse<ApnsPushNotification>> responsePromise = new DefaultPromise( channel.eventLoop()); channel.writeAndFlush(new PushNotificationAndResponsePromise(notification, responsePromise)) .addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(final ChannelFuture future) throws Exception { if (future.isSuccess()) { ApnsClient.this.metricsListener.handleNotificationSent(ApnsClient.this, notificationId); } else { responsePromise.tryFailure(future.cause()); } } }); responseFuture = (Future) responsePromise; } else { log.debug("Failed to send push notification because client is not connected: {}", notification); responseFuture = new FailedFuture<>(GlobalEventExecutor.INSTANCE, NOT_CONNECTED_EXCEPTION); } responseFuture.addListener(new GenericFutureListener<Future<PushNotificationResponse<T>>>() { @Override public void operationComplete(final Future<PushNotificationResponse<T>> future) throws Exception { if (future.isSuccess()) { final PushNotificationResponse<T> response = future.getNow(); if (response.isAccepted()) { ApnsClient.this.metricsListener.handleNotificationAccepted(ApnsClient.this, notificationId); } else { ApnsClient.this.metricsListener.handleNotificationRejected(ApnsClient.this, notificationId); } } else { ApnsClient.this.metricsListener.handleWriteFailure(ApnsClient.this, notificationId); } } }); return responseFuture; }
From source file:com.relayrides.pushy.apns.ApnsClient.java
License:Open Source License
/** * <p>Gracefully disconnects from the APNs gateway. The disconnection process will wait until notifications that * have been sent to the APNs server have been either accepted or rejected. Note that some notifications passed to * {@link com.relayrides.pushy.apns.ApnsClient#sendNotification(ApnsPushNotification)} may still be enqueued and * not yet sent by the time the shutdown process begins; the {@code Futures} associated with those notifications * will fail.</p>/*from w w w .ja v a 2 s . c o m*/ * * <p>The returned {@code Future} will be marked as complete when the connection has closed completely. If the * connection is already closed when this method is called, the returned {@code Future} will be marked as complete * immediately.</p> * * <p>If a non-null {@code EventLoopGroup} was provided at construction time, clients may be reconnected and reused * after they have been disconnected. If no event loop group was provided at construction time, clients may not be * restarted after they have been disconnected via this method.</p> * * @return a {@code Future} that will be marked as complete when the connection has been closed * * @since 0.5 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public Future<Void> disconnect() { log.info("Disconnecting."); final Future<Void> disconnectFuture; synchronized (this.bootstrap) { this.reconnectionPromise = null; if (this.scheduledReconnectFuture != null) { this.scheduledReconnectFuture.cancel(true); } final Future<Void> channelCloseFuture; if (this.connectionReadyPromise != null) { channelCloseFuture = this.connectionReadyPromise.channel().close(); } else { channelCloseFuture = new SucceededFuture<>(GlobalEventExecutor.INSTANCE, null); } if (this.shouldShutDownEventLoopGroup) { // Wait for the channel to close before we try to shut down the event loop group channelCloseFuture.addListener(new GenericFutureListener<Future<Void>>() { @Override public void operationComplete(final Future<Void> future) throws Exception { ApnsClient.this.bootstrap.config().group().shutdownGracefully(); } }); // Since the termination future for the event loop group is a Future<?> instead of a Future<Void>, // we'll need to create our own promise and then notify it when the termination future completes. disconnectFuture = new DefaultPromise<>(GlobalEventExecutor.INSTANCE); this.bootstrap.config().group().terminationFuture().addListener(new GenericFutureListener() { @Override public void operationComplete(final Future future) throws Exception { assert disconnectFuture instanceof DefaultPromise; ((DefaultPromise<Void>) disconnectFuture).trySuccess(null); } }); } else { // We're done once we've closed the channel, so we can return the closure future directly. disconnectFuture = channelCloseFuture; } } return disconnectFuture; }
From source file:com.spotify.netty4.handler.codec.zmtp.ListenableFutureAdapter.java
License:Apache License
static <T> ListenableFuture<T> listenable(final Future<T> future) { final ListenableFutureAdapter<T> adapter = new ListenableFutureAdapter<T>(); future.addListener(adapter); return adapter; }
From source file:com.turo.pushy.apns.ApnsChannelPool.java
License:Open Source License
private void acquireWithinEventExecutor(final Promise<Channel> acquirePromise) { assert this.executor.inEventLoop(); if (!this.isClosed) { // We always want to open new channels if we have spare capacity. Once the pool is full, we'll start looking // for idle, pre-existing channels. if (this.allChannels.size() + this.pendingCreateChannelFutures.size() < this.capacity) { final Future<Channel> createChannelFuture = this.channelFactory .create(executor.<Channel>newPromise()); this.pendingCreateChannelFutures.add(createChannelFuture); createChannelFuture.addListener(new GenericFutureListener<Future<Channel>>() { @Override//from ww w. j a v a 2s.c o m public void operationComplete(final Future<Channel> future) { ApnsChannelPool.this.pendingCreateChannelFutures.remove(createChannelFuture); if (future.isSuccess()) { final Channel channel = future.getNow(); ApnsChannelPool.this.allChannels.add(channel); ApnsChannelPool.this.metricsListener.handleConnectionAdded(); acquirePromise.trySuccess(channel); } else { ApnsChannelPool.this.metricsListener.handleConnectionCreationFailed(); acquirePromise.tryFailure(future.cause()); // If we failed to open a connection, this is the end of the line for this acquisition // attempt, and callers won't be able to release the channel (since they didn't get one // in the first place). Move on to the next acquisition attempt if one is present. ApnsChannelPool.this.handleNextAcquisition(); } } }); } else { final Channel channelFromIdlePool = ApnsChannelPool.this.idleChannels.poll(); if (channelFromIdlePool != null) { if (channelFromIdlePool.isActive()) { acquirePromise.trySuccess(channelFromIdlePool); } else { // The channel from the idle pool isn't usable; discard it and create a new one instead this.discardChannel(channelFromIdlePool); this.acquireWithinEventExecutor(acquirePromise); } } else { // We don't have any connections ready to go, and don't have any more capacity to create new // channels. Add this acquisition to the queue waiting for channels to become available. pendingAcquisitionPromises.add(acquirePromise); } } } else { acquirePromise.tryFailure(POOL_CLOSED_EXCEPTION); } }
From source file:com.turo.pushy.apns.ApnsClientTest.java
License:Open Source License
@Test @Parameters({ "true", "false" }) public void testSendManyNotificationsWithListeners(final boolean useTokenAuthentication) throws Exception { final int notificationCount = 1000; final List<SimpleApnsPushNotification> pushNotifications = new ArrayList<>(); for (int i = 0; i < notificationCount; i++) { final String token = ApnsClientTest.generateRandomDeviceToken(); final String payload = ApnsClientTest.generateRandomPayload(); pushNotifications.add(new SimpleApnsPushNotification(token, TOPIC, payload)); }/*from ww w .ja v a 2s .c o m*/ final MockApnsServer server = this.buildServer(new AcceptAllPushNotificationHandlerFactory()); final ApnsClient client = useTokenAuthentication ? this.buildTokenAuthenticationClient() : this.buildTlsAuthenticationClient(); final CountDownLatch countDownLatch = new CountDownLatch(notificationCount); try { server.start(PORT).await(); for (final SimpleApnsPushNotification pushNotification : pushNotifications) { final Future<PushNotificationResponse<SimpleApnsPushNotification>> future = client .sendNotification(pushNotification); future.addListener( new GenericFutureListener<Future<PushNotificationResponse<SimpleApnsPushNotification>>>() { @Override public void operationComplete( final Future<PushNotificationResponse<SimpleApnsPushNotification>> future) { if (future.isSuccess()) { countDownLatch.countDown(); } } }); } countDownLatch.await(); } finally { client.close().await(); server.shutdown().await(); } }
From source file:com.turo.pushy.apns.ApnsClientTest.java
License:Open Source License
@Test @Parameters({ "true", "false" }) public void testRepeatedlySendSameNotification(final boolean useTokenAuthentication) throws Exception { final int notificationCount = 1000; final SimpleApnsPushNotification pushNotification = new SimpleApnsPushNotification(DEVICE_TOKEN, TOPIC, PAYLOAD);/*from w ww. ja v a2s. c om*/ final CountDownLatch countDownLatch = new CountDownLatch(notificationCount); final MockApnsServer server = this.buildServer(new AcceptAllPushNotificationHandlerFactory()); final ApnsClient client = useTokenAuthentication ? this.buildTokenAuthenticationClient() : this.buildTlsAuthenticationClient(); try { server.start(PORT).await(); for (int i = 0; i < notificationCount; i++) { final Future<PushNotificationResponse<SimpleApnsPushNotification>> future = client .sendNotification(pushNotification); future.addListener( new GenericFutureListener<Future<PushNotificationResponse<SimpleApnsPushNotification>>>() { @Override public void operationComplete( final Future<PushNotificationResponse<SimpleApnsPushNotification>> future) { // All we're concerned with here is that the client told us SOMETHING about what happened to the // notification countDownLatch.countDown(); } }); } countDownLatch.await(); } finally { client.close().await(); server.shutdown().await(); } }
From source file:com.turo.pushy.apns.MockApnsServer.java
License:Open Source License
/** * <p>Shuts down this server and releases the port to which this server was bound. If a {@code null} event loop * group was provided at construction time, the server will also shut down its internally-managed event loop * group.</p>/*from w w w. j av a 2 s . c o m*/ * * <p>If a non-null {@code EventLoopGroup} was provided at construction time, mock servers may be reconnected and * reused after they have been shut down. If no event loop group was provided at construction time, mock servers may * not be restarted after they have been shut down via this method.</p> * * @return a {@code Future} that will succeed once the server has finished unbinding from its port and, if the * server was managing its own event loop group, its event loop group has shut down */ @SuppressWarnings({ "rawtypes", "unchecked" }) public Future<Void> shutdown() { final Future<Void> channelCloseFuture = (this.allChannels != null) ? this.allChannels.close() : new SucceededFuture<Void>(GlobalEventExecutor.INSTANCE, null); final Future<Void> disconnectFuture; if (this.shouldShutDownEventLoopGroup) { // Wait for the channel to close before we try to shut down the event loop group channelCloseFuture.addListener(new GenericFutureListener<Future<Void>>() { @Override public void operationComplete(final Future<Void> future) throws Exception { MockApnsServer.this.bootstrap.config().group().shutdownGracefully(); } }); // Since the termination future for the event loop group is a Future<?> instead of a Future<Void>, // we'll need to create our own promise and then notify it when the termination future completes. disconnectFuture = new DefaultPromise<>(GlobalEventExecutor.INSTANCE); this.bootstrap.config().group().terminationFuture().addListener(new GenericFutureListener() { @Override public void operationComplete(final Future future) throws Exception { assert disconnectFuture instanceof DefaultPromise; ((DefaultPromise<Void>) disconnectFuture).trySuccess(null); } }); } else { // We're done once we've closed all the channels, so we can return the closure future directly. disconnectFuture = channelCloseFuture; } return disconnectFuture; }
From source file:com.turo.pushy.apns.server.BaseHttp2Server.java
License:Open Source License
/** * <p>Shuts down this server and releases the port to which this server was bound. If a {@code null} event loop * group was provided at construction time, the server will also shut down its internally-managed event loop * group.</p>//from ww w . j a va 2 s . c o m * * <p>If a non-null {@code EventLoopGroup} was provided at construction time, mock servers may be reconnected and * reused after they have been shut down. If no event loop group was provided at construction time, mock servers may * not be restarted after they have been shut down via this method.</p> * * @return a {@code Future} that will succeed once the server has finished unbinding from its port and, if the * server was managing its own event loop group, its event loop group has shut down */ @SuppressWarnings({ "rawtypes", "unchecked" }) public Future<Void> shutdown() { final Future<Void> channelCloseFuture = this.allChannels.close(); final Future<Void> disconnectFuture; if (this.shouldShutDownEventLoopGroup) { // Wait for the channel to close before we try to shut down the event loop group channelCloseFuture.addListener(new GenericFutureListener<Future<Void>>() { @Override public void operationComplete(final Future<Void> future) throws Exception { BaseHttp2Server.this.bootstrap.config().group().shutdownGracefully(); } }); // Since the termination future for the event loop group is a Future<?> instead of a Future<Void>, // we'll need to create our own promise and then notify it when the termination future completes. disconnectFuture = new DefaultPromise<>(GlobalEventExecutor.INSTANCE); this.bootstrap.config().group().terminationFuture().addListener(new GenericFutureListener() { @Override public void operationComplete(final Future future) throws Exception { ((Promise<Void>) disconnectFuture).trySuccess(null); } }); } else { // We're done once we've closed all the channels, so we can return the closure future directly. disconnectFuture = channelCloseFuture; } disconnectFuture.addListener(new GenericFutureListener<Future<Void>>() { @Override public void operationComplete(final Future<Void> future) throws Exception { if (BaseHttp2Server.this.sslContext instanceof ReferenceCounted) { if (BaseHttp2Server.this.hasReleasedSslContext.compareAndSet(false, true)) { ((ReferenceCounted) BaseHttp2Server.this.sslContext).release(); } } } }); return disconnectFuture; }