From a6d40de1be0f8ae1ba938acb7875ebcf2b3b18e7 Mon Sep 17 00:00:00 2001 From: soryu Date: Thu, 12 Feb 2026 19:12:36 +0000 Subject: Fix PR creation task for directives to be atomic --- makima/src/orchestration/directive.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'makima/src/orchestration/directive.rs') diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index 37cc5e7..d2fcbfd 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -537,6 +537,24 @@ impl DirectiveOrchestrator { let directives = repository::get_idle_directives_needing_completion(&self.pool).await?; for directive in directives { + // Atomically claim this directive for completion using a placeholder. + // This prevents a concurrent tick from also spawning a completion task. + let placeholder_id = Uuid::new_v4(); + let claimed = repository::claim_directive_for_completion( + &self.pool, + directive.id, + placeholder_id, + ) + .await?; + + if !claimed { + tracing::debug!( + directive_id = %directive.id, + "Directive already claimed for completion — skipping" + ); + continue; + } + tracing::info!( directive_id = %directive.id, title = %directive.title, @@ -545,6 +563,8 @@ impl DirectiveOrchestrator { let step_tasks = repository::get_completed_step_tasks(&self.pool, directive.id).await?; if step_tasks.is_empty() { + // Release the claim since there's nothing to complete + let _ = repository::clear_completion_task(&self.pool, directive.id).await; continue; } @@ -603,14 +623,17 @@ impl DirectiveOrchestrator { update, ) .await; + // Replace placeholder with the real task ID repository::assign_completion_task(&self.pool, directive.id, task_id).await?; } Err(e) => { tracing::warn!( directive_id = %directive.id, error = %e, - "Failed to spawn completion task" + "Failed to spawn completion task — releasing claim" ); + // Release the claim so it can be retried on the next tick + let _ = repository::clear_completion_task(&self.pool, directive.id).await; } } } -- cgit v1.2.3