Skip to content

Commit 3fa9650

Browse files
committed
enable scheduled procedures and adjust test
1 parent 07eb897 commit 3fa9650

File tree

12 files changed

+252
-234
lines changed

12 files changed

+252
-234
lines changed

crates/codegen/src/rust.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ impl {func_name} for super::RemoteReducers {{
423423
{callback_id}(self.imp.on_reducer(
424424
{reducer_name:?},
425425
Box::new(move |ctx: &super::ReducerEventContext| {{
426+
#[allow(irrefutable_let_patterns)]
426427
let super::ReducerEventContext {{
427428
event: __sdk::ReducerEvent {{
428429
reducer: super::Reducer::{enum_variant_name} {{

crates/codegen/tests/snapshots/codegen__codegen_rust.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ impl add_player for super::RemoteReducers {
7272
AddPlayerCallbackId(self.imp.on_reducer(
7373
"add_player",
7474
Box::new(move |ctx: &super::ReducerEventContext| {
75+
#[allow(irrefutable_let_patterns)]
7576
let super::ReducerEventContext {
7677
event: __sdk::ReducerEvent {
7778
reducer: super::Reducer::AddPlayer {
@@ -181,6 +182,7 @@ impl add_private for super::RemoteReducers {
181182
AddPrivateCallbackId(self.imp.on_reducer(
182183
"add_private",
183184
Box::new(move |ctx: &super::ReducerEventContext| {
185+
#[allow(irrefutable_let_patterns)]
184186
let super::ReducerEventContext {
185187
event: __sdk::ReducerEvent {
186188
reducer: super::Reducer::AddPrivate {
@@ -294,6 +296,7 @@ age: u8,
294296
AddCallbackId(self.imp.on_reducer(
295297
"add",
296298
Box::new(move |ctx: &super::ReducerEventContext| {
299+
#[allow(irrefutable_let_patterns)]
297300
let super::ReducerEventContext {
298301
event: __sdk::ReducerEvent {
299302
reducer: super::Reducer::Add {
@@ -398,6 +401,7 @@ impl assert_caller_identity_is_module_identity for super::RemoteReducers {
398401
AssertCallerIdentityIsModuleIdentityCallbackId(self.imp.on_reducer(
399402
"assert_caller_identity_is_module_identity",
400403
Box::new(move |ctx: &super::ReducerEventContext| {
404+
#[allow(irrefutable_let_patterns)]
401405
let super::ReducerEventContext {
402406
event: __sdk::ReducerEvent {
403407
reducer: super::Reducer::AssertCallerIdentityIsModuleIdentity {
@@ -527,6 +531,7 @@ impl client_connected for super::RemoteReducers {
527531
ClientConnectedCallbackId(self.imp.on_reducer(
528532
"client_connected",
529533
Box::new(move |ctx: &super::ReducerEventContext| {
534+
#[allow(irrefutable_let_patterns)]
530535
let super::ReducerEventContext {
531536
event: __sdk::ReducerEvent {
532537
reducer: super::Reducer::ClientConnected {
@@ -636,6 +641,7 @@ impl delete_player for super::RemoteReducers {
636641
DeletePlayerCallbackId(self.imp.on_reducer(
637642
"delete_player",
638643
Box::new(move |ctx: &super::ReducerEventContext| {
644+
#[allow(irrefutable_let_patterns)]
639645
let super::ReducerEventContext {
640646
event: __sdk::ReducerEvent {
641647
reducer: super::Reducer::DeletePlayer {
@@ -745,6 +751,7 @@ impl delete_players_by_name for super::RemoteReducers {
745751
DeletePlayersByNameCallbackId(self.imp.on_reducer(
746752
"delete_players_by_name",
747753
Box::new(move |ctx: &super::ReducerEventContext| {
754+
#[allow(irrefutable_let_patterns)]
748755
let super::ReducerEventContext {
749756
event: __sdk::ReducerEvent {
750757
reducer: super::Reducer::DeletePlayersByName {
@@ -1066,6 +1073,7 @@ impl list_over_age for super::RemoteReducers {
10661073
ListOverAgeCallbackId(self.imp.on_reducer(
10671074
"list_over_age",
10681075
Box::new(move |ctx: &super::ReducerEventContext| {
1076+
#[allow(irrefutable_let_patterns)]
10691077
let super::ReducerEventContext {
10701078
event: __sdk::ReducerEvent {
10711079
reducer: super::Reducer::ListOverAge {
@@ -1170,6 +1178,7 @@ impl log_module_identity for super::RemoteReducers {
11701178
LogModuleIdentityCallbackId(self.imp.on_reducer(
11711179
"log_module_identity",
11721180
Box::new(move |ctx: &super::ReducerEventContext| {
1181+
#[allow(irrefutable_let_patterns)]
11731182
let super::ReducerEventContext {
11741183
event: __sdk::ReducerEvent {
11751184
reducer: super::Reducer::LogModuleIdentity {
@@ -3567,6 +3576,7 @@ impl query_private for super::RemoteReducers {
35673576
QueryPrivateCallbackId(self.imp.on_reducer(
35683577
"query_private",
35693578
Box::new(move |ctx: &super::ReducerEventContext| {
3579+
#[allow(irrefutable_let_patterns)]
35703580
let super::ReducerEventContext {
35713581
event: __sdk::ReducerEvent {
35723582
reducer: super::Reducer::QueryPrivate {
@@ -3852,6 +3862,7 @@ impl repeating_test for super::RemoteReducers {
38523862
RepeatingTestCallbackId(self.imp.on_reducer(
38533863
"repeating_test",
38543864
Box::new(move |ctx: &super::ReducerEventContext| {
3865+
#[allow(irrefutable_let_patterns)]
38553866
let super::ReducerEventContext {
38563867
event: __sdk::ReducerEvent {
38573868
reducer: super::Reducer::RepeatingTest {
@@ -4015,6 +4026,7 @@ impl say_hello for super::RemoteReducers {
40154026
SayHelloCallbackId(self.imp.on_reducer(
40164027
"say_hello",
40174028
Box::new(move |ctx: &super::ReducerEventContext| {
4029+
#[allow(irrefutable_let_patterns)]
40184030
let super::ReducerEventContext {
40194031
event: __sdk::ReducerEvent {
40204032
reducer: super::Reducer::SayHello {
@@ -4325,6 +4337,7 @@ impl test_btree_index_args for super::RemoteReducers {
43254337
TestBtreeIndexArgsCallbackId(self.imp.on_reducer(
43264338
"test_btree_index_args",
43274339
Box::new(move |ctx: &super::ReducerEventContext| {
4340+
#[allow(irrefutable_let_patterns)]
43284341
let super::ReducerEventContext {
43294342
event: __sdk::ReducerEvent {
43304343
reducer: super::Reducer::TestBtreeIndexArgs {
@@ -4878,6 +4891,7 @@ arg_4: NamespaceTestF,
48784891
TestCallbackId(self.imp.on_reducer(
48794892
"test",
48804893
Box::new(move |ctx: &super::ReducerEventContext| {
4894+
#[allow(irrefutable_let_patterns)]
48814895
let super::ReducerEventContext {
48824896
event: __sdk::ReducerEvent {
48834897
reducer: super::Reducer::Test {

crates/core/src/host/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use spacetimedb_lib::bsatn;
88
use spacetimedb_lib::de::{serde::SeedWrapper, DeserializeSeed};
99
use spacetimedb_lib::ProductValue;
1010
use spacetimedb_schema::def::deserialize::{ArgsSeed, FunctionDef};
11+
use spacetimedb_schema::def::ModuleDef;
1112

1213
mod disk_storage;
1314
mod host_controller;
@@ -41,6 +42,14 @@ pub enum FunctionArgs {
4142
}
4243

4344
impl FunctionArgs {
45+
fn into_tuple_for_def<Def: FunctionDef>(
46+
self,
47+
module: &ModuleDef,
48+
def: &Def,
49+
) -> Result<ArgsTuple, InvalidFunctionArguments> {
50+
self.into_tuple(module.arg_seed_for(def))
51+
}
52+
4453
fn into_tuple<Def: FunctionDef>(self, seed: ArgsSeed<'_, Def>) -> Result<ArgsTuple, InvalidFunctionArguments> {
4554
self._into_tuple(seed).map_err(|err| InvalidFunctionArguments {
4655
err,

crates/core/src/host/module_host.rs

Lines changed: 60 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::error::DBError;
1111
use crate::estimation::estimate_rows_scanned;
1212
use crate::hash::Hash;
1313
use crate::host::host_controller::CallProcedureReturn;
14-
use crate::host::scheduler::{handle_queued_call_reducer_params, QueueItem};
1514
use crate::host::v8::JsInstance;
1615
use crate::host::wasmtime::ModuleInstance;
1716
use crate::host::{InvalidFunctionArguments, InvalidViewArguments};
@@ -41,7 +40,7 @@ use spacetimedb_client_api_messages::websocket::{ByteListLen, Compression, OneOf
4140
use spacetimedb_data_structures::error_stream::ErrorStream;
4241
use spacetimedb_data_structures::map::{HashCollectionExt as _, IntMap};
4342
use spacetimedb_datastore::error::DatastoreError;
44-
use spacetimedb_datastore::execution_context::{ExecutionContext, ReducerContext, Workload, WorkloadType};
43+
use spacetimedb_datastore::execution_context::{Workload, WorkloadType};
4544
use spacetimedb_datastore::locking_tx_datastore::{MutTxId, ViewCallInfo};
4645
use spacetimedb_datastore::traits::{IsolationLevel, Program, TxData};
4746
use spacetimedb_durability::DurableOffset;
@@ -56,7 +55,6 @@ use spacetimedb_primitives::{ArgId, ProcedureId, TableId, ViewFnPtr, ViewId};
5655
use spacetimedb_query::compile_subscription;
5756
use spacetimedb_sats::{AlgebraicTypeRef, ProductValue};
5857
use spacetimedb_schema::auto_migrate::{AutoMigrateError, MigrationPolicy};
59-
use spacetimedb_schema::def::deserialize::ArgsSeed;
6058
use spacetimedb_schema::def::{ModuleDef, ProcedureDef, ReducerDef, TableDef, ViewDef};
6159
use spacetimedb_schema::schema::{Schema, TableSchema};
6260
use spacetimedb_vm::relation::RelValue;
@@ -615,59 +613,6 @@ pub fn call_identity_connected(
615613
}
616614
}
617615

618-
// Only for logging purposes.
619-
const SCHEDULED_REDUCER: &str = "scheduled_reducer";
620-
621-
pub(crate) fn call_scheduled_reducer(
622-
module: &ModuleInfo,
623-
queue_item: QueueItem,
624-
call_reducer: impl FnOnce(Option<MutTxId>, CallReducerParams) -> (ReducerCallResult, bool),
625-
) -> (Result<(ReducerCallResult, Timestamp), ReducerCallError>, bool) {
626-
extract_trapped(call_scheduled_reducer_inner(module, queue_item, call_reducer))
627-
}
628-
629-
fn call_scheduled_reducer_inner(
630-
module: &ModuleInfo,
631-
item: QueueItem,
632-
call_reducer: impl FnOnce(Option<MutTxId>, CallReducerParams) -> (ReducerCallResult, bool),
633-
) -> Result<((ReducerCallResult, Timestamp), bool), ReducerCallError> {
634-
let db = &module.relational_db();
635-
let mut tx = db.begin_mut_tx(IsolationLevel::Serializable, Workload::Internal);
636-
637-
match handle_queued_call_reducer_params(&tx, module, db, item) {
638-
Ok(Some(params)) => {
639-
// Is necessary to patch the context with the actual calling reducer
640-
let reducer_def = module
641-
.module_def
642-
.get_reducer_by_id(params.reducer_id)
643-
.ok_or(ReducerCallError::ScheduleReducerNotFound)?;
644-
let reducer = &*reducer_def.name;
645-
646-
tx.ctx = ExecutionContext::with_workload(
647-
tx.ctx.database_identity(),
648-
Workload::Reducer(ReducerContext {
649-
name: reducer.into(),
650-
caller_identity: params.caller_identity,
651-
caller_connection_id: params.caller_connection_id,
652-
timestamp: Timestamp::now(),
653-
arg_bsatn: params.args.get_bsatn().clone(),
654-
}),
655-
);
656-
657-
let timestamp = params.timestamp;
658-
let (res, trapped) = call_reducer(Some(tx), params);
659-
Ok(((res, timestamp), trapped))
660-
}
661-
Ok(None) => Err(ReducerCallError::ScheduleReducerNotFound),
662-
Err(err) => Err(ReducerCallError::Args(InvalidReducerArguments(
663-
InvalidFunctionArguments {
664-
err,
665-
function_name: SCHEDULED_REDUCER.into(),
666-
},
667-
))),
668-
}
669-
}
670-
671616
pub struct CallReducerParams {
672617
pub timestamp: Timestamp,
673618
pub caller_identity: Identity,
@@ -678,6 +623,7 @@ pub struct CallReducerParams {
678623
pub reducer_id: ReducerId,
679624
pub args: ArgsTuple,
680625
}
626+
681627
impl CallReducerParams {
682628
/// Returns a set of parameters for a call that came from within
683629
/// and without a client/caller/request_id.
@@ -725,6 +671,26 @@ pub struct CallProcedureParams {
725671
pub args: ArgsTuple,
726672
}
727673

674+
impl CallProcedureParams {
675+
/// Returns a set of parameters for a call that came from within
676+
/// and without a client/caller/request_id.
677+
pub fn from_system(
678+
timestamp: Timestamp,
679+
caller_identity: Identity,
680+
procedure_id: ProcedureId,
681+
args: ArgsTuple,
682+
) -> Self {
683+
Self {
684+
timestamp,
685+
caller_identity,
686+
caller_connection_id: ConnectionId::ZERO,
687+
timer: None,
688+
procedure_id,
689+
args,
690+
}
691+
}
692+
}
693+
728694
/// Holds a [`Module`] and a set of [`Instance`]s from it,
729695
/// and allocates the [`Instance`]s to be used for function calls.
730696
///
@@ -1449,8 +1415,9 @@ impl ModuleHost {
14491415
reducer_def: &ReducerDef,
14501416
args: FunctionArgs,
14511417
) -> Result<CallReducerParams, InvalidReducerArguments> {
1452-
let reducer_seed = ArgsSeed(module.module_def.typespace().with_type(reducer_def));
1453-
let args = args.into_tuple(reducer_seed).map_err(InvalidReducerArguments)?;
1418+
let args = args
1419+
.into_tuple_for_def(&module.module_def, reducer_def)
1420+
.map_err(InvalidReducerArguments)?;
14541421
let caller_connection_id = caller_connection_id.unwrap_or(ConnectionId::ZERO);
14551422
Ok(CallReducerParams {
14561423
timestamp: Timestamp::now(),
@@ -1464,6 +1431,20 @@ impl ModuleHost {
14641431
})
14651432
}
14661433

1434+
pub async fn call_reducer_with_params(
1435+
&self,
1436+
reducer_name: &str,
1437+
params: CallReducerParams,
1438+
) -> Result<ReducerCallResult, NoSuchModule> {
1439+
self.call(
1440+
reducer_name,
1441+
params,
1442+
|p, inst| inst.call_reducer(None, p),
1443+
|p, inst| inst.call_reducer(None, p),
1444+
)
1445+
.await
1446+
}
1447+
14671448
async fn call_reducer_inner(
14681449
&self,
14691450
caller_identity: Identity,
@@ -1475,8 +1456,9 @@ impl ModuleHost {
14751456
reducer_def: &ReducerDef,
14761457
args: FunctionArgs,
14771458
) -> Result<ReducerCallResult, ReducerCallError> {
1478-
let reducer_seed = ArgsSeed(self.info.module_def.typespace().with_type(reducer_def));
1479-
let args = args.into_tuple(reducer_seed).map_err(InvalidReducerArguments)?;
1459+
let args = args
1460+
.into_tuple_for_def(&self.info.module_def, reducer_def)
1461+
.map_err(InvalidReducerArguments)?;
14801462
let caller_connection_id = caller_connection_id.unwrap_or(ConnectionId::ZERO);
14811463
let call_reducer_params = CallReducerParams {
14821464
timestamp: Timestamp::now(),
@@ -1490,12 +1472,7 @@ impl ModuleHost {
14901472
};
14911473

14921474
Ok(self
1493-
.call(
1494-
&reducer_def.name,
1495-
call_reducer_params,
1496-
|p, inst| inst.call_reducer(None, p),
1497-
|p, inst| inst.call_reducer(None, p),
1498-
)
1475+
.call_reducer_with_params(&reducer_def.name, call_reducer_params)
14991476
.await?)
15001477
}
15011478

@@ -1600,9 +1577,10 @@ impl ModuleHost {
16001577
procedure_def: &ProcedureDef,
16011578
args: FunctionArgs,
16021579
) -> Result<CallProcedureReturn, ProcedureCallError> {
1603-
let procedure_seed = ArgsSeed(self.info.module_def.typespace().with_type(procedure_def));
1580+
let args = args
1581+
.into_tuple_for_def(&self.info.module_def, procedure_def)
1582+
.map_err(InvalidProcedureArguments)?;
16041583
let caller_connection_id = caller_connection_id.unwrap_or(ConnectionId::ZERO);
1605-
let args = args.into_tuple(procedure_seed).map_err(InvalidProcedureArguments)?;
16061584

16071585
self.call_async_with_instance(&procedure_def.name, async move |mut inst| {
16081586
let res = inst
@@ -1621,20 +1599,18 @@ impl ModuleHost {
16211599
.map_err(Into::into)
16221600
}
16231601

1624-
// Scheduled reducers require a different function here to call their reducer
1625-
// because their reducer arguments are stored in the database and need to be fetched
1626-
// within the same transaction as the reducer call.
1627-
pub(crate) async fn call_scheduled_reducer(
1602+
// This is not reused in `call_procedure_inner`
1603+
// due to concerns re. `Timestamp::now`.
1604+
pub async fn call_procedure_with_params(
16281605
&self,
1629-
item: QueueItem,
1630-
) -> Result<(ReducerCallResult, Timestamp), ReducerCallError> {
1631-
self.call(
1632-
SCHEDULED_REDUCER,
1633-
item,
1634-
|item, inst| inst.call_scheduled_reducer(item),
1635-
|item, inst| inst.call_scheduled_reducer(item),
1636-
)
1637-
.await?
1606+
name: &str,
1607+
params: CallProcedureParams,
1608+
) -> Result<CallProcedureReturn, NoSuchModule> {
1609+
self.call_async_with_instance(name, async move |mut inst| {
1610+
let res = inst.call_procedure(params).await;
1611+
(res, inst)
1612+
})
1613+
.await
16381614
}
16391615

16401616
/// Materializes the views return by the `view_collector`, if not already materialized,
@@ -1721,9 +1697,9 @@ impl ModuleHost {
17211697
let view_def = module_def.view(view_name).ok_or(ViewCallError::NoSuchView)?;
17221698
let fn_ptr = view_def.fn_ptr;
17231699
let row_type = view_def.product_type_ref;
1724-
let typespace = module_def.typespace().with_type(view_def);
1725-
let view_seed = ArgsSeed(typespace);
1726-
let args = args.into_tuple(view_seed).map_err(InvalidViewArguments)?;
1700+
let args = args
1701+
.into_tuple_for_def(module_def, view_def)
1702+
.map_err(InvalidViewArguments)?;
17271703

17281704
match self
17291705
.call_view_inner(tx, view_name, view_id, table_id, fn_ptr, caller, sender, args, row_type)

0 commit comments

Comments
 (0)