Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 15 additions & 14 deletions crates/core/src/host/host_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ pub struct ModuleHostWithBootstrap {
/// The handle owns any wait state needed to prove that the database has a
/// durable `st_module` row.
pub struct BootstrapCompletion {
program_hash: Hash,
bootstrap_generation: u64,
status: ProgramBootstrap,
}

/// Has the module been bootstrapped from the controldb?
///
/// Once we have inserted into `st_module`, bootstrapping is no longer necessary,
/// and the initial program bytes can be dropped fromt the controldb.
/// and the initial program bytes can be dropped from the controldb.
enum ProgramBootstrap {
/// The module's program bytes have already been written to `st_module`
Durable,
Expand All @@ -119,32 +119,32 @@ enum ProgramBootstrap {
}

impl BootstrapCompletion {
fn durable(program_hash: Hash) -> Self {
fn durable(bootstrap_generation: u64) -> Self {
Self {
program_hash,
bootstrap_generation,
status: ProgramBootstrap::Durable,
}
}

fn pending(program_hash: Hash, tx_offset: TransactionOffset, durable_offset: Option<DurableOffset>) -> Self {
fn pending(bootstrap_generation: u64, tx_offset: TransactionOffset, durable_offset: Option<DurableOffset>) -> Self {
Self {
program_hash,
bootstrap_generation,
status: ProgramBootstrap::Pending {
tx_offset,
durable_offset,
},
}
}

pub fn program_hash(&self) -> Hash {
self.program_hash
pub fn bootstrap_generation(&self) -> u64 {
self.bootstrap_generation
}

/// Wait until it is safe to complete program bootstrap in controldb.
/// That is, wait until the initial `st_module` insert becomes durable.
pub async fn wait(self) -> anyhow::Result<Hash> {
pub async fn wait(self) -> anyhow::Result<()> {
match self.status {
ProgramBootstrap::Durable => Ok(self.program_hash),
ProgramBootstrap::Durable => Ok(()),
ProgramBootstrap::Pending {
tx_offset,
durable_offset,
Expand All @@ -160,7 +160,7 @@ impl BootstrapCompletion {
.context("failed waiting for initialized program to become durable")?;
}

Ok(self.program_hash)
Ok(())
}
}
}
Expand Down Expand Up @@ -1132,7 +1132,8 @@ impl Host {
(program, true)
}
};
let mut bootstrap_completion = Some(BootstrapCompletion::durable(program.hash));
let bootstrap_generation = database.bootstrap_generation;
let mut bootstrap_completion = Some(BootstrapCompletion::durable(bootstrap_generation));

let relational_db = Arc::new(db);
let (program, launched) = match HostType::from(program.kind) {
Expand Down Expand Up @@ -1222,13 +1223,12 @@ impl Host {
};

if program_needs_init {
let program_hash = program.hash;
let InitDatabaseResult { reducer, tx_offset } = launched.module_host.init_database(program).await?;
if let Some(call_result) = reducer {
Result::from(call_result)?;
}
bootstrap_completion = Some(BootstrapCompletion::pending(
program_hash,
bootstrap_generation,
tx_offset,
launched.module_host.durable_tx_offset(),
));
Expand Down Expand Up @@ -1540,6 +1540,7 @@ pub(crate) async fn extract_schema_with_pools(
owner_identity,
host_type,
initial_program: program.hash,
bootstrap_generation: 0,
};

let core = AllocatedJobCore::default();
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/host/instance_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,7 @@ mod test {
owner_identity: Identity::ZERO,
host_type: HostType::Wasm,
initial_program: Hash::ZERO,
bootstrap_generation: 0,
},
replica_id: 0,
logger,
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/messages/control_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ pub struct Database {
///
/// Updating the database's module will **not** change this value.
pub initial_program: Hash,
/// Generation of the current bootstrap requirement for `initial_program`.
pub bootstrap_generation: u64,
}

#[derive(Clone, PartialEq, Serialize, Deserialize)]
Expand Down
2 changes: 2 additions & 0 deletions crates/standalone/src/control_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ mod compat {
owner_identity,
host_type,
initial_program,
bootstrap_generation: 0,
}
}
}
Expand All @@ -680,6 +681,7 @@ mod compat {
owner_identity,
host_type,
initial_program,
bootstrap_generation: _,
}: CanonicalDatabase,
) -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions crates/standalone/src/control_db/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ fn test_decode() -> ResultTest<()> {
owner_identity: id,
host_type: HostType::Wasm,
initial_program: Hash::ZERO,
bootstrap_generation: 0,
};

cdb.insert_database(db.clone())?;
Expand Down
4 changes: 2 additions & 2 deletions crates/standalone/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ impl spacetimedb_client_api::ControlStateWriteAccess for StandaloneEnv {
owner_identity: *publisher,
host_type: spec.host_type,
initial_program: program.hash,
bootstrap_generation: 0,
};

let _hash_for_assert = program.hash;
Expand Down Expand Up @@ -432,9 +433,8 @@ impl spacetimedb_client_api::ControlStateWriteAccess for StandaloneEnv {
.await?;
let _stored_hash_for_assert = self.program_store.put(program_bytes).await?;
debug_assert_eq!(_hash_for_assert, _stored_hash_for_assert);

self.control_db.update_database(database)?;
}
self.control_db.update_database(database)?;

for instance in self.control_db.get_replicas_by_database(database_id)? {
self.delete_replica(instance.id).await?;
Expand Down
Loading