@@ -70,7 +70,7 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
70
70
private let index = ManagedAtomic < Int > ( 0 )
71
71
private var eventLoops : [ SelectableEventLoop ]
72
72
private let shutdownLock : NIOLock = NIOLock ( )
73
- private let threadNamePrefix : String
73
+ private let threadNamePrefix : Optional < String >
74
74
private var runState : RunState = . running
75
75
private let canBeShutDown : Bool
76
76
@@ -108,7 +108,8 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
108
108
}
109
109
110
110
private static func setupThreadAndEventLoop(
111
- name: String ,
111
+ name: String ? ,
112
+ threadConfiguration: NIOThreadConfiguration ,
112
113
parentGroup: MultiThreadedEventLoopGroup ,
113
114
selectorFactory: @escaping ( ) throws -> NIOPosix . Selector < NIORegistration > ,
114
115
initializer: @escaping ThreadInitializer ,
@@ -119,7 +120,7 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
119
120
// synchronised by `lock`
120
121
var _loop : SelectableEventLoop ! = nil
121
122
122
- NIOThread . spawnAndRun ( name: name, detachThread: false ) { t in
123
+ NIOThread . spawnAndRun ( name: name, configuration : threadConfiguration , detachThread: false ) { t in
123
124
MultiThreadedEventLoopGroup . runTheLoop (
124
125
thread: t,
125
126
parentGroup: parentGroup,
@@ -150,6 +151,7 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
150
151
public convenience init ( numberOfThreads: Int ) {
151
152
self . init (
152
153
numberOfThreads: numberOfThreads,
154
+ threadConfiguration: . defaultForEventLoopGroups,
153
155
canBeShutDown: true ,
154
156
metricsDelegate: nil ,
155
157
selectorFactory: NIOPosix . Selector< NIORegistration> . init
@@ -169,6 +171,32 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
169
171
public convenience init ( numberOfThreads: Int , metricsDelegate: NIOEventLoopMetricsDelegate ) {
170
172
self . init (
171
173
numberOfThreads: numberOfThreads,
174
+ threadConfiguration: . defaultForEventLoopGroups,
175
+ canBeShutDown: true ,
176
+ metricsDelegate: metricsDelegate,
177
+ selectorFactory: NIOPosix . Selector< NIORegistration> . init
178
+ )
179
+ }
180
+
181
+ /// Creates a `MultiThreadedEventLoopGroup` instance which uses `numberOfThreads`.
182
+ ///
183
+ /// - note: Don't forget to call `shutdownGracefully` or `syncShutdownGracefully` when you no longer need this
184
+ /// `EventLoopGroup`. If you forget to shut the `EventLoopGroup` down you will leak `numberOfThreads`
185
+ /// (kernel) threads which are costly resources. This is especially important in unit tests where one
186
+ /// `MultiThreadedEventLoopGroup` is started per test case.
187
+ ///
188
+ /// - Parameters:
189
+ /// - numberOfThreads: The number of `Threads` to use.
190
+ /// - threadConfiguration: Configuration for the threads to spawn.
191
+ /// - metricsDelegate: Delegate for collecting information from this eventloop
192
+ public convenience init (
193
+ numberOfThreads: Int ,
194
+ threadConfiguration: NIOThreadConfiguration ,
195
+ metricsDelegate: NIOEventLoopMetricsDelegate ? = nil
196
+ ) {
197
+ self . init (
198
+ numberOfThreads: numberOfThreads,
199
+ threadConfiguration: threadConfiguration,
172
200
canBeShutDown: true ,
173
201
metricsDelegate: metricsDelegate,
174
202
selectorFactory: NIOPosix . Selector< NIORegistration> . init
@@ -179,20 +207,21 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
179
207
///
180
208
/// This is only useful for global singletons.
181
209
public static func _makePerpetualGroup(
182
- threadNamePrefix : String ,
183
- numberOfThreads : Int
210
+ numberOfThreads : Int ,
211
+ threadConfiguration : NIOThreadConfiguration
184
212
) -> MultiThreadedEventLoopGroup {
185
213
self . init (
186
214
numberOfThreads: numberOfThreads,
215
+ threadConfiguration: threadConfiguration,
187
216
canBeShutDown: false ,
188
- threadNamePrefix: threadNamePrefix,
189
217
metricsDelegate: nil ,
190
218
selectorFactory: NIOPosix . Selector< NIORegistration> . init
191
219
)
192
220
}
193
221
194
222
internal convenience init (
195
223
numberOfThreads: Int ,
224
+ threadConfiguration: NIOThreadConfiguration ,
196
225
metricsDelegate: NIOEventLoopMetricsDelegate ? ,
197
226
selectorFactory: @escaping ( ) throws -> NIOPosix . Selector < NIORegistration >
198
227
) {
@@ -201,31 +230,15 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
201
230
self . init (
202
231
threadInitializers: initializers,
203
232
canBeShutDown: true ,
233
+ threadConfiguration: threadConfiguration,
204
234
metricsDelegate: metricsDelegate,
205
235
selectorFactory: selectorFactory
206
236
)
207
237
}
208
238
209
239
internal convenience init (
210
240
numberOfThreads: Int ,
211
- canBeShutDown: Bool ,
212
- threadNamePrefix: String ,
213
- metricsDelegate: NIOEventLoopMetricsDelegate ? ,
214
- selectorFactory: @escaping ( ) throws -> NIOPosix . Selector < NIORegistration >
215
- ) {
216
- precondition ( numberOfThreads > 0 , " numberOfThreads must be positive " )
217
- let initializers : [ ThreadInitializer ] = Array ( repeating: { _ in } , count: numberOfThreads)
218
- self . init (
219
- threadInitializers: initializers,
220
- canBeShutDown: canBeShutDown,
221
- threadNamePrefix: threadNamePrefix,
222
- metricsDelegate: metricsDelegate,
223
- selectorFactory: selectorFactory
224
- )
225
- }
226
-
227
- internal convenience init (
228
- numberOfThreads: Int ,
241
+ threadConfiguration: NIOThreadConfiguration ,
229
242
canBeShutDown: Bool ,
230
243
metricsDelegate: NIOEventLoopMetricsDelegate ? ,
231
244
selectorFactory: @escaping ( ) throws -> NIOPosix . Selector < NIORegistration >
@@ -235,20 +248,23 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
235
248
self . init (
236
249
threadInitializers: initializers,
237
250
canBeShutDown: canBeShutDown,
251
+ threadConfiguration: threadConfiguration,
238
252
metricsDelegate: metricsDelegate,
239
253
selectorFactory: selectorFactory
240
254
)
241
255
}
242
256
243
257
internal convenience init (
244
258
threadInitializers: [ ThreadInitializer ] ,
259
+ threadConfiguration: NIOThreadConfiguration ,
245
260
metricsDelegate: NIOEventLoopMetricsDelegate ? ,
246
261
selectorFactory: @escaping ( ) throws -> NIOPosix . Selector < NIORegistration > = NIOPosix . Selector< NIORegistration>
247
262
. init
248
263
) {
249
264
self . init (
250
265
threadInitializers: threadInitializers,
251
266
canBeShutDown: true ,
267
+ threadConfiguration: threadConfiguration,
252
268
metricsDelegate: metricsDelegate,
253
269
selectorFactory: selectorFactory
254
270
)
@@ -261,12 +277,12 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
261
277
internal init (
262
278
threadInitializers: [ ThreadInitializer ] ,
263
279
canBeShutDown: Bool ,
264
- threadNamePrefix : String = " NIO-ELT- " ,
280
+ threadConfiguration : NIOThreadConfiguration ,
265
281
metricsDelegate: NIOEventLoopMetricsDelegate ? ,
266
282
selectorFactory: @escaping ( ) throws -> NIOPosix . Selector < NIORegistration > = NIOPosix . Selector< NIORegistration>
267
283
. init
268
284
) {
269
- self . threadNamePrefix = threadNamePrefix
285
+ self . threadNamePrefix = threadConfiguration . threadNamePrefix
270
286
let myGroupID = nextEventLoopGroupID. loadThenWrappingIncrement ( ordering: . relaxed)
271
287
self . myGroupID = myGroupID
272
288
var idx = 0
@@ -275,7 +291,8 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
275
291
self . eventLoops = threadInitializers. map { initializer in
276
292
// Maximum name length on linux is 16 by default.
277
293
let ev = MultiThreadedEventLoopGroup . setupThreadAndEventLoop (
278
- name: " \( threadNamePrefix) \( myGroupID) -# \( idx) " ,
294
+ name: self . threadNamePrefix. map { " \( $0) \( myGroupID) -# \( idx) " } ,
295
+ threadConfiguration: threadConfiguration,
279
296
parentGroup: self ,
280
297
selectorFactory: selectorFactory,
281
298
initializer: initializer,
0 commit comments