@@ -127,10 +127,10 @@ impl WorkerAvailability {
127
127
pub ( crate ) struct ServerWorker {
128
128
rx : UnboundedReceiver < Conn > ,
129
129
rx2 : UnboundedReceiver < Stop > ,
130
- services : Vec < WorkerService > ,
130
+ services : Box < [ WorkerService ] > ,
131
131
availability : WorkerAvailability ,
132
132
conns : Counter ,
133
- factories : Vec < Box < dyn InternalServiceFactory > > ,
133
+ factories : Box < [ Box < dyn InternalServiceFactory > ] > ,
134
134
state : WorkerState ,
135
135
shutdown_timeout : Duration ,
136
136
}
@@ -199,6 +199,8 @@ impl ServerWorker {
199
199
availability : WorkerAvailability ,
200
200
config : ServerWorkerConfig ,
201
201
) -> ( WorkerHandleAccept , WorkerHandleServer ) {
202
+ assert ! ( !availability. available( ) ) ;
203
+
202
204
let ( tx1, rx) = unbounded_channel ( ) ;
203
205
let ( tx2, rx2) = unbounded_channel ( ) ;
204
206
let avail = availability. clone ( ) ;
@@ -213,20 +215,7 @@ impl ServerWorker {
213
215
. unwrap ( )
214
216
} )
215
217
. spawn ( async move {
216
- availability. set ( false ) ;
217
- let mut wrk = ServerWorker {
218
- rx,
219
- rx2,
220
- services : Vec :: new ( ) ,
221
- availability,
222
- conns : Counter :: new ( config. max_concurrent_connections ) ,
223
- factories,
224
- state : Default :: default ( ) ,
225
- shutdown_timeout : config. shutdown_timeout ,
226
- } ;
227
-
228
- let fut = wrk
229
- . factories
218
+ let fut = factories
230
219
. iter ( )
231
220
. enumerate ( )
232
221
. map ( |( idx, factory) | {
@@ -239,29 +228,44 @@ impl ServerWorker {
239
228
} )
240
229
. collect :: < Vec < _ > > ( ) ;
241
230
242
- // a second spawn to make sure worker future runs as non boxed future.
243
- // As Arbiter::spawn would box the future before send it to arbiter.
231
+ // a second spawn to run !Send future tasks.
244
232
spawn ( async move {
245
- let res: Result < Vec < _ > , _ > = join_all ( fut) . await . into_iter ( ) . collect ( ) ;
246
- match res {
247
- Ok ( services) => {
248
- for item in services {
249
- for ( factory, token, service) in item {
250
- assert_eq ! ( token. 0 , wrk. services. len( ) ) ;
251
- wrk. services . push ( WorkerService {
252
- factory,
253
- service,
254
- status : WorkerServiceStatus :: Unavailable ,
255
- } ) ;
256
- }
257
- }
258
- }
233
+ let res = join_all ( fut)
234
+ . await
235
+ . into_iter ( )
236
+ . collect :: < Result < Vec < _ > , _ > > ( ) ;
237
+ let services = match res {
238
+ Ok ( res) => res
239
+ . into_iter ( )
240
+ . flatten ( )
241
+ . fold ( Vec :: new ( ) , |mut services, ( factory, token, service) | {
242
+ assert_eq ! ( token. 0 , services. len( ) ) ;
243
+ services. push ( WorkerService {
244
+ factory,
245
+ service,
246
+ status : WorkerServiceStatus :: Unavailable ,
247
+ } ) ;
248
+ services
249
+ } )
250
+ . into_boxed_slice ( ) ,
259
251
Err ( e) => {
260
252
error ! ( "Can not start worker: {:?}" , e) ;
261
253
Arbiter :: current ( ) . stop ( ) ;
254
+ return ;
262
255
}
263
- }
264
- wrk. await
256
+ } ;
257
+
258
+ // a third spawn to make sure ServerWorker runs as non boxed future.
259
+ spawn ( ServerWorker {
260
+ rx,
261
+ rx2,
262
+ services,
263
+ availability,
264
+ conns : Counter :: new ( config. max_concurrent_connections ) ,
265
+ factories : factories. into_boxed_slice ( ) ,
266
+ state : Default :: default ( ) ,
267
+ shutdown_timeout : config. shutdown_timeout ,
268
+ } ) ;
265
269
} ) ;
266
270
} ) ;
267
271
0 commit comments