Skip to content

Commit a90fba8

Browse files
authored
Merge pull request #757 from obeli-sk/fix-deployment-id-after-failed-upgrade
fix(db): Update deployment id only after successful auto-upgrade
2 parents 4424587 + cad7e2c commit a90fba8

3 files changed

Lines changed: 56 additions & 29 deletions

File tree

crates/db-postgres/src/postgres_dao.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ async fn update_state_component_upgrade_finished_failed(
908908
async fn update_state_locked_get_intermittent_event_count(
909909
tx: &Transaction<'_>,
910910
execution_id: &ExecutionId,
911-
deployment_id: DeploymentId,
911+
deployment_id: Option<DeploymentId>,
912912
component_digest: Option<&ComponentDigest>,
913913
executor_id: ExecutorId,
914914
run_id: RunId,
@@ -939,7 +939,7 @@ async fn update_state_locked_get_intermittent_event_count(
939939
pending_expires_finished = $2,
940940
state = $3,
941941
updated_at = CURRENT_TIMESTAMP,
942-
deployment_id = $4,
942+
deployment_id = COALESCE($4, deployment_id),
943943
component_id_input_digest = COALESCE($5, component_id_input_digest),
944944
945945
max_retries = $6,
@@ -959,7 +959,7 @@ async fn update_state_locked_get_intermittent_event_count(
959959
&i64::from(appending_version.0),
960960
&lock_expires_at,
961961
&STATE_LOCKED,
962-
&deployment_id.to_string(),
962+
&deployment_id.map(|deployment_id| deployment_id.to_string()),
963963
&component_digest.map(|component_digest| component_digest.as_slice().to_vec()), // no change if `None` due to `coalesce`
964964
&retry_config.max_retries.map(i64::from),
965965
&backoff_millis,
@@ -2029,7 +2029,7 @@ fn parse_response_with_cursor(
20292029
}
20302030

20312031
/// `component_id` is used to construct the `Locked` event.
2032-
/// If `update_component_digest` is set, `t_state` will be set to the component's digest.
2032+
/// If `update_component_digest_and_deployment_id` is set, execution state (`t_state`) will be updated to the component's digest and deployment id.
20332033
/// This should be true in all cases except for `lock_pending_by_ffqns_auto`, where
20342034
/// the digest in `t_state` is only updated after a successful execution upgrade.
20352035
#[instrument(level = Level::TRACE, skip_all, fields(%execution_id, %run_id, %executor_id))]
@@ -2038,7 +2038,7 @@ async fn lock_single_execution(
20382038
tx: &Transaction<'_>,
20392039
created_at: DateTime<Utc>,
20402040
component_id: &ComponentId,
2041-
update_component_digest: bool, // if set, update `t_state` as well
2041+
update_component_digest_and_deployment_id: bool,
20422042
deployment_id: DeploymentId,
20432043
execution_id: &ExecutionId,
20442044
run_id: RunId,
@@ -2051,7 +2051,7 @@ async fn lock_single_execution(
20512051

20522052
// Check State
20532053
let combined_state = get_combined_state(tx, execution_id).await?;
2054-
let context_component_digest = if update_component_digest {
2054+
let context_component_digest = if update_component_digest_and_deployment_id {
20552055
component_id.component_digest.clone()
20562056
} else {
20572057
combined_state.execution_with_state.component_digest.clone()
@@ -2106,8 +2106,8 @@ async fn lock_single_execution(
21062106
let intermittent_event_count = update_state_locked_get_intermittent_event_count(
21072107
tx,
21082108
execution_id,
2109-
deployment_id,
2110-
update_component_digest.then_some(&component_id.component_digest),
2109+
update_component_digest_and_deployment_id.then_some(deployment_id),
2110+
update_component_digest_and_deployment_id.then_some(&component_id.component_digest),
21112111
executor_id,
21122112
run_id,
21132113
lock_expires_at,

crates/db-sqlite/src/sqlite_dao.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,7 @@ impl SqlitePool {
12141214
fn update_state_locked_get_intermittent_event_count(
12151215
tx: &Transaction,
12161216
execution_id: &ExecutionId,
1217-
deployment_id: DeploymentId,
1217+
deployment_id: Option<DeploymentId>,
12181218
component_digest: Option<&ComponentDigest>,
12191219
executor_id: ExecutorId,
12201220
run_id: RunId,
@@ -1241,7 +1241,7 @@ impl SqlitePool {
12411241
pending_expires_finished = :pending_expires_finished,
12421242
state = :state,
12431243
updated_at = CURRENT_TIMESTAMP,
1244-
deployment_id = :deployment_id,
1244+
deployment_id = COALESCE(:deployment_id, deployment_id),
12451245
component_id_input_digest = COALESCE(:component_id_input_digest, component_id_input_digest),
12461246
12471247
max_retries = :max_retries,
@@ -1263,7 +1263,7 @@ impl SqlitePool {
12631263
":appending_version": appending_version.0,
12641264
":pending_expires_finished": lock_expires_at,
12651265
":state": STATE_LOCKED,
1266-
":deployment_id": deployment_id.to_string(),
1266+
":deployment_id": deployment_id, // no change if `None` due to `coalesce`
12671267
":component_id_input_digest": component_digest.cloned(), // no change if `None` due to `coalesce`
12681268
":max_retries": retry_config.max_retries,
12691269
":retry_exp_backoff_millis": backoff_millis,
@@ -1852,7 +1852,7 @@ impl SqlitePool {
18521852
}
18531853

18541854
/// `component_id` is used to construct the `Locked` event.
1855-
/// If `update_component_digest` is set, `t_state` will be set to the component's digest.
1855+
/// If `update_component_digest_and_deployment_id` is set, execution state (`t_state`) will be updated to the component's digest and deployment id.
18561856
/// This should be true in all cases except for `lock_pending_by_ffqns_auto`, where
18571857
/// the digest in `t_state` is only updated after a successful execution upgrade.
18581858
#[instrument(level = Level::TRACE, skip(tx))]
@@ -1861,7 +1861,7 @@ impl SqlitePool {
18611861
tx: &Transaction,
18621862
created_at: DateTime<Utc>,
18631863
component_id: &ComponentId,
1864-
update_component_digest: bool, // if set, update `t_state` as well
1864+
update_component_digest_and_deployment_id: bool,
18651865
deployment_id: DeploymentId,
18661866
execution_id: &ExecutionId,
18671867
run_id: RunId,
@@ -1872,7 +1872,7 @@ impl SqlitePool {
18721872
) -> Result<LockedExecution, DbErrorWrite> {
18731873
trace!("lock_single_execution");
18741874
let combined_state = Self::get_combined_state(tx, execution_id)?;
1875-
let context_component_digest = if update_component_digest {
1875+
let context_component_digest = if update_component_digest_and_deployment_id {
18761876
component_id.component_digest.clone()
18771877
} else {
18781878
combined_state.execution_with_state.component_digest.clone()
@@ -1934,8 +1934,8 @@ impl SqlitePool {
19341934
let intermittent_event_count = Self::update_state_locked_get_intermittent_event_count(
19351935
tx,
19361936
execution_id,
1937-
deployment_id,
1938-
update_component_digest.then_some(&component_id.component_digest),
1937+
update_component_digest_and_deployment_id.then_some(deployment_id),
1938+
update_component_digest_and_deployment_id.then_some(&component_id.component_digest),
19391939
executor_id,
19401940
run_id,
19411941
lock_expires_at,

crates/wasm-workers/src/workflow/workflow_js_worker.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ mod tests {
597597
use assert_matches::assert_matches;
598598
use chrono::DateTime;
599599
use concepts::component_id::{COMPONENT_DIGEST_DUMMY, ComponentDigest, Digest};
600-
use concepts::prefixed_ulid::{DEPLOYMENT_ID_DUMMY, DelayId, ExecutorId, RunId};
600+
use concepts::prefixed_ulid::{DEPLOYMENT_ID_DUMMY, DelayId, DeploymentId, ExecutorId, RunId};
601601
use concepts::storage::{
602602
CapturedDbWrite, ComponentUpgradeOutcome, ComponentUpgradeReason, CreateRequest,
603603
DbConnectionTest, DbPool, DbPoolCloseable, ExecutionRequest, HistoryEvent, JoinSetRequest,
@@ -1059,6 +1059,26 @@ mod tests {
10591059
clock_fn: Box<dyn ClockFn>,
10601060
fn_registry: Arc<dyn FunctionRegistry>,
10611061
workflow_engine: Arc<Engine>,
1062+
) -> (WorkflowJsWorker, concepts::ComponentId, RunnableComponent) {
1063+
compile_js_workflow_worker_with_deployment_id(
1064+
js_source,
1065+
user_ffqn,
1066+
db_pool,
1067+
clock_fn,
1068+
fn_registry,
1069+
workflow_engine,
1070+
DEPLOYMENT_ID_DUMMY,
1071+
)
1072+
}
1073+
1074+
fn compile_js_workflow_worker_with_deployment_id(
1075+
js_source: &str,
1076+
user_ffqn: &FunctionFqn,
1077+
db_pool: Arc<dyn DbPool>,
1078+
clock_fn: Box<dyn ClockFn>,
1079+
fn_registry: Arc<dyn FunctionRegistry>,
1080+
workflow_engine: Arc<Engine>,
1081+
deployment_id: DeploymentId,
10621082
) -> (WorkflowJsWorker, concepts::ComponentId, RunnableComponent) {
10631083
let wasm_path = workflow_js_runtime_builder::WORKFLOW_JS_RUNTIME;
10641084
let params = default_js_params();
@@ -1108,7 +1128,7 @@ mod tests {
11081128

11091129
(
11101130
linked.into_worker(
1111-
DEPLOYMENT_ID_DUMMY,
1131+
deployment_id,
11121132
db_pool,
11131133
deadline_factory,
11141134
CancelRegistry::new(),
@@ -2575,6 +2595,8 @@ mod tests {
25752595
let (_guard, db_pool, db_close) = database.set_up().await;
25762596
let sim_clock = SimClock::epoch();
25772597
let user_ffqn = FunctionFqn::new_static("test:pkg/ifc", "test-auto-locking-failure");
2598+
let original_deployment_id = DeploymentId::from_parts(0, 9009);
2599+
let upgrade_deployment_id = DeploymentId::from_parts(0, 9010);
25782600
let original_js_source = r"
25792601
export default function test_auto_locking_failure(params) {
25802602
obelisk.sleep({ milliseconds: 10 });
@@ -2594,22 +2616,25 @@ mod tests {
25942616
let workflow_engine =
25952617
Engines::get_workflow_engine_test(EngineConfig::on_demand_testing()).unwrap();
25962618
let (original_worker, original_component_id, _original_runnable) =
2597-
compile_js_workflow_worker(
2619+
compile_js_workflow_worker_with_deployment_id(
25982620
original_js_source,
25992621
&user_ffqn,
26002622
db_pool.clone(),
26012623
sim_clock.clone_box(),
26022624
fn_registry.clone(),
26032625
workflow_engine.clone(),
2626+
original_deployment_id,
2627+
);
2628+
let (upgrade_worker, upgrade_component_id, _upgrade_runnable) =
2629+
compile_js_workflow_worker_with_deployment_id(
2630+
failing_upgrade_js_source,
2631+
&user_ffqn,
2632+
db_pool.clone(),
2633+
sim_clock.clone_box(),
2634+
fn_registry,
2635+
workflow_engine,
2636+
upgrade_deployment_id,
26042637
);
2605-
let (upgrade_worker, upgrade_component_id, _upgrade_runnable) = compile_js_workflow_worker(
2606-
failing_upgrade_js_source,
2607-
&user_ffqn,
2608-
db_pool.clone(),
2609-
sim_clock.clone_box(),
2610-
fn_registry,
2611-
workflow_engine,
2612-
);
26132638
assert_ne!(
26142639
original_component_id.component_digest,
26152640
upgrade_component_id.component_digest
@@ -2644,8 +2669,8 @@ mod tests {
26442669
parent: None,
26452670
metadata: ExecutionMetadata::empty(),
26462671
scheduled_at: created_at,
2647-
component_id: original_component_id,
2648-
deployment_id: DEPLOYMENT_ID_DUMMY,
2672+
component_id: original_component_id.clone(),
2673+
deployment_id: original_deployment_id,
26492674
scheduled_by: None,
26502675
paused: false,
26512676
})
@@ -2677,6 +2702,8 @@ mod tests {
26772702
);
26782703

26792704
let log = db_connection.get(&execution_id).await.unwrap();
2705+
assert_eq!(original_deployment_id, log.deployment_id);
2706+
assert_eq!(original_component_id.component_digest, log.component_digest);
26802707
assert_eq!(8, log.events.len());
26812708
assert_matches!(&log.events[0].event, ExecutionRequest::Created { .. });
26822709
assert_matches!(&log.events[1].event, ExecutionRequest::Locked(_));

0 commit comments

Comments
 (0)