@@ -630,6 +630,7 @@ where
630630 ) ?)
631631 } ;
632632
633+ let mut maintenance_deferred = false ;
633634 if let Some ( wal) = db. wal_handle ( ) . cloned ( ) {
634635 let provisional_id = wal. next_provisional_id ( ) ;
635636 let prev_live_floor = db. wal_live_frame_floor ( ) ;
@@ -655,10 +656,6 @@ where
655656 publish_ctx. finalize_manifest ( wal_range) . await ?;
656657 }
657658 CommitAckMode :: Fast => {
658- // NOTE: Fast mode has a known limitation - if auto-seal triggers during
659- // apply_staged_payloads, the sealed segment's WAL range won't include this
660- // transaction's frames (they're recorded asynchronously). This is acceptable
661- // for Fast mode as it prioritizes latency over strict durability ordering.
662659 apply_staged_payloads (
663660 & * db,
664661 upsert_payload. take ( ) ,
@@ -667,7 +664,8 @@ where
667664 ) ?;
668665 let publish_ctx = db. txn_publish_context ( prev_live_floor) ;
669666 let executor = Arc :: clone ( db. executor ( ) ) ;
670- spawn_publish_task ( executor, publish_ctx, tickets) ;
667+ spawn_publish_task ( executor, Arc :: clone ( & db) , publish_ctx, tickets) ;
668+ maintenance_deferred = true ;
671669 }
672670 }
673671 } else {
@@ -690,14 +688,9 @@ where
690688 ) ?;
691689 }
692690
693- db. maybe_seal_after_insert ( )
694- . map_err ( TransactionCommitError :: Apply ) ?;
695- #[ cfg( test) ]
696- db. maybe_run_minor_compaction ( )
697- . await
698- . map_err ( TransactionCommitError :: MinorCompaction ) ?;
699- #[ cfg( not( test) ) ]
700- DbInner :: schedule_background_minor_compaction ( Arc :: clone ( & db) ) ;
691+ if !maintenance_deferred {
692+ run_post_commit_maintenance ( & db) . await ?;
693+ }
701694
702695 drop ( key_guards) ;
703696 Ok ( ( ) )
@@ -1368,6 +1361,7 @@ impl AckRange {
13681361
13691362fn spawn_publish_task < FS , E > (
13701363 executor : Arc < E > ,
1364+ db : Arc < DbInner < FS , E > > ,
13711365 publish_ctx : TxnWalPublishContext < FS , E > ,
13721366 tickets : WalTxnTickets < E > ,
13731367) where
@@ -1378,7 +1372,11 @@ fn spawn_publish_task<FS, E>(
13781372 executor. spawn ( async move {
13791373 match tickets. await_range ( ) . await {
13801374 Ok ( range) => {
1381- if let Err ( err) = publish_ctx. finalize ( range) . await {
1375+ publish_ctx. record_wal_range ( & range) ;
1376+ if let Err ( err) = run_post_commit_maintenance ( & db) . await {
1377+ eprintln ! ( "transaction post-commit maintenance failed: {err}" ) ;
1378+ }
1379+ if let Err ( err) = publish_ctx. finalize_manifest ( range) . await {
13821380 eprintln ! ( "transaction post-commit publish failed: {err}" ) ;
13831381 }
13841382 }
@@ -1460,15 +1458,25 @@ where
14601458
14611459 Ok ( ( ) )
14621460 }
1461+ }
14631462
1464- /// Combined record and finalize for async publish tasks.
1465- ///
1466- /// This is used by the Fast mode async task which handles both
1467- /// WAL range recording and manifest update together.
1468- async fn finalize ( & self , wal_range : WalFrameRange ) -> Result < ( ) , TransactionCommitError > {
1469- self . record_wal_range ( & wal_range) ;
1470- self . finalize_manifest ( wal_range) . await
1471- }
1463+ async fn run_post_commit_maintenance < FS , E > (
1464+ db : & Arc < DbInner < FS , E > > ,
1465+ ) -> Result < ( ) , TransactionCommitError >
1466+ where
1467+ FS : crate :: manifest:: ManifestFs < E > ,
1468+ E : Executor + Timer + Clone + ' static ,
1469+ <FS as fusio:: fs:: Fs >:: File : fusio:: durability:: FileCommit ,
1470+ {
1471+ db. maybe_seal_after_insert ( )
1472+ . map_err ( TransactionCommitError :: Apply ) ?;
1473+ #[ cfg( test) ]
1474+ db. maybe_run_minor_compaction ( )
1475+ . await
1476+ . map_err ( TransactionCommitError :: MinorCompaction ) ?;
1477+ #[ cfg( not( test) ) ]
1478+ DbInner :: schedule_background_minor_compaction ( Arc :: clone ( db) ) ;
1479+ Ok ( ( ) )
14721480}
14731481
14741482/// Errors raised while staging transactional mutations.
0 commit comments