mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-27 02:39:38 +02:00
MR-771: demote Run to direct-publish via expected_table_versions CAS
mutate_as and load now write directly to target tables and call the publisher once at the end with per-table expected versions; the Run state machine, _graph_runs.lance writers, __run__ staging branches, and server /runs/* endpoints are removed. Multi-statement mutations remain atomic at the manifest level via an in-memory MutationStaging accumulator that gives read-your-writes within a query and a single publish at the end. Concurrent-writer conflicts surface as ExpectedVersionMismatch (HTTP 409 manifest_conflict) instead of the old DivergentUpdate merge shape. Documents one known limitation in docs/runs.md: a multi-statement mid-query failure where op-N writes a Lance fragment and op-N+1 fails leaves Lance HEAD ahead of the manifest until a follow-up introduces per-table Lance branches. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
4e5374a85e
commit
35be20cb05
28 changed files with 1188 additions and 3216 deletions
|
|
@ -167,10 +167,6 @@ const EXPECTED_PATHS: &[&str] = &[
|
|||
"/branches",
|
||||
"/branches/{branch}",
|
||||
"/branches/merge",
|
||||
"/runs",
|
||||
"/runs/{run_id}",
|
||||
"/runs/{run_id}/publish",
|
||||
"/runs/{run_id}/abort",
|
||||
"/commits",
|
||||
"/commits/{commit_id}",
|
||||
];
|
||||
|
|
@ -256,30 +252,6 @@ fn openapi_branch_merge_is_post() {
|
|||
assert!(doc["paths"]["/branches/merge"]["post"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn openapi_runs_is_get() {
|
||||
let doc = openapi_json();
|
||||
assert!(doc["paths"]["/runs"]["get"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn openapi_run_show_is_get() {
|
||||
let doc = openapi_json();
|
||||
assert!(doc["paths"]["/runs/{run_id}"]["get"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn openapi_run_publish_is_post() {
|
||||
let doc = openapi_json();
|
||||
assert!(doc["paths"]["/runs/{run_id}/publish"]["post"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn openapi_run_abort_is_post() {
|
||||
let doc = openapi_json();
|
||||
assert!(doc["paths"]["/runs/{run_id}/abort"]["post"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn openapi_commits_is_get() {
|
||||
let doc = openapi_json();
|
||||
|
|
@ -321,10 +293,9 @@ const EXPECTED_SCHEMAS: &[&str] = &[
|
|||
"ReadOutput",
|
||||
"ReadRequest",
|
||||
"ReadTargetOutput",
|
||||
"ManifestConflictOutput",
|
||||
"SchemaApplyOutput",
|
||||
"SchemaApplyRequest",
|
||||
"RunListOutput",
|
||||
"RunOutput",
|
||||
"SnapshotOutput",
|
||||
"SnapshotTableOutput",
|
||||
];
|
||||
|
|
@ -490,19 +461,17 @@ fn error_output_schema_has_expected_fields() {
|
|||
assert!(props.contains_key("error"));
|
||||
assert!(props.contains_key("code"));
|
||||
assert!(props.contains_key("merge_conflicts"));
|
||||
assert!(props.contains_key("manifest_conflict"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_output_schema_has_expected_fields() {
|
||||
fn manifest_conflict_output_schema_has_expected_fields() {
|
||||
let doc = openapi_json();
|
||||
let schema = &doc["components"]["schemas"]["RunOutput"];
|
||||
let schema = &doc["components"]["schemas"]["ManifestConflictOutput"];
|
||||
let props = schema["properties"].as_object().unwrap();
|
||||
assert!(props.contains_key("run_id"));
|
||||
assert!(props.contains_key("target_branch"));
|
||||
assert!(props.contains_key("run_branch"));
|
||||
assert!(props.contains_key("status"));
|
||||
assert!(props.contains_key("created_at"));
|
||||
assert!(props.contains_key("updated_at"));
|
||||
assert!(props.contains_key("table_key"));
|
||||
assert!(props.contains_key("expected"));
|
||||
assert!(props.contains_key("actual"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -621,10 +590,6 @@ fn protected_endpoints_reference_bearer_token_security() {
|
|||
("/branches", "post"),
|
||||
("/branches/{branch}", "delete"),
|
||||
("/branches/merge", "post"),
|
||||
("/runs", "get"),
|
||||
("/runs/{run_id}", "get"),
|
||||
("/runs/{run_id}/publish", "post"),
|
||||
("/runs/{run_id}/abort", "post"),
|
||||
("/commits", "get"),
|
||||
("/commits/{commit_id}", "get"),
|
||||
];
|
||||
|
|
@ -667,18 +632,6 @@ fn branch_delete_has_branch_path_parameter() {
|
|||
assert!(has_branch, "DELETE /branches/{{branch}} must have 'branch' path parameter");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_show_has_run_id_path_parameter() {
|
||||
let doc = openapi_json();
|
||||
let params = doc["paths"]["/runs/{run_id}"]["get"]["parameters"]
|
||||
.as_array()
|
||||
.unwrap();
|
||||
let has_run_id = params.iter().any(|p| {
|
||||
p["name"].as_str() == Some("run_id") && p["in"].as_str() == Some("path")
|
||||
});
|
||||
assert!(has_run_id, "GET /runs/{{run_id}} must have 'run_id' path parameter");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commit_show_has_commit_id_path_parameter() {
|
||||
let doc = openapi_json();
|
||||
|
|
@ -914,7 +867,6 @@ async fn auth_mode_spec_has_security_on_protected_operations() {
|
|||
("/change", "post"),
|
||||
("/snapshot", "get"),
|
||||
("/branches", "get"),
|
||||
("/runs", "get"),
|
||||
("/commits", "get"),
|
||||
];
|
||||
for (path, method) in protected_paths {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue