Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion crates/core/src/host/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,12 +633,16 @@ fn delete_scheduled_function_row(
inst_common: &mut InstanceCommon,
inst: &mut impl WasmInstance,
) -> Option<Reschedule> {
let (timestamp, instant) = reschedule_from;
let tx = tx.unwrap_or_else(|| db.begin_mut_tx(IsolationLevel::Serializable, Workload::Internal));
let schedule_at = delete_scheduled_function_row_with_tx(module_info, db, tx, id, inst_common, inst)?;
interval_reschedule(schedule_at, reschedule_from)
}

fn interval_reschedule(schedule_at: ScheduleAt, reschedule_from: (Timestamp, Instant)) -> Option<Reschedule> {
let ScheduleAt::Interval(dur) = schedule_at else {
return None;
};
let (timestamp, instant) = reschedule_from;
Some(Reschedule {
at_ts: schedule_at.to_timestamp_from(timestamp),
at_real: instant + dur.to_duration_abs(),
Expand Down Expand Up @@ -844,3 +848,27 @@ fn read_schedule_at(row: &RowRef<'_>, at_column: ColId) -> anyhow::Result<Schedu
let schedule_at_av: AlgebraicValue = row.read_col(at_column)?;
ScheduleAt::try_from(schedule_at_av).map_err(|e| anyhow!("Failed to convert 'scheduled_at' to ScheduleAt: {e:?}"))
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn interval_reschedule_advances_from_previous_schedule() {
let interval = Duration::from_secs(5);
let previous_timestamp = Timestamp::from_micros_since_unix_epoch(1_000_000);
let previous_instant = Instant::now();

let reschedule = interval_reschedule(interval.into(), (previous_timestamp, previous_instant)).unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interval_reschedule method is too trivial to test. I don't think these tests are really testing anything good.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — the helper-only assertion did not cover the execution boundary. I replaced it in 6d01046 with a seam used by the actual scheduled-reducer path: the test simulates completion 30 seconds after the captured call time and verifies that both reschedule timestamps still advance from the call time. As a mutation check, temporarily restoring completion-time rescheduling makes the focused test fail; after restoring call-time rescheduling, the focused test, all 151 core library tests, formatting, and clippy pass.


assert_eq!(reschedule.at_ts, previous_timestamp + interval);
assert_eq!(reschedule.at_real, previous_instant + interval);
}

#[test]
fn one_shot_schedule_does_not_reschedule() {
let schedule_at = ScheduleAt::Time(Timestamp::from_micros_since_unix_epoch(1_000_000));

assert!(interval_reschedule(schedule_at, (Timestamp::UNIX_EPOCH, Instant::now())).is_none());
}
}