Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,27 @@ pub(crate) fn ensure_run_conversation_writable_with_connection(
ensure_conversation_writable_with_connection(conn, &root_session_id)
}

/// Resolve exact PR1 ownership before checking a Session's root fence.
///
/// This is used only by deletion planning, including direct Worker deletion;
/// ordinary submission paths keep their PR2 fast path and never call it.
pub(crate) fn ensure_session_conversation_writable_with_connection(
conn: &Connection,
session_id: &str,
) -> Result<(), String> {
match exact_submission_scope_with_connection(conn, session_id)? {
AgentOrgSubmissionScope::Unknown => Err(format!(
"Agent Org deletion ownership remained unknown for session {session_id}"
)),
AgentOrgSubmissionScope::Ordinary => {
ensure_conversation_writable_with_connection(conn, session_id)
}
AgentOrgSubmissionScope::Run { run_id } => {
ensure_run_conversation_writable_with_connection(conn, &run_id)
}
}
}

/// A Run is writable only while it is running and its root conversation is
/// not fenced. Callers that scanned earlier must repeat this check in the
/// transaction that performs their durable write.
Expand Down Expand Up @@ -426,7 +447,6 @@ pub(crate) fn establish_conversation_delete_fence_with_connection(
/// Own the short, serialized transaction used to establish a deletion fence.
/// Callers that must compare topology inside the same snapshot should instead
/// use [`establish_conversation_delete_fence_with_connection`].
#[cfg(test)]
pub(crate) fn establish_conversation_delete_fence(root_session_id: &str) -> Result<(), String> {
let root_session_id = root_session_id.to_string();
let outcome = with_sessions_writer(|| -> Result<_, String> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ mod tests;
#[cfg(debug_assertions)]
#[doc(hidden)]
pub use deletion::debug_establish_e2e_conversation_delete_fence;
#[cfg(test)]
pub(crate) use deletion::establish_conversation_delete_fence;
pub(crate) use deletion::{
admit_agent_org_submission, admit_known_agent_org_submission, agent_org_submission_in_progress,
ensure_conversation_writable_with_connection,
establish_conversation_delete_fence_with_connection, exact_submission_scope,
is_run_writable_with_connection, recheck_agent_org_submission,
ensure_session_conversation_writable_with_connection, establish_conversation_delete_fence,
exact_submission_scope, is_run_writable_with_connection, recheck_agent_org_submission,
recheck_known_agent_org_submission, remove_conversation_delete_fence_with_connection,
submission_scope_for_loaded_session, AgentOrgSubmissionLease, AgentOrgSubmissionPolicy,
AgentOrgSubmissionScope, SharedAgentOrgSubmissionScope,
Expand All @@ -41,6 +39,7 @@ pub use finality::{
};
pub(crate) use progress::bump_work_revision_in_tx;
pub use progress::AgentOrgRunProgress;
pub(crate) use store::AgentOrgRunDeleteOutcome;
pub use store::AgentOrgRunStore;
pub(crate) use worker::recovery_dispatch_recipient_is_available;
pub use worker::{WorkerSessionInfo, WorkerSessionRuntime};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub use crud::{
update_status, update_work_item_link, update_worktree_merge_status, upsert_session,
UnifiedSessionRecord,
};
#[allow(unused_imports)]
pub(crate) use crud::{
delete_session_with_connection, finish_session_delete, notify_session_upserted,
prepare_session_delete, upsert_session_with_connection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ pub fn delete_session_cascade(session_id: &str, tables: &[&str]) -> SqliteResult
})
}

/// Transaction-aware form of [`delete_session_cascade`].
/// Transaction-aware form of [`delete_session_cascade`]. Image files are left
/// for the existing orphan-image housekeeping pass: deleting them here could
/// race an image persisted just before its message row acquires the writer.
///
/// The caller owns the transaction boundary. This is used when several Rust
/// Agent Org sessions and their run-owned rows must commit or roll back as one
Expand All @@ -164,20 +166,6 @@ pub(crate) fn delete_session_cascade_with_connection(
session_id: &str,
tables: &[&str],
) -> SqliteResult<()> {
// Collect image file paths before deleting the rows. Infer the
// prefix from the first table that ends with "_messages".
let prefix = tables
.iter()
.find(|t| t.ends_with("_messages"))
.and_then(|t| t.strip_suffix("_messages"));

if let Some(prefix) = prefix {
let image_paths = collect_session_image_paths_with_connection(conn, prefix, session_id)?;
if !image_paths.is_empty() {
super::images::delete_image_files(&image_paths);
}
}

delete_session_rows_with_connection(conn, session_id, tables)
}

Expand Down
Loading
Loading