1
- use std:: { collections:: HashMap , process:: ExitCode } ;
1
+ use std:: { collections:: HashMap , process:: ExitCode , sync :: atomic :: Ordering , time :: Duration } ;
2
2
3
3
use anyhow:: Context ;
4
4
use camino:: Utf8PathBuf ;
@@ -12,8 +12,10 @@ use mas_storage::SystemClock;
12
12
use mas_storage_pg:: MIGRATOR ;
13
13
use rand:: thread_rng;
14
14
use sqlx:: { Connection , Either , PgConnection , postgres:: PgConnectOptions , types:: Uuid } ;
15
- use syn2mas:: { LockedMasDatabase , MasWriter , SynapseReader , synapse_config} ;
16
- use tracing:: { Instrument , error, info_span, warn} ;
15
+ use syn2mas:: {
16
+ LockedMasDatabase , MasWriter , Progress , ProgressStage , SynapseReader , synapse_config,
17
+ } ;
18
+ use tracing:: { Instrument , error, info, info_span, warn} ;
17
19
18
20
use crate :: util:: { DatabaseConnectOptions , database_connection_from_config_with_options} ;
19
21
@@ -248,7 +250,11 @@ impl Options {
248
250
#[ allow( clippy:: disallowed_methods) ]
249
251
let mut rng = thread_rng ( ) ;
250
252
251
- // TODO progress reporting
253
+ let progress = Progress :: default ( ) ;
254
+
255
+ let occasional_progress_logger_task =
256
+ tokio:: spawn ( occasional_progress_logger ( progress. clone ( ) ) ) ;
257
+
252
258
let mas_matrix = MatrixConfig :: extract ( figment) ?;
253
259
eprintln ! ( "\n \n " ) ;
254
260
syn2mas:: migrate (
@@ -258,11 +264,45 @@ impl Options {
258
264
& clock,
259
265
& mut rng,
260
266
provider_id_mappings,
267
+ & progress,
261
268
)
262
269
. await ?;
263
270
271
+ occasional_progress_logger_task. abort ( ) ;
272
+
264
273
Ok ( ExitCode :: SUCCESS )
265
274
}
266
275
}
267
276
}
268
277
}
278
+
279
+ /// Logs progress every 30 seconds, as a lightweight alternative to a progress
280
+ /// bar. For most deployments, the migration will not take 30 seconds so this
281
+ /// will not be relevant. In other cases, this will give the operator an idea of
282
+ /// what's going on.
283
+ async fn occasional_progress_logger ( progress : Progress ) {
284
+ loop {
285
+ tokio:: time:: sleep ( Duration :: from_secs ( 30 ) ) . await ;
286
+ match & * * progress. get_current_stage ( ) {
287
+ ProgressStage :: SettingUp => {
288
+ info ! ( name: "progress" , "still setting up" ) ;
289
+ }
290
+ ProgressStage :: MigratingData {
291
+ entity,
292
+ migrated,
293
+ approx_count,
294
+ } => {
295
+ let migrated = migrated. load ( Ordering :: Relaxed ) ;
296
+ #[ allow( clippy:: cast_precision_loss) ]
297
+ let percent = ( f64:: from ( migrated) / * approx_count as f64 ) * 100.0 ;
298
+ info ! ( name: "progress" , "migrating {entity}: {migrated}/~{approx_count} (~{percent:.1}%)" ) ;
299
+ }
300
+ ProgressStage :: RebuildIndex { index_name } => {
301
+ info ! ( name: "progress" , "still waiting for rebuild of index {index_name}" ) ;
302
+ }
303
+ ProgressStage :: RebuildConstraint { constraint_name } => {
304
+ info ! ( name: "progress" , "still waiting for rebuild of constraint {constraint_name}" ) ;
305
+ }
306
+ }
307
+ }
308
+ }
0 commit comments