refactor(events): Lift transaction control to callers, eliminate duplicated store functions

events_db.rs:
- Removed internal savepoints from upsert_state_events,
  upsert_label_events, and upsert_milestone_events. Each function
  previously created its own savepoint, making it impossible for
  callers to wrap all three in a single atomic transaction.
- Changed signatures from &mut Connection to &Connection, since
  savepoints are no longer created internally. This makes the
  functions compatible with rusqlite::Transaction (which derefs to
  Connection), allowing callers to pass a transaction directly.

orchestrator.rs:
- Deleted the three store_*_events_tx() functions (store_state_events_tx,
  store_label_events_tx, store_milestone_events_tx) which were
  hand-duplicated copies of the events_db upsert functions, created as
  a workaround for the &mut Connection requirement. Now that events_db
  accepts &Connection, store_resource_events() calls the canonical
  upsert functions directly through the unchecked_transaction.
- Replaced the max-iterations guard in drain_resource_events() with a
  HashSet-based deduplication of job IDs. The old guard used an
  arbitrary 2x multiplier on total_pending which could either terminate
  too early (if many retries were legitimate) or too late. The new
  approach precisely prevents reprocessing the same job within a single
  drain run, which is the actual invariant we need.

Net effect: ~133 lines of duplicated SQL removed, single source of
truth for event upsert logic, and callers control transaction scope.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-03 14:09:35 -05:00
parent 4c0123426a
commit 880ad1d3fa
2 changed files with 36 additions and 181 deletions

View File

@@ -9,9 +9,9 @@ use crate::gitlab::types::{GitLabLabelEvent, GitLabMilestoneEvent, GitLabStateEv
/// Upsert state events for an entity.
///
/// Uses INSERT OR REPLACE keyed on UNIQUE(gitlab_id, project_id).
/// Wraps in a savepoint for atomicity per entity.
/// Caller is responsible for wrapping in a transaction if atomicity is needed.
pub fn upsert_state_events(
conn: &mut Connection,
conn: &Connection,
project_id: i64,
entity_type: &str,
entity_local_id: i64,
@@ -19,9 +19,7 @@ pub fn upsert_state_events(
) -> Result<usize> {
let (issue_id, merge_request_id) = resolve_entity_ids(entity_type, entity_local_id)?;
let sp = conn.savepoint()?;
let mut stmt = sp.prepare_cached(
let mut stmt = conn.prepare_cached(
"INSERT OR REPLACE INTO resource_state_events
(gitlab_id, project_id, issue_id, merge_request_id, state,
actor_gitlab_id, actor_username, created_at,
@@ -51,15 +49,13 @@ pub fn upsert_state_events(
count += 1;
}
drop(stmt);
sp.commit()?;
Ok(count)
}
/// Upsert label events for an entity.
/// Caller is responsible for wrapping in a transaction if atomicity is needed.
pub fn upsert_label_events(
conn: &mut Connection,
conn: &Connection,
project_id: i64,
entity_type: &str,
entity_local_id: i64,
@@ -67,9 +63,7 @@ pub fn upsert_label_events(
) -> Result<usize> {
let (issue_id, merge_request_id) = resolve_entity_ids(entity_type, entity_local_id)?;
let sp = conn.savepoint()?;
let mut stmt = sp.prepare_cached(
let mut stmt = conn.prepare_cached(
"INSERT OR REPLACE INTO resource_label_events
(gitlab_id, project_id, issue_id, merge_request_id, action,
label_name, actor_gitlab_id, actor_username, created_at)
@@ -96,15 +90,13 @@ pub fn upsert_label_events(
count += 1;
}
drop(stmt);
sp.commit()?;
Ok(count)
}
/// Upsert milestone events for an entity.
/// Caller is responsible for wrapping in a transaction if atomicity is needed.
pub fn upsert_milestone_events(
conn: &mut Connection,
conn: &Connection,
project_id: i64,
entity_type: &str,
entity_local_id: i64,
@@ -112,9 +104,7 @@ pub fn upsert_milestone_events(
) -> Result<usize> {
let (issue_id, merge_request_id) = resolve_entity_ids(entity_type, entity_local_id)?;
let sp = conn.savepoint()?;
let mut stmt = sp.prepare_cached(
let mut stmt = conn.prepare_cached(
"INSERT OR REPLACE INTO resource_milestone_events
(gitlab_id, project_id, issue_id, merge_request_id, action,
milestone_title, milestone_id, actor_gitlab_id, actor_username, created_at)
@@ -142,9 +132,6 @@ pub fn upsert_milestone_events(
count += 1;
}
drop(stmt);
sp.commit()?;
Ok(count)
}