Implement crash-safe streaming worker runtime

This commit is contained in:
ms2k 2026-07-17 18:51:44 +09:00
commit cdeef3cc1a

View file

@ -18,7 +18,7 @@ use remora_domain::{
use remora_durable::{MutationDisposition, PoolConfig, connect, migrate as durable_migrate};
use remora_identity::{DefaultTarget, Principal};
use remora_result::{PublicationInput, migrate as result_migrate};
use remora_target::{ContentSha256, ObjectIdentity, StoredObject, attempt_manifest_key};
use remora_target::{ContentSha256, ObjectIdentity, StoredObject, attempt_manifest_key_in};
use sqlx::PgPool;
struct Harness {
@ -168,7 +168,7 @@ impl Harness {
) -> PublicationInput {
let manifest_id = unique_id("manifest");
let sha256 = format!("sha256:{}", "11".repeat(32));
let key = attempt_manifest_key(attempt_id, &manifest_id);
let key = attempt_manifest_key_in("users/alice", attempt_id, &manifest_id);
let input = PublicationInput {
attempt_id: attempt_id.clone(),
manifest_id: manifest_id.clone(),
@ -190,9 +190,10 @@ impl Harness {
"INSERT INTO result_inventories (
attempt_id, state, manifest_schema_version, manifest_id, manifest_store,
manifest_bucket, manifest_key, manifest_version_id, manifest_sha256,
manifest_size, member_count, total_bytes
manifest_size, member_count, total_bytes,
staging_origin_attempt_id, target_prefix
) VALUES ($1, 'sealed', 1, $2, 'primary', 'remora-results', $3,
'version-1', $4, 128, $5, $6)",
'version-1', $4, 128, $5, $6, $1, 'users/alice')",
)
.bind(attempt_id.as_str())
.bind(manifest_id.as_str())
@ -283,6 +284,7 @@ async fn resolved_source_checkpoint_and_progress_are_fenced_and_replayable() {
resolved_source_id: resolved.id.clone(),
validated_bytes: 0,
validated_members: 0,
staging_multipart: None,
},
)
.await
@ -295,6 +297,7 @@ async fn resolved_source_checkpoint_and_progress_are_fenced_and_replayable() {
resolved_source_id: resolved.id.clone(),
validated_bytes: 1024,
validated_members: 1,
staging_multipart: None,
};
let mut wrong_source = checkpoint.clone();
wrong_source.resolved_source_id = unique_id("resolved");
@ -539,6 +542,7 @@ async fn failure_disposition_retries_with_budget_and_becomes_terminal_when_exhau
resolved_source_id: retry_source.id.clone(),
validated_bytes: 512,
validated_members: 1,
staging_multipart: None,
};
assert_rejected(
service
@ -555,6 +559,40 @@ async fn failure_disposition_retries_with_budget_and_becomes_terminal_when_exhau
.persist_checkpoint(&first, &unique_id("checkpointop"), retry_checkpoint)
.await
.unwrap();
sqlx::query(
"INSERT INTO result_inventories (
attempt_id, staging_origin_attempt_id, target_prefix
) VALUES ($1, $1, 'users/alice')",
)
.bind(first.attempt_id.as_str())
.execute(&harness.pool)
.await
.unwrap();
sqlx::query(
"INSERT INTO result_inventory_members (
attempt_id, member_id, path, size, object_store, object_bucket,
object_key, object_sha256
) VALUES ($1, $2, 'retry.bin', 512, 'target', 'bucket', $3, $4)",
)
.bind(first.attempt_id.as_str())
.bind(unique_id("member").as_str())
.bind(format!(
"users/alice/_remora/a/{}/o/retry/retry.bin",
first.attempt_id.as_str()
))
.bind(format!("sha256:{}", "0".repeat(64)))
.execute(&harness.pool)
.await
.unwrap();
sqlx::query(
"UPDATE result_inventories
SET member_count = 1, total_bytes = 512
WHERE attempt_id = $1",
)
.bind(first.attempt_id.as_str())
.execute(&harness.pool)
.await
.unwrap();
assert!(matches!(
service
.publish_failure(
@ -610,6 +648,20 @@ async fn failure_disposition_retries_with_budget_and_becomes_terminal_when_exhau
.await
.unwrap();
assert_eq!(initial_progress, 512);
let staging_origin: String =
sqlx::query_scalar("SELECT staging_origin_attempt_id FROM attempts WHERE attempt_id = $1")
.bind(second.attempt_id.as_str())
.fetch_one(&harness.pool)
.await
.unwrap();
assert_eq!(staging_origin, first.attempt_id.as_str());
let inventory_owner: String =
sqlx::query_scalar("SELECT attempt_id FROM result_inventories WHERE attempt_id = $1")
.bind(second.attempt_id.as_str())
.fetch_one(&harness.pool)
.await
.unwrap();
assert_eq!(inventory_owner, second.attempt_id.as_str());
service
.publish_failure(
&second,
@ -760,7 +812,7 @@ async fn publication_from_database(pool: &PgPool, attempt_id: &OpaqueId) -> Publ
identity: ObjectIdentity {
target_store_id: row.1,
bucket: row.2,
key: attempt_manifest_key(attempt_id, &manifest_id),
key: attempt_manifest_key_in("users/alice", attempt_id, &manifest_id),
version_id: row.3,
},
content_sha256: ContentSha256::parse(row.4).unwrap(),