Skip to content

Commit ae9bd74

Browse files
authored
Disable scheduling procedures (#3768)
# Description of Changes We've been unable to get scheduled procedures into the initial release of procedures due to a nondeterministic hang in some of our tests which we don't have time to debug. As such, this commit disables scheduled procedures by: - Changing the `RawModuleDevV9` validator to reject scheduled procedures. - Changing the Rust bindings library's typechecking magic so that scheduled table annotations referencing procedures will cause a type error. - Removes some docs from the Rust bindings library which reference scheduled procedures. # API and ABI breaking changes N/a # Expected complexity level and risk 1 # Testing Automated tests should be sufficient. Prior to merging #3774 , CI for this branch merged with master failed in the intended way: modules which attempted to define scheduled procedures failed to typecheck.
1 parent 0590f70 commit ae9bd74

File tree

4 files changed

+58
-25
lines changed

4 files changed

+58
-25
lines changed

crates/bindings/src/lib.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -728,16 +728,17 @@ pub use spacetimedb_bindings_macro::reducer;
728728
// TODO(procedure-http): add example with an HTTP request.
729729
// TODO(procedure-transaction): document obtaining and using a transaction within a procedure.
730730
///
731-
/// # Scheduled procedures
731+
// TODO(scheduled-procedures): Uncomment below docs.
732+
// /// # Scheduled procedures
732733
// TODO(docs): after moving scheduled reducer docs into table secion, link there.
733-
///
734-
/// Like [reducer]s, procedures can be made **scheduled**.
735-
/// This allows calling procedures at a particular time, or in a loop.
736-
/// It also allows reducers to enqueue procedure runs.
737-
///
738-
/// Scheduled procedures are called on a best-effort basis and may be slightly delayed in their execution
739-
/// when a database is under heavy load.
740-
///
734+
// ///
735+
// /// Like [reducer]s, procedures can be made **scheduled**.
736+
// /// This allows calling procedures at a particular time, or in a loop.
737+
// /// It also allows reducers to enqueue procedure runs.
738+
// ///
739+
// /// Scheduled procedures are called on a best-effort basis and may be slightly delayed in their execution
740+
// /// when a database is under heavy load.
741+
// ///
741742
/// [clients]: https://spacetimedb.com/docs/#client
742743
// TODO(procedure-async): update docs and examples with `async`-ness.
743744
#[doc(inline)]

crates/bindings/src/rt.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,9 @@ pub struct FnKindView {
424424
/// See <https://willcrichton.net/notes/defeating-coherence-rust/> for details on this technique.
425425
#[cfg_attr(
426426
feature = "unstable",
427-
doc = "It will be one of [`FnKindReducer`] or [`FnKindProcedure`] in modules that compile successfully."
427+
// TODO(scheduled-procedures): uncomment this, delete other line
428+
// doc = "It will be one of [`FnKindReducer`] or [`FnKindProcedure`] in modules that compile successfully."
429+
doc = "It will be [`FnKindReducer`] in modules that compile successfully."
428430
)]
429431
#[cfg_attr(
430432
not(feature = "unstable"),
@@ -437,23 +439,24 @@ pub struct FnKindView {
437439
note = "views cannot be scheduled",
438440
note = "the scheduled function must take `{TableRow}` as its sole argument",
439441
note = "e.g: `fn scheduled_reducer(ctx: &ReducerContext, arg: {TableRow})`",
440-
note = "or `fn scheduled_procedure(ctx: &mut ProcedureContext, arg: {TableRow})`"
442+
// note = "or `fn scheduled_procedure(ctx: &mut ProcedureContext, arg: {TableRow})`"
441443
)]
442444
pub trait ExportFunctionForScheduledTable<'de, TableRow, FnKind> {}
443445
impl<'de, TableRow: SpacetimeType + Serialize + Deserialize<'de>, F: Reducer<'de, (TableRow,)>>
444446
ExportFunctionForScheduledTable<'de, TableRow, FnKindReducer> for F
445447
{
446448
}
447449

448-
#[cfg(feature = "unstable")]
449-
impl<
450-
'de,
451-
TableRow: SpacetimeType + Serialize + Deserialize<'de>,
452-
Ret: SpacetimeType + Serialize + Deserialize<'de>,
453-
F: Procedure<'de, (TableRow,), Ret>,
454-
> ExportFunctionForScheduledTable<'de, TableRow, FnKindProcedure<Ret>> for F
455-
{
456-
}
450+
// TODO(scheduled-procedures): uncomment this to syntactically allow scheduled procedures.
451+
// #[cfg(feature = "unstable")]
452+
// impl<
453+
// 'de,
454+
// TableRow: SpacetimeType + Serialize + Deserialize<'de>,
455+
// Ret: SpacetimeType + Serialize + Deserialize<'de>,
456+
// F: Procedure<'de, (TableRow,), Ret>,
457+
// > ExportFunctionForScheduledTable<'de, TableRow, FnKindProcedure<Ret>> for F
458+
// {
459+
// }
457460

458461
// the macro generates <T as SpacetimeType>::make_type::<DummyTypespace>
459462
pub struct DummyTypespace;

crates/bindings/tests/ui/views.stderr

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,29 @@ error[E0277]: the trait bound `NotSpacetimeType: SpacetimeType` is not satisfied
408408
ColId
409409
and $N others
410410
= note: required for `Option<NotSpacetimeType>` to implement `SpacetimeType`
411+
412+
error[E0631]: type mismatch in function arguments
413+
--> tests/ui/views.rs:142:56
414+
|
415+
142 | #[spacetimedb::table(name = scheduled_table, scheduled(scheduled_table_view))]
416+
| -------------------------------------------------------^^^^^^^^^^^^^^^^^^^^---
417+
| | |
418+
| | expected due to this
419+
| required by a bound introduced by this call
420+
...
421+
154 | fn scheduled_table_view(_: &ViewContext, _args: ScheduledTable) -> Vec<Player> {
422+
| ------------------------------------------------------------------------------ found signature defined here
423+
|
424+
= note: expected function signature `for<'a> fn(&'a ReducerContext, ScheduledTable) -> _`
425+
found function signature `fn(&ViewContext, ScheduledTable) -> _`
426+
= note: required for `for<'a> fn(&'a ViewContext, ScheduledTable) -> Vec<Player> {scheduled_table_view}` to implement `Reducer<'_, (ScheduledTable,)>`
427+
= note: required for `for<'a> fn(&'a ViewContext, ScheduledTable) -> Vec<Player> {scheduled_table_view}` to implement `ExportFunctionForScheduledTable<'_, ScheduledTable, {type error}>`
428+
note: required by a bound in `scheduled_typecheck`
429+
--> src/rt.rs
430+
|
431+
| pub const fn scheduled_typecheck<'de, Row, FnKind>(_x: impl ExportFunctionForScheduledTable<'de, Row, FnKind>)
432+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `scheduled_typecheck`
433+
help: consider wrapping the function in a closure
434+
|
435+
142 | #[spacetimedb::table(name = scheduled_table, scheduled(|arg0: &ReducerContext, arg1: ScheduledTable| scheduled_table_view(/* &ViewContext */, arg1)))]
436+
| +++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++

crates/schema/src/def/validate/v9.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ fn identifier(name: Box<str>) -> Result<Identifier> {
11971197
fn check_scheduled_functions_exist(
11981198
tables: &mut IdentifierMap<TableDef>,
11991199
reducers: &IndexMap<Identifier, ReducerDef>,
1200-
procedures: &IndexMap<Identifier, ProcedureDef>,
1200+
_procedures: &IndexMap<Identifier, ProcedureDef>,
12011201
) -> Result<()> {
12021202
let validate_params =
12031203
|params_from_function: &ProductType, table_row_type_ref: AlgebraicTypeRef, function_name: &str| {
@@ -1222,10 +1222,13 @@ fn check_scheduled_functions_exist(
12221222
if let Some(reducer) = reducers.get(&schedule.function_name) {
12231223
schedule.function_kind = FunctionKind::Reducer;
12241224
validate_params(&reducer.params, table.product_type_ref, &reducer.name).map_err(Into::into)
1225-
} else if let Some(procedure) = procedures.get(&schedule.function_name) {
1226-
schedule.function_kind = FunctionKind::Procedure;
1227-
validate_params(&procedure.params, table.product_type_ref, &procedure.name).map_err(Into::into)
1228-
} else {
1225+
} else
1226+
// TODO(scheduled-procedures): Uncomment this
1227+
// if let Some(procedure) = procedures.get(&schedule.function_name) {
1228+
// schedule.function_kind = FunctionKind::Procedure;
1229+
// validate_params(&procedure.params, table.product_type_ref, &procedure.name).map_err(Into::into)
1230+
// } else
1231+
{
12291232
Err(ValidationError::MissingScheduledFunction {
12301233
schedule: schedule.name.clone(),
12311234
function: schedule.function_name.clone(),

0 commit comments

Comments
 (0)