Skip to content

Commit 94adfdc

Browse files
Ludv1gLgefjon
andauthored
fix(scheduler): Restore ReducerContext recording for scheduled reducers (#3947)
## Summary This fixes a regression introduced in commit afe169a ("Fix the issues with scheduling procedures #3816", Dec 5, 2025) where scheduled reducers stopped recording their `ReducerContext` to the commitlog. **Impact:** - No `inputs` section was written to the commitlog for scheduled reducers - The reducer's name, caller, timestamp, and arguments were not persisted ## Root Cause The old code in `module_host.rs::call_scheduled_reducer_inner` patched `tx.ctx` with the `ReducerContext`: ```rust tx.ctx = ExecutionContext::with_workload( tx.ctx.database_identity(), Workload::Reducer(ReducerContext { ... }), ); ``` This was removed when the logic moved to `scheduler.rs`. The new code in `call_reducer_with_tx` only applies the `ReducerContext` when `tx` is `None` — since the scheduler passes `Some(tx)`, the context was never applied. ## Fix Restore the `tx.ctx` patching in `scheduler.rs` before calling `call_reducer_with_tx`. ## Test Plan - [ ] Existing tests pass Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
1 parent 3c8836b commit 94adfdc

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

crates/core/src/host/scheduler.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use core::time::Duration;
1111
use futures::{FutureExt, StreamExt};
1212
use rustc_hash::FxHashMap;
1313
use spacetimedb_client_api_messages::energy::EnergyQuanta;
14-
use spacetimedb_datastore::execution_context::Workload;
14+
use spacetimedb_datastore::execution_context::{ExecutionContext, ReducerContext, Workload};
1515
use spacetimedb_datastore::locking_tx_datastore::MutTxId;
1616
use spacetimedb_datastore::system_tables::{StFields, StScheduledFields, ST_SCHEDULED_ID};
1717
use spacetimedb_datastore::traits::IsolationLevel;
@@ -394,7 +394,7 @@ pub(super) async fn call_scheduled_function(
394394
})
395395
};
396396

397-
let tx = db.begin_mut_tx(IsolationLevel::Serializable, Workload::Internal);
397+
let mut tx = db.begin_mut_tx(IsolationLevel::Serializable, Workload::Internal);
398398

399399
// Determine the call params.
400400
// This also lets us know whether to call a reducer or procedure.
@@ -418,6 +418,24 @@ pub(super) async fn call_scheduled_function(
418418
// so we must remove the schedule row before executing.
419419
match params {
420420
CallParams::Reducer(params) => {
421+
// Patch the transaction context with ReducerContext so the commitlog
422+
// records the reducer's name, caller, timestamp, and arguments.
423+
//
424+
// Background: Scheduled reducers start with Workload::Internal, but
425+
// call_reducer_with_tx only sets ReducerContext when tx is None.
426+
// Since we pass Some(tx), we must set it here.
427+
let reducer_name = &*module_info.module_def.reducer_by_id(params.reducer_id).name;
428+
tx.ctx = ExecutionContext::with_workload(
429+
tx.ctx.database_identity(),
430+
Workload::Reducer(ReducerContext {
431+
name: reducer_name.into(),
432+
caller_identity: params.caller_identity,
433+
caller_connection_id: params.caller_connection_id,
434+
timestamp: params.timestamp,
435+
arg_bsatn: params.args.get_bsatn().clone(),
436+
}),
437+
);
438+
421439
// We don't want a panic in the module host to affect the scheduler, as unlikely
422440
// as it might be, so catch it so we can handle it "gracefully". Panics will
423441
// print their message and backtrace when they occur, so we don't need to do

0 commit comments

Comments
 (0)