@@ -30,12 +30,19 @@ final case class NettyConfig(
30
30
nThreads : Int ,
31
31
shutdownQuietPeriodDuration : Duration ,
32
32
shutdownTimeoutDuration : Duration ,
33
+ bossGroup : NettyConfig .BossGroup ,
33
34
) extends EventLoopGroups .Config { self =>
34
35
36
+ /**
37
+ * Configure Netty's boss event-loop group. This only applies to server
38
+ * applications and is ignored for the Client
39
+ */
40
+ def bossGroup (cfg : NettyConfig .BossGroup ): NettyConfig = self.copy(bossGroup = cfg)
41
+
35
42
def channelType (channelType : ChannelType ): NettyConfig = self.copy(channelType = channelType)
36
43
37
44
/**
38
- * Configure the server to use the leak detection level provided.
45
+ * Configure Netty to use the leak detection level provided.
39
46
*
40
47
* @see
41
48
* <a
@@ -44,50 +51,104 @@ final case class NettyConfig(
44
51
def leakDetection (level : LeakDetectionLevel ): NettyConfig = self.copy(leakDetectionLevel = level)
45
52
46
53
/**
47
- * Configure the server to use a maximum of nThreads to process requests.
54
+ * Configure Netty to use a maximum of `nThreads` for the worker event-loop
55
+ * group.
48
56
*/
49
57
def maxThreads (nThreads : Int ): NettyConfig = self.copy(nThreads = nThreads)
50
58
51
- val shutdownTimeUnit : TimeUnit = TimeUnit .MILLISECONDS
52
-
53
- val shutdownQuietPeriod : Long = shutdownQuietPeriodDuration.toMillis
54
- val shutdownTimeOut : Long = shutdownTimeoutDuration.toMillis
59
+ def shutdownTimeUnit : TimeUnit = TimeUnit .MILLISECONDS
60
+ def shutdownQuietPeriod : Long = shutdownQuietPeriodDuration.toMillis
61
+ def shutdownTimeOut : Long = shutdownTimeoutDuration.toMillis
55
62
}
56
63
57
64
object NettyConfig {
58
- def config : Config [NettyConfig ] =
59
- (LeakDetectionLevel .config.nested(" leak-detection-level" ).withDefault(NettyConfig .default.leakDetectionLevel) ++
60
- Config
61
- .string(" channel-type" )
62
- .mapOrFail {
63
- case " auto" => Right (ChannelType .AUTO )
64
- case " nio" => Right (ChannelType .NIO )
65
- case " epoll" => Right (ChannelType .EPOLL )
66
- case " kqueue" => Right (ChannelType .KQUEUE )
67
- case " uring" => Right (ChannelType .URING )
68
- case other => Left (Config .Error .InvalidData (message = s " Invalid channel type: $other" ))
69
- }
70
- .withDefault(NettyConfig .default.channelType) ++
65
+ final case class BossGroup (
66
+ channelType : ChannelType ,
67
+ nThreads : Int ,
68
+ shutdownQuietPeriodDuration : Duration ,
69
+ shutdownTimeOutDuration : Duration ,
70
+ ) extends EventLoopGroups .Config {
71
+ def shutdownTimeUnit : TimeUnit = TimeUnit .MILLISECONDS
72
+ def shutdownQuietPeriod : Long = shutdownQuietPeriodDuration.toMillis
73
+ def shutdownTimeOut : Long = shutdownTimeOutDuration.toMillis
74
+ }
75
+
76
+ private def baseConfig : Config [EventLoopGroups .Config ] =
77
+ (Config
78
+ .string(" channel-type" )
79
+ .mapOrFail {
80
+ case " auto" => Right (ChannelType .AUTO )
81
+ case " nio" => Right (ChannelType .NIO )
82
+ case " epoll" => Right (ChannelType .EPOLL )
83
+ case " kqueue" => Right (ChannelType .KQUEUE )
84
+ case " uring" => Right (ChannelType .URING )
85
+ case other => Left (Config .Error .InvalidData (message = s " Invalid channel type: $other" ))
86
+ }
87
+ .withDefault(NettyConfig .default.channelType) ++
71
88
Config .int(" max-threads" ).withDefault(NettyConfig .default.nThreads) ++
72
89
Config .duration(" shutdown-quiet-period" ).withDefault(NettyConfig .default.shutdownQuietPeriodDuration) ++
73
90
Config .duration(" shutdown-timeout" ).withDefault(NettyConfig .default.shutdownTimeoutDuration)).map {
74
- case (leakDetectionLevel, channelType, maxThreads, quietPeriod, timeout) =>
75
- NettyConfig (leakDetectionLevel, channelType, maxThreads, quietPeriod, timeout)
91
+ case (channelT, maxThreads, quietPeriod, timeout) =>
92
+ new EventLoopGroups .Config {
93
+ override val channelType : ChannelType = channelT
94
+ override val nThreads : Int = maxThreads
95
+ override val shutdownQuietPeriod : Long = quietPeriod.toMillis
96
+ override val shutdownTimeOut : Long = timeout.toMillis
97
+ override val shutdownTimeUnit : TimeUnit = TimeUnit .MILLISECONDS
98
+ }
76
99
}
77
100
78
- val default : NettyConfig = NettyConfig (
79
- LeakDetectionLevel .SIMPLE ,
80
- ChannelType .AUTO ,
81
- 0 ,
82
- // Defaults taken from io.netty.util.concurrent.AbstractEventExecutor
83
- Duration .fromSeconds(2 ),
84
- Duration .fromSeconds(15 ),
85
- )
86
-
87
- val defaultWithFastShutdown : NettyConfig = default.copy(
88
- shutdownQuietPeriodDuration = Duration .fromMillis(50 ),
89
- shutdownTimeoutDuration = Duration .fromMillis(250 ),
90
- )
101
+ def config : Config [NettyConfig ] =
102
+ (LeakDetectionLevel .config.nested(" leak-detection-level" ).withDefault(NettyConfig .default.leakDetectionLevel) ++
103
+ baseConfig.nested(" worker-group" ).orElse(baseConfig) ++
104
+ baseConfig.nested(" boss-group" )).map { case (leakDetectionLevel, worker, boss) =>
105
+ def toDuration (n : Long , timeUnit : TimeUnit ) = Duration .fromJava(java.time.Duration .of(n, timeUnit.toChronoUnit))
106
+ NettyConfig (
107
+ leakDetectionLevel,
108
+ worker.channelType,
109
+ worker.nThreads,
110
+ shutdownQuietPeriodDuration = toDuration(worker.shutdownQuietPeriod, worker.shutdownTimeUnit),
111
+ shutdownTimeoutDuration = toDuration(worker.shutdownTimeOut, worker.shutdownTimeUnit),
112
+ NettyConfig .BossGroup (
113
+ boss.channelType,
114
+ boss.nThreads,
115
+ shutdownQuietPeriodDuration = toDuration(boss.shutdownQuietPeriod, boss.shutdownTimeUnit),
116
+ shutdownTimeOutDuration = toDuration(boss.shutdownTimeOut, boss.shutdownTimeUnit),
117
+ ),
118
+ )
119
+ }
120
+
121
+ val default : NettyConfig = {
122
+ val quietPeriod = Duration .fromSeconds(2 )
123
+ val timeout = Duration .fromSeconds(15 )
124
+ NettyConfig (
125
+ LeakDetectionLevel .SIMPLE ,
126
+ ChannelType .AUTO ,
127
+ java.lang.Runtime .getRuntime.availableProcessors(),
128
+ // Defaults taken from io.netty.util.concurrent.AbstractEventExecutor
129
+ shutdownQuietPeriodDuration = quietPeriod,
130
+ shutdownTimeoutDuration = timeout,
131
+ NettyConfig .BossGroup (
132
+ ChannelType .AUTO ,
133
+ 1 ,
134
+ shutdownQuietPeriodDuration = quietPeriod,
135
+ shutdownTimeOutDuration = timeout,
136
+ ),
137
+ )
138
+ }
139
+
140
+ val defaultWithFastShutdown : NettyConfig = {
141
+ val quietPeriod = Duration .fromMillis(50 )
142
+ val timeout = Duration .fromMillis(250 )
143
+ default.copy(
144
+ shutdownQuietPeriodDuration = quietPeriod,
145
+ shutdownTimeoutDuration = timeout,
146
+ bossGroup = default.bossGroup.copy(
147
+ shutdownQuietPeriodDuration = quietPeriod,
148
+ shutdownTimeOutDuration = timeout,
149
+ ),
150
+ )
151
+ }
91
152
92
153
sealed trait LeakDetectionLevel {
93
154
self =>
0 commit comments