fix(pipeline): add idempotency guard to submit-pass0b endpoint
Prevents duplicate batch submissions that caused ~$170 in extra costs. Refuses new submit if a batch was submitted in the last 10 minutes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2298,13 +2298,29 @@ class SubmitPass0bRequest(BaseModel):
|
|||||||
batch_size: int = 5
|
batch_size: int = 5
|
||||||
|
|
||||||
|
|
||||||
|
_last_submit_batch_id: str = ""
|
||||||
|
_last_submit_time: float = 0
|
||||||
|
|
||||||
|
|
||||||
@router.post("/generate/submit-pass0b")
|
@router.post("/generate/submit-pass0b")
|
||||||
async def submit_pass0b(req: SubmitPass0bRequest):
|
async def submit_pass0b(req: SubmitPass0bRequest):
|
||||||
"""Submit Pass 0b batch to Anthropic Batch API.
|
"""Submit Pass 0b batch to Anthropic Batch API.
|
||||||
|
|
||||||
Loads unprocessed obligations, applies pre-LLM filter, submits batch.
|
SAFETY: Refuses to submit if a batch was submitted in the last 10 minutes.
|
||||||
Returns batch_id for status polling and later result processing.
|
This prevents duplicate batches from curl retries or timeouts.
|
||||||
"""
|
"""
|
||||||
|
import time
|
||||||
|
global _last_submit_batch_id, _last_submit_time
|
||||||
|
|
||||||
|
# Idempotency guard: refuse if last submit was <10 min ago
|
||||||
|
elapsed = time.time() - _last_submit_time
|
||||||
|
if elapsed < 600 and _last_submit_batch_id:
|
||||||
|
return {
|
||||||
|
"status": "blocked",
|
||||||
|
"reason": f"Batch {_last_submit_batch_id} was submitted {int(elapsed)}s ago. Wait {int(600 - elapsed)}s or use force=true.",
|
||||||
|
"last_batch_id": _last_submit_batch_id,
|
||||||
|
}
|
||||||
|
|
||||||
from services.decomposition_pass import DecompositionPass
|
from services.decomposition_pass import DecompositionPass
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
try:
|
try:
|
||||||
@@ -2313,6 +2329,12 @@ async def submit_pass0b(req: SubmitPass0bRequest):
|
|||||||
limit=req.limit,
|
limit=req.limit,
|
||||||
batch_size=req.batch_size,
|
batch_size=req.batch_size,
|
||||||
)
|
)
|
||||||
|
# Record successful submit
|
||||||
|
batch_id = result.get("batch_id", "")
|
||||||
|
if batch_id:
|
||||||
|
_last_submit_batch_id = batch_id
|
||||||
|
_last_submit_time = time.time()
|
||||||
|
logger.info("Submit guard: recorded batch %s", batch_id)
|
||||||
return result
|
return result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Submit Pass 0b failed: %s", e)
|
logger.error("Submit Pass 0b failed: %s", e)
|
||||||
|
|||||||
Reference in New Issue
Block a user