fix(samples): serialize concurrent seed runs per company - #99
Merged
Merged
Conversation
Two runs at the same time could reject each other's sample while it was still in processing (the leftover rule of #84). A seed run now holds a transaction-level advisory lock per company for its whole duration – safe behind the Supabase transaction pooler, released when the run ends or its connection drops. A second run waits and then finds the samples in place; after a minute it stops with SeedRunBusy and a clear message. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…out (#99 review) Pool and Supabase role end every statement after 30 s, so the documented one-minute wait never happened and the waiting run failed with a raw statement-timeout error. The wait is now 20 s, and a statement timeout while waiting also reads as SeedRunBusy. The seed script's pool gets a third connection: one holds the lock for the whole run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ext) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Deployment failed for project requestflow with the following error: Learn More: https://vercel.com/doc-edit?upgradeToPro=build-rate-limit |
…ted next) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Deployment failed for project requestflow-ai with the following error: Learn More: https://vercel.com/doc-edit?upgradeToPro=build-rate-limit |
Owner
Author
Frischer Review (unabhängiger Subagent, liest nur, Stand
|
| # | Befund | Umsetzung |
|---|---|---|
| 1 | 60-s-Wartezeit vom 30-s-statement_timeout überholt |
055464a: Die Wartezeit ist jetzt 20 s, der Kommentar begründet das. Ein Statement-Timeout während des Wartens (57014) meldet ebenfalls SeedRunBusy, so kommt auch bei einem niedrigeren Rollen-Timeout die klare Meldung. Runbook §6 und CHANGELOG sagen jetzt „nach 20 Sekunden“. Der 57014-Pfad hat keinen eigenen Test (30 s Laufzeit), er nutzt dieselbe Erkennung wie der getestete 55P03-Pfad. |
| 2 | Seed-Pool ohne Reserve | 055464a: max: 3 mit Kommentar („one connection holds the per-company seed lock“) |
| 3 | roter Lauf nur behauptet | Probe-Commits 24a21b2 + 88c81bf ohne lockSeedRun. Im CI-Lauf 36461390392 (88c81bf; der erste Lauf 36460519453 scheiterte schon am Lint der Probe) scheitern genau die zwei #93-Tests: „expected [ 'pumpe-p204', 'pumpe-p204', …(2) ] to deeply equal [ 'pumpe-p204', 'werk-ost' ]“ (vier statt zwei Musterfälle) und „promise resolved … instead of rejecting“. Beide Probe-Commits sind per 145ad9e + b69bd3a zurückgenommen, der Baum ist identisch mit 055464a. |
Fluory
marked this pull request as ready for review
September 28, 2026 18:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warum
Fixes #93 · gefunden im Review von #92
Arbeitsstand
pnpm seed:samples-Läufe für dieselbe Firma stören sich nicht mehr: Jeder Musterfall entsteht genau einmal, und kein Lauf lehnt den Musterfall des anderen ab.Was ist passiert (Klartext)
Die vorbereiteten Beispiel-Anfragen werden mit einem Befehl angelegt. Liefen zwei solche Befehle gleichzeitig für dieselbe Firma, konnte der zweite das Beispiel des ersten für „abgebrochen“ halten und ablehnen. Jetzt wartet der zweite Lauf, bis der erste fertig ist, und legt dann nur an, was noch fehlt. Dauert der erste länger als 20 Sekunden, bricht der zweite mit einer verständlichen Meldung ab.
Plan-Pflicht (SYSTEM.md §4)
Geändert
src/features/samples/repository.ts(neu):lockSeedRun,SeedRunBusy– transaktionsweite Advisory-Lock je Firma (pg_advisory_xact_lock,lock_timeoutlokal)src/features/samples/seed.ts,index.ts:seedSampleshält die Sperre in einer eigenen Transaktion über den ganzen Lauf;seedLockTimeoutMs(Standard 20 s – unter dem 30-s-statement_timeoutvon Pool und Rolle)src/seed-samples.ts: Pool mit 3 statt 2 Verbindungen (eine hält die Sperre)tests/integration/samples.test.ts: zwei gleichzeitige Läufe; zweiter Lauf bricht mitSeedRunBusyab, solange der erste hältdocs/technical/deployment-vercel.md§6,docs/technical/architecture.md,CHANGELOG.mdWarum transaktions- statt sitzungsweit: Der Showcase verbindet über den Supabase-Pooler (Transaktionsmodus). Eine Sitzungs-Sperre hinge dort an einer beliebigen Serververbindung. Eine offene Transaktion bindet ihre Verbindung dagegen bis zum Ende und gibt die Sperre auch frei, wenn der Prozess abbricht.
Nachweis (SYSTEM.md §11)
verify:changed: grün –tsc,eslint,depcruise(Exit 0), Unitsamples3/3verify: grün – CI-Lauf 36461740690 (Kopfb69bd3a): Unit 278/278, Integration 146/146 gegen Postgres + S3, darunter die zwei neuen chore(samples): serialize concurrent seed runs per company #93-Tests; depcruise, build, auditlockSeedRun(Probe-Commits, danach zurückgenommen) scheitern genau die zwei chore(samples): serialize concurrent seed runs per company #93-Tests in CI-Lauf 36461390392 (vier statt zwei Musterfälle; zweiter Lauf bricht nicht ab)verify:full/ E2E-Spec: nicht betroffen (kein Nutzerfluss)Doku-Entscheidung (genau eine)
deployment-vercel.md§6samples(Sperre je Firma)[Unreleased](sichtbares Feature oder Verhalten – im selben PR, nie „später"): Fixed-Eintrag chore(samples): serialize concurrent seed runs per company #93Entferntes oder Umbenanntes:
docs/+ README gegrept, Treffer bereinigt: nichts entferntDateigrößen und neue Bausteine (SYSTEM.md §7)
Dateien über 500 Zeilen im Diff (Ausnahmen: generierter Code, Lockfiles, Fixtures, Migrationen, Schemas, Ressourcen, Doku, Konfiguration):
Über 800 Zeilen mit neuer Fachlogik oder über 1000 Zeilen (P1/P2): nicht betroffen
Neue Shared-Komponente, Utility-Datei, Adapter oder fachlicher Service:
advisory,lockDuplicateDetection,lockRequest); gefunden:lockDuplicateDetection(transaktionsweite Advisory-Lock je Firma) – dasselbe Muster, eigener Schlüsselseed-samples:<company>imsamples-ModulSubagent-Einsätze
Risiken / offene Punkte
🤖 Generated with Claude Code