View Javadoc
1   /*
2    * Copyright 2012 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.buffer.ByteBuf;
19  import io.netty.util.concurrent.EventExecutorGroup;
20  
21  import java.net.SocketAddress;
22  import java.nio.ByteBuffer;
23  import java.nio.channels.SocketChannel;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Map.Entry;
27  import java.util.NoSuchElementException;
28  
29  
30  /**
31   * A list of {@link ChannelHandler}s which handles or intercepts inbound events and outbound operations of a
32   * {@link Channel}.  {@link ChannelPipeline} implements an advanced form of the
33   * <a href="https://www.oracle.com/technetwork/java/interceptingfilter-142169.html">Intercepting Filter</a> pattern
34   * to give a user full control over how an event is handled and how the {@link ChannelHandler}s in a pipeline
35   * interact with each other.
36   *
37   * <h3>Creation of a pipeline</h3>
38   *
39   * Each channel has its own pipeline and it is created automatically when a new channel is created.
40   *
41   * <h3>How an event flows in a pipeline</h3>
42   *
43   * The following diagram describes how I/O events are processed by {@link ChannelHandler}s in a {@link ChannelPipeline}
44   * typically. An I/O event is handled by either a {@link ChannelInboundHandler} or a {@link ChannelOutboundHandler}
45   * and be forwarded to its closest handler by calling the event propagation methods defined in
46   * {@link ChannelHandlerContext}, such as {@link ChannelHandlerContext#fireChannelRead(Object)} and
47   * {@link ChannelHandlerContext#write(Object)}.
48   *
49   * <pre>
50   *                                                 I/O Request
51   *                                            via {@link Channel} or
52   *                                        {@link ChannelHandlerContext}
53   *                                                      |
54   *  +---------------------------------------------------+---------------+
55   *  |                           ChannelPipeline         |               |
56   *  |                                                  \|/              |
57   *  |    +---------------------+            +-----------+----------+    |
58   *  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
59   *  |    +----------+----------+            +-----------+----------+    |
60   *  |              /|\                                  |               |
61   *  |               |                                  \|/              |
62   *  |    +----------+----------+            +-----------+----------+    |
63   *  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
64   *  |    +----------+----------+            +-----------+----------+    |
65   *  |              /|\                                  .               |
66   *  |               .                                   .               |
67   *  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
68   *  |        [ method call]                       [method call]         |
69   *  |               .                                   .               |
70   *  |               .                                  \|/              |
71   *  |    +----------+----------+            +-----------+----------+    |
72   *  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
73   *  |    +----------+----------+            +-----------+----------+    |
74   *  |              /|\                                  |               |
75   *  |               |                                  \|/              |
76   *  |    +----------+----------+            +-----------+----------+    |
77   *  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
78   *  |    +----------+----------+            +-----------+----------+    |
79   *  |              /|\                                  |               |
80   *  +---------------+-----------------------------------+---------------+
81   *                  |                                  \|/
82   *  +---------------+-----------------------------------+---------------+
83   *  |               |                                   |               |
84   *  |       [ Socket.read() ]                    [ Socket.write() ]     |
85   *  |                                                                   |
86   *  |  Netty Internal I/O Threads (Transport Implementation)            |
87   *  +-------------------------------------------------------------------+
88   * </pre>
89   * An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the
90   * diagram.  An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the
91   * diagram.  The inbound data is often read from a remote peer via the actual input operation such as
92   * {@link SocketChannel#read(ByteBuffer)}.  If an inbound event goes beyond the top inbound handler, it is discarded
93   * silently, or logged if it needs your attention.
94   * <p>
95   * An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the
96   * diagram.  An outbound handler usually generates or transforms the outbound traffic such as write requests.
97   * If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the
98   * {@link Channel}. The I/O thread often performs the actual output operation such as
99   * {@link SocketChannel#write(ByteBuffer)}.
100  * <p>
101  * For example, let us assume that we created the following pipeline:
102  * <pre>
103  * {@link ChannelPipeline} p = ...;
104  * p.addLast("1", new InboundHandlerA());
105  * p.addLast("2", new InboundHandlerB());
106  * p.addLast("3", new OutboundHandlerA());
107  * p.addLast("4", new OutboundHandlerB());
108  * p.addLast("5", new InboundOutboundHandlerX());
109  * </pre>
110  * In the example above, the class whose name starts with {@code Inbound} means it is an inbound handler.
111  * The class whose name starts with {@code Outbound} means it is a outbound handler.
112  * <p>
113  * In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound.
114  * When an event goes outbound, the order is 5, 4, 3, 2, 1.  On top of this principle, {@link ChannelPipeline} skips
115  * the evaluation of certain handlers to shorten the stack depth:
116  * <ul>
117  * <li>3 and 4 don't implement {@link ChannelInboundHandler}, and therefore the actual evaluation order of an inbound
118  *     event will be: 1, 2, and 5.</li>
119  * <li>1 and 2 don't implement {@link ChannelOutboundHandler}, and therefore the actual evaluation order of a
120  *     outbound event will be: 5, 4, and 3.</li>
121  * <li>If 5 implements both {@link ChannelInboundHandler} and {@link ChannelOutboundHandler}, the evaluation order of
122  *     an inbound and a outbound event could be 125 and 543 respectively.</li>
123  * </ul>
124  *
125  * <h3>Forwarding an event to the next handler</h3>
126  *
127  * As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in
128  * {@link ChannelHandlerContext} to forward an event to its next handler.  Those methods include:
129  * <ul>
130  * <li>Inbound event propagation methods:
131  *     <ul>
132  *     <li>{@link ChannelHandlerContext#fireChannelRegistered()}</li>
133  *     <li>{@link ChannelHandlerContext#fireChannelActive()}</li>
134  *     <li>{@link ChannelHandlerContext#fireChannelRead(Object)}</li>
135  *     <li>{@link ChannelHandlerContext#fireChannelReadComplete()}</li>
136  *     <li>{@link ChannelHandlerContext#fireExceptionCaught(Throwable)}</li>
137  *     <li>{@link ChannelHandlerContext#fireUserEventTriggered(Object)}</li>
138  *     <li>{@link ChannelHandlerContext#fireChannelWritabilityChanged()}</li>
139  *     <li>{@link ChannelHandlerContext#fireChannelInactive()}</li>
140  *     <li>{@link ChannelHandlerContext#fireChannelUnregistered()}</li>
141  *     </ul>
142  * </li>
143  * <li>Outbound event propagation methods:
144  *     <ul>
145  *     <li>{@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)}</li>
146  *     <li>{@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)}</li>
147  *     <li>{@link ChannelHandlerContext#write(Object, ChannelPromise)}</li>
148  *     <li>{@link ChannelHandlerContext#flush()}</li>
149  *     <li>{@link ChannelHandlerContext#read()}</li>
150  *     <li>{@link ChannelHandlerContext#disconnect(ChannelPromise)}</li>
151  *     <li>{@link ChannelHandlerContext#close(ChannelPromise)}</li>
152  *     <li>{@link ChannelHandlerContext#deregister(ChannelPromise)}</li>
153  *     </ul>
154  * </li>
155  * </ul>
156  *
157  * and the following example shows how the event propagation is usually done:
158  *
159  * <pre>
160  * public class MyInboundHandler extends {@link ChannelInboundHandlerAdapter} {
161  *     {@code @Override}
162  *     public void channelActive({@link ChannelHandlerContext} ctx) {
163  *         System.out.println("Connected!");
164  *         ctx.fireChannelActive();
165  *     }
166  * }
167  *
168  * public class MyOutboundHandler extends {@link ChannelOutboundHandlerAdapter} {
169  *     {@code @Override}
170  *     public void close({@link ChannelHandlerContext} ctx, {@link ChannelPromise} promise) {
171  *         System.out.println("Closing ..");
172  *         ctx.close(promise);
173  *     }
174  * }
175  * </pre>
176  *
177  * <h3>Building a pipeline</h3>
178  * <p>
179  * A user is supposed to have one or more {@link ChannelHandler}s in a pipeline to receive I/O events (e.g. read) and
180  * to request I/O operations (e.g. write and close). For example, a typical server will have the following handlers
181  * in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the
182  * protocol and business logic:
183  *
184  * <ol>
185  * <li>Protocol Decoder - translates binary data (e.g. {@link ByteBuf}) into a Java object.</li>
186  * <li>Protocol Encoder - translates a Java object into binary data.</li>
187  * <li>Business Logic Handler - performs the actual business logic.</li>
188  * </ol>
189  *
190  * and it could be represented as shown in the following example:
191  *
192  * <pre>
193  * ...
194  *
195  * {@link ChannelPipeline} pipeline = ch.pipeline();
196  *
197  * pipeline.addLast("decoder", new MyProtocolDecoder());
198  * pipeline.addLast("encoder", new MyProtocolEncoder());
199  * pipeline.addLast("handler", new MyBusinessLogicHandler());
200  * </pre>
201  *
202  * <h3>Thread safety</h3>
203  * <p>
204  * A {@link ChannelHandler} can be added or removed at any time because a {@link ChannelPipeline} is thread safe.
205  * For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it
206  * after the exchange.
207  */
208 public interface ChannelPipeline
209         extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> {
210 
211     /**
212      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
213      *
214      * @param name     the name of the handler to insert first
215      * @param handler  the handler to insert first
216      *
217      * @throws IllegalArgumentException
218      *         if there's an entry with the same name already in the pipeline
219      * @throws NullPointerException
220      *         if the specified handler is {@code null}
221      */
222     ChannelPipeline addFirst(String name, ChannelHandler handler);
223 
224     /**
225      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
226      *
227      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
228      *                 methods
229      * @param name     the name of the handler to insert first
230      * @param handler  the handler to insert first
231      *
232      * @throws IllegalArgumentException
233      *         if there's an entry with the same name already in the pipeline
234      * @throws NullPointerException
235      *         if the specified handler is {@code null}
236      * @deprecated use {@link #addFirst(String, ChannelHandler)}
237      */
238     @Deprecated
239     ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
240 
241     /**
242      * Appends a {@link ChannelHandler} at the last position of this pipeline.
243      *
244      * @param name     the name of the handler to append
245      * @param handler  the handler to append
246      *
247      * @throws IllegalArgumentException
248      *         if there's an entry with the same name already in the pipeline
249      * @throws NullPointerException
250      *         if the specified handler is {@code null}
251      */
252     ChannelPipeline addLast(String name, ChannelHandler handler);
253 
254     /**
255      * Appends a {@link ChannelHandler} at the last position of this pipeline.
256      *
257      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
258      *                 methods
259      * @param name     the name of the handler to append
260      * @param handler  the handler to append
261      *
262      * @throws IllegalArgumentException
263      *         if there's an entry with the same name already in the pipeline
264      * @throws NullPointerException
265      *         if the specified handler is {@code null}
266      * @deprecated use {@link #addLast(String, ChannelHandler)}
267      */
268     @Deprecated
269     ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
270 
271     /**
272      * Inserts a {@link ChannelHandler} before an existing handler of this
273      * pipeline.
274      *
275      * @param baseName  the name of the existing handler
276      * @param name      the name of the handler to insert before
277      * @param handler   the handler to insert before
278      *
279      * @throws NoSuchElementException
280      *         if there's no such entry with the specified {@code baseName}
281      * @throws IllegalArgumentException
282      *         if there's an entry with the same name already in the pipeline
283      * @throws NullPointerException
284      *         if the specified baseName or handler is {@code null}
285      */
286     ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
287 
288     /**
289      * Inserts a {@link ChannelHandler} before an existing handler of this
290      * pipeline.
291      *
292      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
293      *                  methods
294      * @param baseName  the name of the existing handler
295      * @param name      the name of the handler to insert before
296      * @param handler   the handler to insert before
297      *
298      * @throws NoSuchElementException
299      *         if there's no such entry with the specified {@code baseName}
300      * @throws IllegalArgumentException
301      *         if there's an entry with the same name already in the pipeline
302      * @throws NullPointerException
303      *         if the specified baseName or handler is {@code null}
304      * @deprecated use {@link #addBefore(String, String, ChannelHandler)}
305      */
306     @Deprecated
307     ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
308 
309     /**
310      * Inserts a {@link ChannelHandler} after an existing handler of this
311      * pipeline.
312      *
313      * @param baseName  the name of the existing handler
314      * @param name      the name of the handler to insert after
315      * @param handler   the handler to insert after
316      *
317      * @throws NoSuchElementException
318      *         if there's no such entry with the specified {@code baseName}
319      * @throws IllegalArgumentException
320      *         if there's an entry with the same name already in the pipeline
321      * @throws NullPointerException
322      *         if the specified baseName or handler is {@code null}
323      */
324     ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
325 
326     /**
327      * Inserts a {@link ChannelHandler} after an existing handler of this
328      * pipeline.
329      *
330      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
331      *                  methods
332      * @param baseName  the name of the existing handler
333      * @param name      the name of the handler to insert after
334      * @param handler   the handler to insert after
335      *
336      * @throws NoSuchElementException
337      *         if there's no such entry with the specified {@code baseName}
338      * @throws IllegalArgumentException
339      *         if there's an entry with the same name already in the pipeline
340      * @throws NullPointerException
341      *         if the specified baseName or handler is {@code null}
342      * @deprecated use {@link #addAfter(String, String, ChannelHandler)}
343      */
344     @Deprecated
345     ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
346 
347     /**
348      * Inserts {@link ChannelHandler}s at the first position of this pipeline.
349      *
350      * @param handlers  the handlers to insert first
351      *
352      */
353     ChannelPipeline addFirst(ChannelHandler... handlers);
354 
355     /**
356      * Inserts {@link ChannelHandler}s at the first position of this pipeline.
357      *
358      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
359      *                  methods.
360      * @param handlers  the handlers to insert first
361      * @deprecated use {@link #addFirst(String, ChannelHandler)}
362      */
363     @Deprecated
364     ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
365 
366     /**
367      * Inserts {@link ChannelHandler}s at the last position of this pipeline.
368      *
369      * @param handlers  the handlers to insert last
370      *
371      */
372     ChannelPipeline addLast(ChannelHandler... handlers);
373 
374     /**
375      * Inserts {@link ChannelHandler}s at the last position of this pipeline.
376      *
377      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
378      *                  methods.
379      * @param handlers  the handlers to insert last
380      * @deprecated use {@link #addLast(ChannelHandler...)}
381      */
382     @Deprecated
383     ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
384 
385     /**
386      * Removes the specified {@link ChannelHandler} from this pipeline.
387      *
388      * @param  handler          the {@link ChannelHandler} to remove
389      *
390      * @throws NoSuchElementException
391      *         if there's no such handler in this pipeline
392      * @throws NullPointerException
393      *         if the specified handler is {@code null}
394      */
395     ChannelPipeline remove(ChannelHandler handler);
396 
397     /**
398      * Removes the {@link ChannelHandler} with the specified name from this pipeline.
399      *
400      * @param  name             the name under which the {@link ChannelHandler} was stored.
401      *
402      * @return the removed handler
403      *
404      * @throws NoSuchElementException
405      *         if there's no such handler with the specified name in this pipeline
406      * @throws NullPointerException
407      *         if the specified name is {@code null}
408      */
409     ChannelHandler remove(String name);
410 
411     /**
412      * Removes the {@link ChannelHandler} of the specified type from this pipeline.
413      *
414      * @param <T>           the type of the handler
415      * @param handlerType   the type of the handler
416      *
417      * @return the removed handler
418      *
419      * @throws NoSuchElementException
420      *         if there's no such handler of the specified type in this pipeline
421      * @throws NullPointerException
422      *         if the specified handler type is {@code null}
423      */
424     <T extends ChannelHandler> T remove(Class<T> handlerType);
425 
426     /**
427      * Removes the first {@link ChannelHandler} in this pipeline.
428      *
429      * @return the removed handler
430      *
431      * @throws NoSuchElementException
432      *         if this pipeline is empty
433      */
434     ChannelHandler removeFirst();
435 
436     /**
437      * Removes the last {@link ChannelHandler} in this pipeline.
438      *
439      * @return the removed handler
440      *
441      * @throws NoSuchElementException
442      *         if this pipeline is empty
443      */
444     ChannelHandler removeLast();
445 
446     /**
447      * Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
448      *
449      * @param  oldHandler    the {@link ChannelHandler} to be replaced
450      * @param  newName       the name under which the replacement should be added
451      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
452      *
453      * @return itself
454 
455      * @throws NoSuchElementException
456      *         if the specified old handler does not exist in this pipeline
457      * @throws IllegalArgumentException
458      *         if a handler with the specified new name already exists in this
459      *         pipeline, except for the handler to be replaced
460      * @throws NullPointerException
461      *         if the specified old handler or new handler is
462      *         {@code null}
463      */
464     ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
465 
466     /**
467      * Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline.
468      *
469      * @param  oldName       the name of the {@link ChannelHandler} to be replaced
470      * @param  newName       the name under which the replacement should be added
471      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
472      *
473      * @return the removed handler
474      *
475      * @throws NoSuchElementException
476      *         if the handler with the specified old name does not exist in this pipeline
477      * @throws IllegalArgumentException
478      *         if a handler with the specified new name already exists in this
479      *         pipeline, except for the handler to be replaced
480      * @throws NullPointerException
481      *         if the specified old handler or new handler is
482      *         {@code null}
483      */
484     ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
485 
486     /**
487      * Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline.
488      *
489      * @param  oldHandlerType   the type of the handler to be removed
490      * @param  newName          the name under which the replacement should be added
491      * @param  newHandler       the {@link ChannelHandler} which is used as replacement
492      *
493      * @return the removed handler
494      *
495      * @throws NoSuchElementException
496      *         if the handler of the specified old handler type does not exist
497      *         in this pipeline
498      * @throws IllegalArgumentException
499      *         if a handler with the specified new name already exists in this
500      *         pipeline, except for the handler to be replaced
501      * @throws NullPointerException
502      *         if the specified old handler or new handler is
503      *         {@code null}
504      */
505     <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
506                                          ChannelHandler newHandler);
507 
508     /**
509      * Returns the first {@link ChannelHandler} in this pipeline.
510      *
511      * @return the first handler.  {@code null} if this pipeline is empty.
512      */
513     ChannelHandler first();
514 
515     /**
516      * Returns the context of the first {@link ChannelHandler} in this pipeline.
517      *
518      * @return the context of the first handler.  {@code null} if this pipeline is empty.
519      */
520     ChannelHandlerContext firstContext();
521 
522     /**
523      * Returns the last {@link ChannelHandler} in this pipeline.
524      *
525      * @return the last handler.  {@code null} if this pipeline is empty.
526      */
527     ChannelHandler last();
528 
529     /**
530      * Returns the context of the last {@link ChannelHandler} in this pipeline.
531      *
532      * @return the context of the last handler.  {@code null} if this pipeline is empty.
533      */
534     ChannelHandlerContext lastContext();
535 
536     /**
537      * Returns the {@link ChannelHandler} with the specified name in this
538      * pipeline.
539      *
540      * @return the handler with the specified name.
541      *         {@code null} if there's no such handler in this pipeline.
542      */
543     ChannelHandler get(String name);
544 
545     /**
546      * Returns the {@link ChannelHandler} of the specified type in this
547      * pipeline.
548      *
549      * @return the handler of the specified handler type.
550      *         {@code null} if there's no such handler in this pipeline.
551      */
552     <T extends ChannelHandler> T get(Class<T> handlerType);
553 
554     /**
555      * Returns the context object of the specified {@link ChannelHandler} in
556      * this pipeline.
557      *
558      * @return the context object of the specified handler.
559      *         {@code null} if there's no such handler in this pipeline.
560      */
561     ChannelHandlerContext context(ChannelHandler handler);
562 
563     /**
564      * Returns the context object of the {@link ChannelHandler} with the
565      * specified name in this pipeline.
566      *
567      * @return the context object of the handler with the specified name.
568      *         {@code null} if there's no such handler in this pipeline.
569      */
570     ChannelHandlerContext context(String name);
571 
572     /**
573      * Returns the context object of the {@link ChannelHandler} of the
574      * specified type in this pipeline.
575      *
576      * @return the context object of the handler of the specified type.
577      *         {@code null} if there's no such handler in this pipeline.
578      */
579     ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);
580 
581     /**
582      * Returns the {@link Channel} that this pipeline is attached to.
583      *
584      * @return the channel. {@code null} if this pipeline is not attached yet.
585      */
586     Channel channel();
587 
588     /**
589      * Returns the {@link List} of the handler names.
590      */
591     List<String> names();
592 
593     /**
594      * Converts this pipeline into an ordered {@link Map} whose keys are
595      * handler names and whose values are handlers.
596      */
597     Map<String, ChannelHandler> toMap();
598 
599     @Override
600     ChannelPipeline fireChannelRegistered();
601 
602     @Override
603     ChannelPipeline fireChannelUnregistered();
604 
605     @Override
606     ChannelPipeline fireChannelActive();
607 
608     @Override
609     ChannelPipeline fireChannelInactive();
610 
611     @Override
612     ChannelPipeline fireExceptionCaught(Throwable cause);
613 
614     @Override
615     ChannelPipeline fireUserEventTriggered(Object event);
616 
617     @Override
618     ChannelPipeline fireChannelRead(Object msg);
619 
620     @Override
621     ChannelPipeline fireChannelReadComplete();
622 
623     @Override
624     ChannelPipeline fireChannelWritabilityChanged();
625 
626     @Override
627     ChannelPipeline flush();
628 
629     @Override
630     default ChannelPromise newPromise() {
631         return new DefaultChannelPromise(channel());
632     }
633 
634     @Override
635     default ChannelProgressivePromise newProgressivePromise() {
636         return new DefaultChannelProgressivePromise(channel());
637     }
638 
639     @Override
640     default ChannelFuture newFailedFuture(Throwable cause) {
641         return new FailedChannelFuture(channel(), null, cause);
642     }
643 }