1 /*
2 * Copyright 2021 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package io.netty5.channel;
17
18 import io.netty5.util.concurrent.Future;
19 import io.netty5.util.concurrent.FutureContextListener;
20
21 /**
22 * {@link FutureContextListener} listeners that take a context, and listens to the result of a {@link Future}.
23 * The result of the asynchronous {@link ChannelOutboundInvoker} I/O operation is notified once this listener is added
24 * by calling {@link Future#addListener(Object, FutureContextListener)} with the {@link ChannelOutboundInvoker} /
25 * {@link Channel} as context.
26 */
27 public final class ChannelFutureListeners {
28
29 /**
30 * A {@link FutureContextListener} that closes the {@link ChannelOutboundInvoker} which is associated with
31 * the specified {@link Future}.
32 */
33 public static final FutureContextListener<ChannelOutboundInvoker, Object> CLOSE = new Close();
34
35 /**
36 * A {@link FutureContextListener} that closes the {@link ChannelOutboundInvoker} when the operation ended up with
37 * a failure or cancellation rather than a success.
38 */
39 public static final FutureContextListener<ChannelOutboundInvoker, Object> CLOSE_ON_FAILURE = new CloseOnFailure();
40
41 /**
42 * A {@link FutureContextListener} that forwards the {@link Throwable} of the {@link Future} into the
43 * {@link ChannelPipeline}. This mimics the old behavior of Netty 3.
44 */
45 public static final FutureContextListener<Channel, Object> FIRE_EXCEPTION_ON_FAILURE = new FireExceptionOnFailure();
46
47 private ChannelFutureListeners() {
48 }
49
50 private static final class Close implements FutureContextListener<ChannelOutboundInvoker, Object> {
51 @Override
52 public void operationComplete(ChannelOutboundInvoker context, Future<?> future) throws Exception {
53 context.close();
54 }
55 }
56
57 private static final class CloseOnFailure implements FutureContextListener<ChannelOutboundInvoker, Object> {
58 @Override
59 public void operationComplete(ChannelOutboundInvoker context, Future<?> future) throws Exception {
60 if (future.isFailed()) {
61 context.close();
62 }
63 }
64 }
65
66 private static final class FireExceptionOnFailure implements FutureContextListener<Channel, Object> {
67 @Override
68 public void operationComplete(Channel context, Future<?> future) throws Exception {
69 if (future.isFailed()) {
70 context.pipeline().fireChannelExceptionCaught(future.cause());
71 }
72 }
73 }
74 }