View Javadoc
1   /*
2    * Copyright 2013 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.group;
17  
18  import io.netty5.bootstrap.ServerBootstrap;
19  import io.netty5.buffer.api.Buffer;
20  import io.netty5.buffer.api.DefaultBufferAllocators;
21  import io.netty5.channel.Channel;
22  import io.netty5.channel.ChannelHandler;
23  import io.netty5.channel.ChannelHandlerContext;
24  import io.netty5.channel.ChannelId;
25  import io.netty5.channel.EventLoop;
26  import io.netty5.channel.ServerChannel;
27  import io.netty5.util.concurrent.GlobalEventExecutor;
28  
29  import java.nio.charset.StandardCharsets;
30  import java.util.Set;
31  
32  /**
33   * A thread-safe {@link Set} that contains open {@link Channel}s and provides
34   * various bulk operations on them.  Using {@link ChannelGroup}, you can
35   * categorize {@link Channel}s into a meaningful group (e.g. on a per-service
36   * or per-state basis.)  A closed {@link Channel} is automatically removed from
37   * the collection, so that you don't need to worry about the life cycle of the
38   * added {@link Channel}.  A {@link Channel} can belong to more than one
39   * {@link ChannelGroup}.
40   *
41   * <h3>Broadcast a message to multiple {@link Channel}s</h3>
42   * <p>
43   * If you need to broadcast a message to more than one {@link Channel}, you can
44   * add the {@link Channel}s associated with the recipients and call {@link ChannelGroup#write(Object)}:
45   * <pre>
46   * <strong>{@link ChannelGroup} recipients =
47   *         new {@link DefaultChannelGroup}({@link GlobalEventExecutor}.INSTANCE);</strong>
48   * recipients.add(channelA);
49   * recipients.add(channelB);
50   * ..
51   * <strong>recipients.write({@link DefaultBufferAllocators#preferredAllocator()}.copyOf(
52   *         "Service will shut down for maintenance in 5 minutes.",
53   *         {@link StandardCharsets#UTF_8}));</strong>
54   * </pre>
55   *
56   * <h3>Simplify shutdown process with {@link ChannelGroup}</h3>
57   * <p>
58   * If both {@link ServerChannel}s and non-{@link ServerChannel}s exist in the
59   * same {@link ChannelGroup}, any requested I/O operations on the group are
60   * performed for the {@link ServerChannel}s first and then for the others.
61   * <p>
62   * This rule is very useful when you shut down a server in one shot:
63   *
64   * <pre>
65   * <strong>{@link ChannelGroup} allChannels =
66   *         new {@link DefaultChannelGroup}({@link GlobalEventExecutor}.INSTANCE);</strong>
67   *
68   * public static void main(String[] args) throws Exception {
69   *     {@link ServerBootstrap} b = new {@link ServerBootstrap}(..);
70   *     ...
71   *     b.childHandler(new MyHandler());
72   *
73   *     // Start the server
74   *     b.getPipeline().addLast("handler", new MyHandler());
75   *     {@link Channel} serverChannel = b.bind(..).sync();
76   *     <strong>allChannels.add(serverChannel);</strong>
77   *
78   *     ... Wait until the shutdown signal reception ...
79   *
80   *     // Close the serverChannel and then all accepted connections.
81   *     <strong>allChannels.close().await();</strong>
82   * }
83   *
84   * public class MyHandler implements {@link ChannelHandler} {
85   *     {@code @Override}
86   *     public void channelActive({@link ChannelHandlerContext} ctx) {
87   *         // closed on shutdown.
88   *         <strong>allChannels.add(ctx.channel());</strong>
89   *         ctx.fireChannelActive();
90   *     }
91   * }
92   * </pre>
93   */
94  public interface ChannelGroup extends Set<Channel>, Comparable<ChannelGroup> {
95  
96      /**
97       * Returns the name of this group.  A group name is purely for helping
98       * you to distinguish one group from others.
99       */
100     String name();
101 
102     /**
103      * Returns the {@link Channel} which has the specified {@link ChannelId}.
104      *
105      * @return the matching {@link Channel} if found. {@code null} otherwise.
106      */
107     Channel find(ChannelId id);
108 
109     /**
110      * Writes the specified {@code message} to all {@link Channel}s in this
111      * group.
112      * If the specified {@code message} is an instance of {@link Buffer}, it is automatically
113      * {@linkplain Buffer#copy() copied} to avoid a race condition.
114      * Please note that this operation is asynchronous as {@link Channel#write(Object)} is.
115      *
116      * @return itself
117      */
118     ChannelGroupFuture write(Object message);
119 
120     /**
121      * Writes the specified {@code message} to all {@link Channel}s in this
122      * group that are matched by the given {@link ChannelMatcher}.
123      * If the specified {@code message} is an instance of {@link Buffer}, it is automatically
124      * {@linkplain Buffer#copy() copied} to avoid a race condition.
125      * Please note that this operation is asynchronous as {@link Channel#write(Object)} is.
126      *
127      * @return the {@link ChannelGroupFuture} instance that notifies when
128      *         the operation is done for all channels
129      */
130     ChannelGroupFuture write(Object message, ChannelMatcher matcher);
131 
132     /**
133      * Flush all {@link Channel}s in this
134      * group.
135      * If the specified {@code message} is an instance of {@link Buffer}, it is automatically
136      * {@linkplain Buffer#copy() copied} to avoid a race condition.
137      * Please note that this operation is asynchronous as {@link Channel#flush()} is.
138      *
139      * @return the {@link ChannelGroupFuture} instance that notifies when
140      *         the operation is done for all channels
141      */
142     ChannelGroup flush();
143 
144     /**
145      * Flush all {@link Channel}s in this group that are matched by the given {@link ChannelMatcher}.
146      * If the specified {@code message} is an instance of {@link Buffer}, it is automatically
147      * {@linkplain Buffer#copy() copied} to avoid a race condition.
148      * Please note that this operation is asynchronous as {@link Channel#flush()} is.
149      *
150      * @return the {@link ChannelGroupFuture} instance that notifies when
151      *         the operation is done for all channels
152      */
153     ChannelGroup flush(ChannelMatcher matcher);
154 
155     /**
156      * Shortcut for calling {@link #write(Object)} and {@link #flush()}.
157      */
158     ChannelGroupFuture writeAndFlush(Object message);
159 
160     /**
161      * @deprecated Use {@link #writeAndFlush(Object)} instead.
162      */
163     @Deprecated
164     ChannelGroupFuture flushAndWrite(Object message);
165 
166     /**
167      * Shortcut for calling {@link #write(Object)} and {@link #flush()} and only act on
168      * {@link Channel}s that are matched by the {@link ChannelMatcher}.
169      */
170     ChannelGroupFuture writeAndFlush(Object message, ChannelMatcher matcher);
171 
172     /**
173      * @deprecated Use {@link #writeAndFlush(Object, ChannelMatcher)} instead.
174      */
175     @Deprecated
176     ChannelGroupFuture flushAndWrite(Object message, ChannelMatcher matcher);
177 
178     /**
179      * Disconnects all {@link Channel}s in this group from their remote peers.
180      *
181      * @return the {@link ChannelGroupFuture} instance that notifies when
182      *         the operation is done for all channels
183      */
184     ChannelGroupFuture disconnect();
185 
186     /**
187      * Disconnects all {@link Channel}s in this group from their remote peers,
188      * that are matched by the given {@link ChannelMatcher}.
189      *
190      * @return the {@link ChannelGroupFuture} instance that notifies when
191      *         the operation is done for all channels
192      */
193     ChannelGroupFuture disconnect(ChannelMatcher matcher);
194 
195     /**
196      * Closes all {@link Channel}s in this group.  If the {@link Channel} is
197      * connected to a remote peer or bound to a local address, it is
198      * automatically disconnected and unbound.
199      *
200      * @return the {@link ChannelGroupFuture} instance that notifies when
201      *         the operation is done for all channels
202      */
203     ChannelGroupFuture close();
204 
205     /**
206      * Closes all {@link Channel}s in this group that are matched by the given {@link ChannelMatcher}.
207      * If the {@link Channel} is  connected to a remote peer or bound to a local address, it is
208      * automatically disconnected and unbound.
209      *
210      * @return the {@link ChannelGroupFuture} instance that notifies when
211      *         the operation is done for all channels
212      */
213     ChannelGroupFuture close(ChannelMatcher matcher);
214 
215     /**
216      * @deprecated This method will be removed in the next major feature release.
217      *
218      * Deregister all {@link Channel}s in this group from their {@link EventLoop}.
219      * Please note that this operation is asynchronous as {@link Channel#deregister()} is.
220      *
221      * @return the {@link ChannelGroupFuture} instance that notifies when
222      *         the operation is done for all channels
223      */
224     @Deprecated
225     ChannelGroupFuture deregister();
226 
227     /**
228      * @deprecated This method will be removed in the next major feature release.
229      *
230      * Deregister all {@link Channel}s in this group from their {@link EventLoop} that are matched by the given
231      * {@link ChannelMatcher}. Please note that this operation is asynchronous as {@link Channel#deregister()} is.
232      *
233      * @return the {@link ChannelGroupFuture} instance that notifies when
234      *         the operation is done for all channels
235      */
236     @Deprecated
237     ChannelGroupFuture deregister(ChannelMatcher matcher);
238 
239     /**
240      * Returns the {@link ChannelGroupFuture} which will be notified when all {@link Channel}s that are part of this
241      * {@link ChannelGroup}, at the time of calling, are closed.
242      */
243     ChannelGroupFuture newCloseFuture();
244 
245     /**
246      * Returns the {@link ChannelGroupFuture} which will be notified when all {@link Channel}s that are part of this
247      * {@link ChannelGroup}, at the time of calling, are closed.
248      */
249     ChannelGroupFuture newCloseFuture(ChannelMatcher matcher);
250 }