FDN-04: job-queue & worker-runtime
Postgres-Jobqueue (processing_jobs, FOR UPDATE SKIP LOCKED), In-Prozess- Worker-Goroutinen, kein Redis/AMQP. Enqueue mit Idempotency-Key-Dedup, Dequeue mit Stale-Lock-Wiedervorlage (Absturzsicherheit), Fail mit arithmetischem Backoff und Dead-Letter-Queue nach erschoepften Versuchen, RequeueDeadLetter fuer manuelle Wiederholung. Auf 192.168.1.131 verifiziert: Absturz-Wiedervorlage (Job von einem "abgestuerzten" Worker nie completed/failed, zweiter Worker holt ihn nach Ablauf der Sperre erneut), Idempotenz bei Doppelzustellung (gleicher idempotency_key erzeugt nur 1 Zeile), DLQ-Eintrag manuell wiederholbar. Vier reale Fehler beim Testen gefunden und behoben: zwei pgx-Typinferenz- Bugs im SQL-Parameterhandling (toter workerID-Parameter ohne Referenz in der Query; untypisiertes any statt []string fuer den ::text[]-Cast), sowie zwei Testinfrastruktur-Bugs (dms_tenant_test sammelte schema_migrations- Zustand ueber Sitzungen hinweg an, jobqueue-Testfixture raeumte processing_jobs nicht auf) - neues scripts/reset-test-env.sh + make check (-p 1) analog Core behoben. Siehe dms/docs/FDN-04-PRUEFPROTOKOLL.md fuer alle Pruefungsergebnisse. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
a9ede93176
commit
bfea94b032
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS processing_jobs;
|
||||
@@ -0,0 +1,30 @@
|
||||
-- FDN-04: Postgres-Jobqueue fuer asynchrone Verarbeitung (OCR, Konvertierung,
|
||||
-- Indexierung, Exporte) — kein Redis/AMQP, dasselbe Muster wie das
|
||||
-- projektweite Postgres-Jobqueue-Konzept (siehe SKALIERUNGSKONZEPT.md).
|
||||
-- Laeuft in der DB EINES Mandanten (Modell C, siehe Core TEN-01).
|
||||
CREATE TABLE processing_jobs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
job_type TEXT NOT NULL,
|
||||
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
-- idempotency_key verhindert doppelte Einreihung DERSELBEN logischen
|
||||
-- Aufgabe (z.B. "ocr:<revision_id>") — NULL erlaubt mehrere Zeilen ohne
|
||||
-- Dedup-Anspruch (Standard-Postgres-Verhalten: NULL ist nie gleich NULL
|
||||
-- im UNIQUE-Index).
|
||||
idempotency_key TEXT UNIQUE,
|
||||
status TEXT NOT NULL DEFAULT 'pending'
|
||||
CHECK (status IN ('pending', 'processing', 'succeeded', 'failed', 'dead_letter')),
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
max_attempts INT NOT NULL DEFAULT 5,
|
||||
available_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
locked_at TIMESTAMPTZ,
|
||||
locked_by TEXT,
|
||||
last_error TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Deckt genau die Zugriffsmuster von Dequeue (status+available_at) und der
|
||||
-- Stale-Lock-Wiedervorlage (status+locked_at) ab.
|
||||
CREATE INDEX idx_processing_jobs_pending ON processing_jobs (available_at) WHERE status = 'pending';
|
||||
CREATE INDEX idx_processing_jobs_processing ON processing_jobs (locked_at) WHERE status = 'processing';
|
||||
CREATE INDEX idx_processing_jobs_job_type ON processing_jobs (job_type);
|
||||
Reference in New Issue
Block a user