@@ -252,7 +252,19 @@ async fn migrate_users(
252
252
let otel_kv = [ KeyValue :: new ( K_ENTITY , V_ENTITY_USERS ) ] ;
253
253
254
254
// HACK(matrix.org): allocate a large buffer
255
- let ( tx, mut rx) = tokio:: sync:: mpsc:: channel :: < SynapseUser > ( 50 * 1024 * 1024 ) ;
255
+ let ( tx, mut rx) = tokio:: sync:: mpsc:: channel :: < SynapseUser > ( 20 * 1024 * 1024 ) ;
256
+
257
+ let ( txi, mut rxi) = tokio:: sync:: mpsc:: channel :: < ( CompactString , UserInfo ) > ( 20 * 1024 * 1024 ) ;
258
+
259
+ let server_name = state. server_name . clone ( ) ;
260
+ // Accumulating the users state is potentially CPU-intensive, so we spawn a
261
+ // separate task to do it
262
+ let state_task = tokio:: spawn ( async move {
263
+ while let Some ( ( username, user_info) ) = rxi. recv ( ) . await {
264
+ state. users . insert ( username, user_info) ;
265
+ }
266
+ state
267
+ } ) ;
256
268
257
269
// create a new RNG seeded from the passed RNG so that we can move it into the
258
270
// spawned task
@@ -269,15 +281,14 @@ async fn migrate_users(
269
281
&& user
270
282
. name
271
283
. 0
272
- . strip_suffix ( & format ! ( ":{}" , state . server_name ) )
284
+ . strip_suffix ( & format ! ( ":{server_name}" ) )
273
285
. is_some_and ( |localpart| localpart. contains ( ':' ) )
274
286
{
275
287
tracing:: warn!( "AS user {} has invalid localpart, ignoring!" , user. name. 0 ) ;
276
288
continue ;
277
289
}
278
290
279
- let ( mas_user, mas_password_opt) =
280
- transform_user ( & user, & state. server_name , & mut rng) ?;
291
+ let ( mas_user, mas_password_opt) = transform_user ( & user, & server_name, & mut rng) ?;
281
292
282
293
let mut flags = UserFlags :: empty ( ) ;
283
294
if bool:: from ( user. admin ) {
@@ -297,23 +308,27 @@ async fn migrate_users(
297
308
298
309
// Special case for appservice users: we don't insert them into the database
299
310
// We just record the user's information in the state and continue
300
- state . users . insert (
311
+ txi . send ( (
301
312
CompactString :: new ( & mas_user. username ) ,
302
313
UserInfo {
303
314
mas_user_id : None ,
304
315
flags,
305
316
} ,
306
- ) ;
317
+ ) )
318
+ . await
319
+ . map_err ( |_| Error :: ChannelClosed ) ?;
307
320
continue ;
308
321
}
309
322
310
- state . users . insert (
323
+ txi . send ( (
311
324
CompactString :: new ( & mas_user. username ) ,
312
325
UserInfo {
313
326
mas_user_id : Some ( mas_user. user_id ) ,
314
327
flags,
315
328
} ,
316
- ) ;
329
+ ) )
330
+ . await
331
+ . map_err ( |_| Error :: ChannelClosed ) ?;
317
332
318
333
user_buffer
319
334
. write ( & mut mas, mas_user)
@@ -331,6 +346,9 @@ async fn migrate_users(
331
346
progress_counter. increment_migrated ( ) ;
332
347
}
333
348
349
+ // Explicitly drop the sender, so that the channel is closed
350
+ drop ( txi) ;
351
+
334
352
user_buffer
335
353
. finish ( & mut mas)
336
354
. await
@@ -340,7 +358,7 @@ async fn migrate_users(
340
358
. await
341
359
. into_mas ( "writing passwords" ) ?;
342
360
343
- Ok ( ( mas, state ) )
361
+ Ok ( mas)
344
362
}
345
363
. instrument ( tracing:: info_span!( "ingest_task" ) ) ,
346
364
) ;
@@ -354,7 +372,8 @@ async fn migrate_users(
354
372
. inspect_err ( |e| tracing:: error!( error = e as & dyn std:: error:: Error ) )
355
373
. await ;
356
374
357
- let ( mas, state) = task. await . into_join ( "user write task" ) ??;
375
+ let mas = task. await . into_join ( "user write task" ) ??;
376
+ let state = state_task. await . into_join ( "user state task" ) ?;
358
377
359
378
res?;
360
379
0 commit comments