1 /*
2 * Copyright 2016 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.netty.channel;
17
18 import io.netty.util.concurrent.EventExecutor;
19 import io.netty.util.concurrent.FutureListener;
20
21 import java.net.ConnectException;
22 import java.net.SocketAddress;
23
24 public interface ChannelOutboundInvoker {
25
26 /**
27 * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
28 * completes, either because the operation was successful or because of an error.
29 * <p>
30 * This will result in having the
31 * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
32 * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
33 * {@link Channel}.
34 */
35 default ChannelFuture bind(SocketAddress localAddress) {
36 return bind(localAddress, newPromise());
37 }
38
39 /**
40 * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
41 * completes, either because the operation was successful or because of an error.
42 * <p>
43 * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
44 * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
45 * will be used.
46 * <p>
47 * This will result in having the
48 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
49 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
50 * {@link Channel}.
51 */
52 default ChannelFuture connect(SocketAddress remoteAddress) {
53 return connect(remoteAddress, newPromise());
54 }
55
56 /**
57 * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
58 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
59 * an error.
60 * <p>
61 * This will result in having the
62 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
63 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
64 * {@link Channel}.
65 */
66 default ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress) {
67 return connect(remoteAddress, localAddress, newPromise());
68 }
69
70 /**
71 * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
72 * either because the operation was successful or because of an error.
73 * <p>
74 * This will result in having the
75 * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
76 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
77 * {@link Channel}.
78 */
79 default ChannelFuture disconnect() {
80 return disconnect(newPromise());
81 }
82
83 /**
84 * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
85 * either because the operation was successful or because of
86 * an error.
87 *
88 * After it is closed it is not possible to reuse it again.
89 * <p>
90 * This will result in having the
91 * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
92 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
93 * {@link Channel}.
94 */
95 default ChannelFuture close() {
96 return close(newPromise());
97 }
98
99 /**
100 * Request to deregister from the previous assigned {@link EventExecutor} and notify the
101 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
102 * an error.
103 * <p>
104 * This will result in having the
105 * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
106 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
107 * {@link Channel}.
108 *
109 */
110 default ChannelFuture deregister() {
111 return deregister(newPromise());
112 }
113
114 /**
115 * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
116 * completes, either because the operation was successful or because of an error.
117 *
118 * The given {@link ChannelPromise} will be notified.
119 * <p>
120 * This will result in having the
121 * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
122 * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
123 * {@link Channel}.
124 */
125 ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
126
127 /**
128 * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
129 * completes, either because the operation was successful or because of an error.
130 *
131 * The given {@link ChannelFuture} will be notified.
132 *
133 * <p>
134 * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
135 * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
136 * will be used.
137 * <p>
138 * This will result in having the
139 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
140 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
141 * {@link Channel}.
142 */
143 ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
144
145 /**
146 * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
147 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
148 * an error.
149 *
150 * The given {@link ChannelPromise} will be notified and also returned.
151 * <p>
152 * This will result in having the
153 * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
154 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
155 * {@link Channel}.
156 */
157 ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
158
159 /**
160 * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
161 * either because the operation was successful or because of an error.
162 *
163 * The given {@link ChannelPromise} will be notified.
164 * <p>
165 * This will result in having the
166 * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
167 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
168 * {@link Channel}.
169 */
170 ChannelFuture disconnect(ChannelPromise promise);
171
172 /**
173 * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
174 * either because the operation was successful or because of
175 * an error.
176 *
177 * After it is closed it is not possible to reuse it again.
178 * The given {@link ChannelPromise} will be notified.
179 * <p>
180 * This will result in having the
181 * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
182 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
183 * {@link Channel}.
184 */
185 ChannelFuture close(ChannelPromise promise);
186
187 /**
188 * Request to deregister from the previous assigned {@link EventExecutor} and notify the
189 * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
190 * an error.
191 *
192 * The given {@link ChannelPromise} will be notified.
193 * <p>
194 * This will result in having the
195 * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
196 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
197 * {@link Channel}.
198 */
199 ChannelFuture deregister(ChannelPromise promise);
200
201 /**
202 * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
203 * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was
204 * read, and triggers a
205 * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the
206 * handler can decide to continue reading. If there's a pending read operation already, this method does nothing.
207 * <p>
208 * This will result in having the
209 * {@link ChannelOutboundHandler#read(ChannelHandlerContext)}
210 * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
211 * {@link Channel}.
212 */
213 ChannelOutboundInvoker read();
214
215 /**
216 * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}.
217 * This method will not request to actual flush, so be sure to call {@link #flush()}
218 * once you want to request to flush all pending data to the actual transport.
219 */
220 default ChannelFuture write(Object msg) {
221 return write(msg, newPromise());
222 }
223
224 /**
225 * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}.
226 * This method will not request to actual flush, so be sure to call {@link #flush()}
227 * once you want to request to flush all pending data to the actual transport.
228 */
229 ChannelFuture write(Object msg, ChannelPromise promise);
230
231 /**
232 * Request to flush all pending messages via this ChannelOutboundInvoker.
233 */
234 ChannelOutboundInvoker flush();
235
236 /**
237 * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}.
238 */
239 ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
240
241 /**
242 * Shortcut for call {@link #write(Object)} and {@link #flush()}.
243 */
244 default ChannelFuture writeAndFlush(Object msg) {
245 return writeAndFlush(msg, newPromise());
246 }
247
248 /**
249 * Return a new {@link ChannelPromise}.
250 */
251 ChannelPromise newPromise();
252
253 /**
254 * Return an new {@link ChannelProgressivePromise}
255 */
256 ChannelProgressivePromise newProgressivePromise();
257
258 /**
259 * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()}
260 * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
261 * every call of blocking methods will just return without blocking.
262 */
263 ChannelFuture newSucceededFuture();
264
265 /**
266 * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()}
267 * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
268 * every call of blocking methods will just return without blocking.
269 */
270 ChannelFuture newFailedFuture(Throwable cause);
271
272 /**
273 * Return a special ChannelPromise which can be reused for different operations.
274 * <p>
275 * It's only supported to use
276 * it for {@link ChannelOutboundInvoker#write(Object, ChannelPromise)}.
277 * </p>
278 * <p>
279 * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used
280 * if you want to save an object allocation for every write operation. You will not be able to detect if the
281 * operation was complete, only if it failed as the implementation will call
282 * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case.
283 * </p>
284 * <strong>Be aware this is an expert feature and should be used with care!</strong>
285 */
286 ChannelPromise voidPromise();
287 }