mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-10 03:30:59 +00:00
Build required publication on Petri main's finalization
Track Petri main now that required run finalization has merged there, read workflow execution from the engine state, resume the failed-publication regression with its admitted workflow, and keep the worker lifecycle helper usable for rejected appends. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3443a923c0
commit
599b674ec1
6 changed files with 74 additions and 50 deletions
52
Cargo.lock
generated
52
Cargo.lock
generated
|
|
@ -1820,7 +1820,7 @@ dependencies = [
|
|||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1934,7 +1934,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3774,7 +3774,7 @@ dependencies = [
|
|||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.62.2",
|
||||
"windows-core 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4584,7 +4584,7 @@ version = "0.50.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -5166,7 +5166,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|||
[[package]]
|
||||
name = "petri-attractor-steps"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"globset",
|
||||
|
|
@ -5197,7 +5197,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-driver"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"getrandom 0.3.4",
|
||||
|
|
@ -5217,7 +5217,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-engine"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"petri-ir",
|
||||
"serde",
|
||||
|
|
@ -5229,7 +5229,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-execution"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-driver",
|
||||
|
|
@ -5253,7 +5253,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-executor"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"libc",
|
||||
|
|
@ -5268,7 +5268,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-executor-sandbox"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-executor",
|
||||
|
|
@ -5290,7 +5290,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"marked-yaml",
|
||||
"petri-ir",
|
||||
|
|
@ -5304,7 +5304,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend-attractor"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"minijinja",
|
||||
"petri-frontend",
|
||||
|
|
@ -5321,7 +5321,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend-fabro"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"petri-frontend",
|
||||
"petri-frontend-attractor",
|
||||
|
|
@ -5337,7 +5337,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-frontend-native"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"petri-frontend",
|
||||
"petri-ir",
|
||||
|
|
@ -5348,7 +5348,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-ir"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
|
|
@ -5361,7 +5361,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-runtime"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-driver",
|
||||
|
|
@ -5382,7 +5382,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-steps"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-executor",
|
||||
|
|
@ -5398,7 +5398,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-store"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"getrandom 0.3.4",
|
||||
|
|
@ -5413,7 +5413,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "petri-testkit"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#e46845bd0139dd04e9e795d3201b5b9b4b8b1026"
|
||||
source = "git+https://github.com/lithoscomputer/petri.git?branch=main#505a17839987f052ef0a47b799d30c565fd29475"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"petri-driver",
|
||||
|
|
@ -5752,7 +5752,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6200,7 +6200,7 @@ dependencies = [
|
|||
"errno 0.3.14",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6259,7 +6259,7 @@ dependencies = [
|
|||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -6907,7 +6907,7 @@ version = "1.4.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||
dependencies = [
|
||||
"errno 0.2.8",
|
||||
"errno 0.3.14",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
|
@ -7385,7 +7385,7 @@ dependencies = [
|
|||
"getrandom 0.4.1",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -7420,7 +7420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -8467,7 +8467,7 @@ version = "0.1.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
14
Cargo.toml
14
Cargo.toml
|
|
@ -108,13 +108,13 @@ pebble-cli-core = { git = "https://github.com/lithoscomputer/pebble", branch = "
|
|||
# petri: the workflow engine Fabro runs its workflows on. Only `fabro-petri`
|
||||
# and `fabro-dot` (the DOT parser alone) may depend on these packages; the
|
||||
# keys carry the `petri_` prefix so the crate names say where they come from.
|
||||
petri_runtime = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-runtime" }
|
||||
petri_execution = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-execution" }
|
||||
petri_store = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-store" }
|
||||
petri_attractor_steps = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-attractor-steps" }
|
||||
petri_frontend_attractor = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-frontend-attractor" }
|
||||
petri_frontend_fabro = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-frontend-fabro" }
|
||||
petri_testkit = { git = "https://github.com/lithoscomputer/petri.git", rev = "0198e66f6619e147e461c52c138497863d851969", package = "petri-testkit" }
|
||||
petri_runtime = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-runtime" }
|
||||
petri_execution = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-execution" }
|
||||
petri_store = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-store" }
|
||||
petri_attractor_steps = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-attractor-steps" }
|
||||
petri_frontend_attractor = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-frontend-attractor" }
|
||||
petri_frontend_fabro = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-frontend-fabro" }
|
||||
petri_testkit = { git = "https://github.com/lithoscomputer/petri.git", branch = "main", package = "petri-testkit" }
|
||||
sentry = { version = "0.35", default-features = false, features = ["backtrace", "contexts", "ureq", "rustls"] }
|
||||
fork = "0.2"
|
||||
exec = "0.3"
|
||||
|
|
|
|||
|
|
@ -20,14 +20,13 @@ Both HTTP and in-process worker transports store the finish before settling
|
|||
managed status. A rejected append cannot settle the run. The later platform
|
||||
terminal lifecycle record acknowledges the same outcome; it cannot replace a
|
||||
terminal result or conclusion. Early worker failures without a Petri finish
|
||||
still end through their committed platform lifecycle record. Worker generation,
|
||||
run scope and lease ownership checks remain required for every worker write.
|
||||
still end through their committed platform lifecycle record. Run scope,
|
||||
authorization and lease ownership checks remain required for every worker write.
|
||||
|
||||
## Recovery and stored history
|
||||
|
||||
This integration pins Petri revision
|
||||
`0198e66f6619e147e461c52c138497863d851969`, coordinator format 9 and event
|
||||
contract 6. Petri retains its strict stored-format policy: version-8 coordinator
|
||||
This integration requires a Petri with required run finalization (coordinator
|
||||
format 9) and event contract 6. Petri retains its strict stored-format policy: version-8 coordinator
|
||||
logs cannot resume, inspect or replay with this engine. Fabro does not rewrite
|
||||
source history or relax that policy. Existing materialized views and stream
|
||||
rows remain stored; a projector replay failure holds Petri positions and reports
|
||||
|
|
|
|||
|
|
@ -574,13 +574,25 @@ mod tests {
|
|||
transition: RunLifecycleKind,
|
||||
status: RunStatus,
|
||||
) {
|
||||
let response = append_lifecycle_as_worker(app, run_id, token, transition, status).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
/// Append one lifecycle record as the run's worker, and return the
|
||||
/// server's response whatever it is.
|
||||
async fn append_lifecycle_as_worker(
|
||||
app: &axum::Router,
|
||||
run_id: RunId,
|
||||
token: &str,
|
||||
transition: RunLifecycleKind,
|
||||
status: RunStatus,
|
||||
) -> axum::response::Response {
|
||||
let record =
|
||||
PlatformRecord::RunLifecycle(RunLifecycleRecord::new(transition).with_status(status));
|
||||
let body = json!({
|
||||
"record": serde_json::to_value(&record).expect("the record encodes"),
|
||||
});
|
||||
let response = app
|
||||
.clone()
|
||||
app.clone()
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
|
|
@ -591,8 +603,7 @@ mod tests {
|
|||
.expect("the append request builds"),
|
||||
)
|
||||
.await
|
||||
.expect("the append request completes");
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
.expect("the append request completes")
|
||||
}
|
||||
|
||||
/// Petri's own finish of the run, stored the way its worker stores it:
|
||||
|
|
|
|||
|
|
@ -1262,16 +1262,24 @@ async fn published_run(
|
|||
let (origin, _) = upstream(&harness.run_dir.with_file_name("upstream"), 2).await;
|
||||
harness.source = Some(file_source(&origin, "main", Some(1)));
|
||||
harness.publisher = Some(Arc::clone(publisher) as Arc<dyn RunPublisher>);
|
||||
let workflow = workflow(
|
||||
&format!(" edit [shape=parallelogram, {attributes}]"),
|
||||
" start -> edit -> exit",
|
||||
);
|
||||
let outcome = harness
|
||||
.run_on(SandboxProviderKind::LOCAL, &workflow, SETTINGS)
|
||||
.run_on(
|
||||
SandboxProviderKind::LOCAL,
|
||||
&published_workflow(attributes),
|
||||
SETTINGS,
|
||||
)
|
||||
.await;
|
||||
(harness, outcome)
|
||||
}
|
||||
|
||||
/// The workflow [`published_run`] runs: one command stage with `attributes`.
|
||||
fn published_workflow(attributes: &str) -> String {
|
||||
workflow(
|
||||
&format!(" edit [shape=parallelogram, {attributes}]"),
|
||||
" start -> edit -> exit",
|
||||
)
|
||||
}
|
||||
|
||||
/// A successful run hands its publisher the run branch, the commit it ends
|
||||
/// on (held by the snapshot repository) and its patch, before the run ends.
|
||||
#[tokio::test]
|
||||
|
|
@ -1308,7 +1316,8 @@ async fn a_successful_run_is_published_with_its_branch_head_and_patch() {
|
|||
#[tokio::test]
|
||||
async fn a_failed_publication_fails_the_run() {
|
||||
let publisher = RecordingPublisher::new(Some("the push was rejected"));
|
||||
let (harness, outcome) = published_run("script=\"echo edited >> README.md\"", &publisher).await;
|
||||
let attributes = "script=\"echo edited >> README.md\"";
|
||||
let (harness, outcome) = published_run(attributes, &publisher).await;
|
||||
assert_eq!(outcome.status, RunStatus::Failed, "{outcome:?}");
|
||||
assert!(outcome.publish_failed);
|
||||
assert_eq!(outcome.failure.as_deref(), Some("the push was rejected"));
|
||||
|
|
@ -1324,7 +1333,12 @@ async fn a_failed_publication_fails_the_run() {
|
|||
assert_eq!(stored.failure, outcome.failure);
|
||||
assert!(stored.publish_failed);
|
||||
let resumed = harness
|
||||
.execute_on(SandboxProviderKind::LOCAL, "", SETTINGS, true)
|
||||
.execute_on(
|
||||
SandboxProviderKind::LOCAL,
|
||||
&published_workflow(attributes),
|
||||
SETTINGS,
|
||||
true,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(resumed.status, outcome.status);
|
||||
assert_eq!(resumed.failure, outcome.failure);
|
||||
|
|
|
|||
|
|
@ -1449,7 +1449,7 @@ async fn required_finalization_projects_only_the_committed_overall_result() {
|
|||
}
|
||||
finalizer.release.add_permits(1);
|
||||
let report = task.await.unwrap();
|
||||
assert_eq!(report.execution_status, PetriRunStatus::Success);
|
||||
assert_eq!(report.state.folded_status(), PetriRunStatus::Success);
|
||||
assert_eq!(
|
||||
report.status,
|
||||
if rejection.is_some() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue