25
25
import static io .grpc .internal .GrpcUtil .SERVER_KEEPALIVE_TIME_NANOS_DISABLED ;
26
26
27
27
import com .google .common .annotations .VisibleForTesting ;
28
- import com .google .common .base .Preconditions ;
29
28
import com .google .errorprone .annotations .CanIgnoreReturnValue ;
30
29
import io .grpc .ExperimentalApi ;
31
30
import io .grpc .Internal ;
36
35
import io .grpc .internal .KeepAliveManager ;
37
36
import io .grpc .internal .ObjectPool ;
38
37
import io .grpc .internal .SharedResourcePool ;
38
+ import io .netty .channel .ChannelFactory ;
39
39
import io .netty .channel .ChannelOption ;
40
40
import io .netty .channel .EventLoopGroup ;
41
+ import io .netty .channel .ReflectiveChannelFactory ;
41
42
import io .netty .channel .ServerChannel ;
42
43
import io .netty .channel .socket .nio .NioServerSocketChannel ;
43
44
import io .netty .handler .ssl .SslContext ;
@@ -79,7 +80,9 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
79
80
SharedResourcePool .forResource (Utils .DEFAULT_WORKER_EVENT_LOOP_GROUP );
80
81
81
82
private final List <SocketAddress > listenAddresses = new ArrayList <>();
82
- private Class <? extends ServerChannel > channelType = null ;
83
+
84
+ private ChannelFactory <? extends ServerChannel > channelFactory =
85
+ Utils .DEFAULT_SERVER_CHANNEL_FACTORY ;
83
86
private final Map <ChannelOption <?>, Object > channelOptions = new HashMap <>();
84
87
private ObjectPool <? extends EventLoopGroup > bossEventLoopGroupPool =
85
88
DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL ;
@@ -91,7 +94,7 @@ public final class NettyServerBuilder extends AbstractServerImplBuilder<NettySer
91
94
private int flowControlWindow = DEFAULT_FLOW_CONTROL_WINDOW ;
92
95
private int maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE ;
93
96
private int maxHeaderListSize = GrpcUtil .DEFAULT_MAX_HEADER_LIST_SIZE ;
94
- private long keepAliveTimeInNanos = DEFAULT_SERVER_KEEPALIVE_TIME_NANOS ;
97
+ private long keepAliveTimeInNanos = DEFAULT_SERVER_KEEPALIVE_TIME_NANOS ;
95
98
private long keepAliveTimeoutInNanos = DEFAULT_SERVER_KEEPALIVE_TIMEOUT_NANOS ;
96
99
private long maxConnectionIdleInNanos = MAX_CONNECTION_IDLE_NANOS_DISABLED ;
97
100
private long maxConnectionAgeInNanos = MAX_CONNECTION_AGE_NANOS_DISABLED ;
@@ -142,16 +145,41 @@ public NettyServerBuilder addListenAddress(SocketAddress listenAddress) {
142
145
}
143
146
144
147
/**
145
- * Specify the channel type to use, by default we use {@link NioServerSocketChannel} or {@code
146
- * EpollServerSocketChannel}.
148
+ * Specifies the channel type to use, by default we use {@code EpollServerSocketChannel} if
149
+ * available, otherwise using {@link NioServerSocketChannel}.
150
+ *
151
+ * <p>You either use this or {@link #channelFactory(io.netty.channel.ChannelFactory)} if your
152
+ * {@link ServerChannel} implementation has no no-args constructor.
153
+ *
154
+ * <p>It's an optional parameter. If the user has not provided an Channel type or ChannelFactory
155
+ * when the channel is built, the builder will use the default one which is static.
147
156
*
148
157
* <p>You must also provide corresponding {@link EventLoopGroup} using {@link
149
158
* #workerEventLoopGroup(EventLoopGroup)} and {@link #bossEventLoopGroup(EventLoopGroup)}. For
150
159
* example, {@link NioServerSocketChannel} must use {@link
151
160
* io.netty.channel.nio.NioEventLoopGroup}, otherwise your server won't start.
152
161
*/
153
162
public NettyServerBuilder channelType (Class <? extends ServerChannel > channelType ) {
154
- this .channelType = Preconditions .checkNotNull (channelType , "channelType" );
163
+ checkNotNull (channelType , "channelType" );
164
+ return channelFactory (new ReflectiveChannelFactory <>(channelType ));
165
+ }
166
+
167
+ /**
168
+ * Specifies the {@link ChannelFactory} to create {@link ServerChannel} instances. This method is
169
+ * usually only used if the specific {@code ServerChannel} requires complex logic which requires
170
+ * additional information to create the {@code ServerChannel}. Otherwise, recommend to use {@link
171
+ * #channelType(Class)}.
172
+ *
173
+ * <p>It's an optional parameter. If the user has not provided an Channel type or ChannelFactory
174
+ * when the channel is built, the builder will use the default one which is static.
175
+ *
176
+ * <p>You must also provide corresponding {@link EventLoopGroup} using {@link
177
+ * #workerEventLoopGroup(EventLoopGroup)} and {@link #bossEventLoopGroup(EventLoopGroup)}. For
178
+ * example, if the factory creates {@link NioServerSocketChannel} you must use {@link
179
+ * io.netty.channel.nio.NioEventLoopGroup}, otherwise your server won't start.
180
+ */
181
+ public NettyServerBuilder channelFactory (ChannelFactory <? extends ServerChannel > channelFactory ) {
182
+ this .channelFactory = checkNotNull (channelFactory , "channelFactory" );
155
183
return this ;
156
184
}
157
185
@@ -499,16 +527,13 @@ protected List<NettyServer> buildTransportServers(
499
527
ProtocolNegotiator negotiator = protocolNegotiator ;
500
528
if (negotiator == null ) {
501
529
negotiator = sslContext != null ? ProtocolNegotiators .serverTls (sslContext ) :
502
- ProtocolNegotiators .serverPlaintext ();
530
+ ProtocolNegotiators .serverPlaintext ();
503
531
}
504
532
505
- Class <? extends ServerChannel > resolvedChannelType =
506
- channelType == null ? Utils .DEFAULT_SERVER_CHANNEL_TYPE : channelType ;
507
-
508
533
List <NettyServer > transportServers = new ArrayList <>(listenAddresses .size ());
509
534
for (SocketAddress listenAddress : listenAddresses ) {
510
535
NettyServer transportServer = new NettyServer (
511
- listenAddress , resolvedChannelType , channelOptions , bossEventLoopGroupPool ,
536
+ listenAddress , channelFactory , channelOptions , bossEventLoopGroupPool ,
512
537
workerEventLoopGroupPool , negotiator , streamTracerFactories ,
513
538
getTransportTracerFactory (), maxConcurrentCallsPerConnection , flowControlWindow ,
514
539
maxMessageSize , maxHeaderListSize , keepAliveTimeInNanos , keepAliveTimeoutInNanos ,
@@ -521,10 +546,10 @@ protected List<NettyServer> buildTransportServers(
521
546
522
547
@ VisibleForTesting
523
548
void assertEventLoopsAndChannelType () {
524
- boolean allProvided = channelType != null
549
+ boolean allProvided = channelFactory != Utils . DEFAULT_SERVER_CHANNEL_FACTORY
525
550
&& bossEventLoopGroupPool != DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL
526
551
&& workerEventLoopGroupPool != DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL ;
527
- boolean nonProvided = channelType == null
552
+ boolean nonProvided = channelFactory == Utils . DEFAULT_SERVER_CHANNEL_FACTORY
528
553
&& bossEventLoopGroupPool == DEFAULT_BOSS_EVENT_LOOP_GROUP_POOL
529
554
&& workerEventLoopGroupPool == DEFAULT_WORKER_EVENT_LOOP_GROUP_POOL ;
530
555
checkState (
0 commit comments