@@ -362,12 +362,18 @@ async fn start() -> anyhow::Result<()> {
362362 . workers ( worker_amount)
363363 . run ( ) ;
364364
365+ // Without this lock the noon-UTC cron and the INITIAL_DATA_INIT spawn can
366+ // race on a boot near noon, doubling outbound quota burn and racing into
367+ // the signature_metadata_mapping unique indexes.
368+ let maintenance_lock: Arc < tokio:: sync:: Mutex < ( ) > > = Arc :: new ( tokio:: sync:: Mutex :: new ( ( ) ) ) ;
369+
365370 let conn = conn_arc. clone ( ) ;
366371 let dat_client = dat_http_client_arc. clone ( ) ;
367372 let providers_for_cron = providers_arc. clone ( ) ;
368373 let lb_for_cron = lb_client_opt. clone ( ) ;
369374 let ovgdb_for_cron = ovgdb_client_opt. clone ( ) ;
370375 let ra_for_cron = ra_client_opt. clone ( ) ;
376+ let maintenance_lock_cron = maintenance_lock. clone ( ) ;
371377 sched
372378 . add ( Job :: new_async ( "0 0 12 * * *" , move |_, _| {
373379 let conn = conn. clone ( ) ;
@@ -376,7 +382,9 @@ async fn start() -> anyhow::Result<()> {
376382 let lb = lb_for_cron. clone ( ) ;
377383 let ovgdb = ovgdb_for_cron. clone ( ) ;
378384 let ra = ra_for_cron. clone ( ) ;
385+ let lock = maintenance_lock_cron. clone ( ) ;
379386 Box :: pin ( async move {
387+ let _guard = lock. lock ( ) . await ;
380388 wrap_download_and_parse_dats ( dat_client, conn. clone ( ) , false ) . await ;
381389 wrap_launchbox_import ( lb) . await ;
382390 wrap_openvgdb_import ( ovgdb) . await ;
@@ -436,7 +444,9 @@ async fn start() -> anyhow::Result<()> {
436444 == "true" ;
437445
438446 if initial_data_init {
447+ let maintenance_lock_init = maintenance_lock. clone ( ) ;
439448 tokio:: spawn ( async move {
449+ let _guard = maintenance_lock_init. lock ( ) . await ;
440450 wrap_download_and_parse_dats ( http_client, conn. clone ( ) , force_initial_data_init) . await ;
441451 wrap_launchbox_import ( lb_for_init) . await ;
442452 wrap_openvgdb_import ( ovgdb_for_init) . await ;
0 commit comments