perf: optimize import persistence for 0.3.14
deploy / deploy (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-29 18:56:11 +02:00
parent 0d953173a8
commit cbd7220d8d
23 changed files with 1262 additions and 46 deletions
+30
View File
@@ -2329,3 +2329,33 @@ tasks:
note: Release 0.3.13 professionaliseert responsive layout, mobiele gastflow, begrensde vacature-UX, verplichte
zes-viewport-Playwrightgate zonder skips, echte runtimeheartbeat, parserbenchmark, authdekking, SBOM en integrale
documentatie; volledige gate 312 tests groen, 84,16% dekking.
- id: VR-228
title: Optimaliseer de importpipeline voor release 0.3.14
status: ready
priority: P0
requirement_ids:
- NFR-007
- NFR-008
- NFR-009
depends_on:
- VR-227
summary: Profileer de PostgreSQL-import reproduceerbaar, verwijder aantoonbare N+1- en overbodige writes en lever
de geverifieerde optimalisatie veilig op zonder wijziging aan deduplicatie, scoring of datakwaliteit.
acceptance_criteria:
- Een fail-closed runner meet een disposable PostgreSQL-database met vaste fixture, warm-up en drie herhalingen.
- De geoptimaliseerde import reduceert queryvolume en doorlooptijd aantoonbaar tegenover 0.3.13 en rapporteert
p50, p95, throughput, geheugen en queryfamilies.
- Parserdekking blijft 12/12, dedupeprecision en -recall blijven 1,0, rankingchurn blijft nul en historische
ScoreRuns plus veldprovenance blijven intact.
- Regressietests begrenzen het queryvolume; de volledige kwaliteitsgate slaagt tweemaal en productieacceptatie
bewijst health, beperkte importsmoke, publieke kernflows en rollbackgereedheid.
verification:
- python -m scripts.benchmark_import --jobs 250 --iterations 3
- uv run pytest tests/integration/test_pipeline.py tests/unit/test_import_benchmark.py
- ./scripts/codex_verify.sh
primary_paths:
- apps/jobs/services/pipeline.py
- scripts/benchmark.py
- scripts/benchmark_import.py
- tests/integration/test_pipeline.py
- docs/audit/IMPORT_PERFORMANCE_FINAL.md
+14
View File
@@ -0,0 +1,14 @@
# Importperformancebaseline 0.3.13
Gemeten op 2026-07-29 in een disposable PostgreSQL-database op Unraid (Linux 6.12.54, Python 3.13.14, 20 CPU's). De vaste fixture bevat 250 geldige HTML-documenten met dezelfde externe vacature-identiteit: één create en 249 idempotente duplicate-updates. Concurrency is bewust 1; netwerk, Celery, Ollama en mail zijn uit de meting gehouden.
| Metriek | 0.3.13 |
|---|---:|
| Importduur | 16.358,158 ms |
| p50 per document | 63,034 ms |
| p95 per document | 79,871 ms |
| Throughput | 15,283 documenten/s |
| Importqueries | >9.000 (loggerlimiet bereikt) |
| Piekgeheugen | 26,582 MB |
Correctheidsankers: parserdekking 12/12, dedupeprecision 1,0, deduperecall 1,0 en rankingchurn 0. De overschrijding van 9.000 queries is als ondergrens gerapporteerd, niet als exact getal.
+14
View File
@@ -0,0 +1,14 @@
# Finale importperformancemeting 0.3.14
De officiële runner gebruikt een database met verplichte prefix `vacatureradar_bench_`, weigert SQLite, externe databasehosts en publieke productiedomeinen, migreert en flusht de disposable database, voert één warm-up uit en meet daarna drie iteraties van 250 documenten. Het machineleesbare bewijs staat in `artifacts/import-performance-report.json`.
| Metriek | 0.3.13 | 0.3.14 gemiddeld | Verbetering |
|---|---:|---:|---:|
| Importduur | 16.358,158 ms | 9.040,123 ms | 44,74% lager |
| p50 | 63,034 ms | 32,900 ms | 47,80% lager |
| p95 | 79,871 ms | 52,296 ms | 34,53% lager |
| Throughput | 15,283/s | 28,031/s | 83,42% hoger |
| Importqueries | >9.000 | 3.264 | minstens 63,73% lager |
| Piekgeheugen | 26,582 MB | 18,799 MB | 29,28% lager |
Alle drie iteraties zijn gelijk voor queryvolume en queryfamilies. De kwaliteitsankers bleven parser 12/12, precision 1,0, recall 1,0 en rankingchurn 0. De fixture resulteert per iteratie in één vacature, één versie, behouden veldprovenance, 250 historische ScoreRuns en 249 idempotente duplicates.
@@ -0,0 +1,10 @@
# Importperformancetraceability
| Acceptatie | Implementatie | Bewijs |
|---|---|---|
| Veilige isolatie | `scripts/benchmark_import.py`, `scripts/run_import_benchmark.sh` | negatieve identitytests en disposable PostgreSQL-run |
| Meetbare reductie | run-local caches, gebundelde provenance en score-snapshotcopy | baseline/finaal rapport en machine-JSON |
| Geen functionele regressie | bestaande dedupe/scoringregels ongewijzigd | pipeline-, dedupe- en benchmarktests |
| Historiek en provenance | scorecopy per import, evidence bulk sync | integratietest met 20 herhaalde documenten |
| Queryregressie voorkomen | execute-wrapper en budgettest | stabiel 3.264 queries per 250; minder dan 300 per 20 in test |
| Releasekwaliteit | VR-228, gates, acceptance en operationsdocs | `docs/ai/PROJECT_STATE.md` en `FINAL_ACCEPTANCE.md` |
+12
View File
@@ -0,0 +1,12 @@
# Importqueryanalyse 0.3.14
De hot path liep van `process_raw_document` via parsing en `persist_draft` naar employer-resolutie, deduplicatie, alias/provenance, versiebeheer en scoring. Profiling wees vier dominante oorzaken aan:
1. Dezelfde werkgever en actieve profielen werden voor elk document opnieuw opgehaald.
2. Veldprovenance gebruikte per veld een afzonderlijke `update_or_create`.
3. Een inhoudelijk ongewijzigde waarneming schreef opnieuw een versie en berekende alle scores volledig.
4. `last_changed` verschoof ten onrechte bij alleen een nieuwe `last_seen`-waarneming.
De oplossing blijft binnen de modulaire monoliet en transacties: een import-run krijgt een lokale `PersistenceContext`, provenance wordt per alias gelezen en gebundeld geschreven, versies ontstaan alleen bij inhoudelijke wijziging en een ongewijzigde job kopieert het laatste ongewijzigde scoresnapshot. Daardoor blijft iedere `ScoreRun` historisch aanwezig, terwijl deterministische scoring niet opnieuw wordt uitgevoerd. De cache leeft nooit buiten één seriële import-run en verandert workerisolatie of deduplicatieregels niet.
De database-executieteller rapporteert per 250 items exact: 1.256 SELECT, 1.003 INSERT, 499 UPDATE, 253 SAVEPOINT en 253 RELEASE; totaal 3.264 importexecuties. De drie officiële iteraties geven identieke queryfamilies.
+4
View File
@@ -1,5 +1,9 @@
# Performanceaudit 2026-07-29
## Importoptimalisatie 0.3.14
De eerder geregistreerde importhotspot is opgelost en reproduceerbaar gemeten in een disposable PostgreSQL-database. Tegenover de 0.3.13-baseline daalt de gemiddelde 250-itemimport van 16.358,158 naar 9.040,123 ms; p95 daalt van 79,871 naar 52,296 ms en queryvolume van meer dan 9.000 naar exact 3.264. Zie `IMPORT_PERFORMANCE_BASELINE.md`, `IMPORT_QUERY_ANALYSIS.md` en `IMPORT_PERFORMANCE_FINAL.md`.
## Baseline
- Lokale quickbenchmark: 250 invoeritems op Windows 11, Python 3.13, 16 CPU-threads.
+1
View File
@@ -16,3 +16,4 @@
| Back-up/restore | custom dump, media en runbook | geïsoleerde restore, exacte tellingen en aparte applicatiestart | implemented and live verified |
| Rollback | immutable vorige en huidige imagetags | oude image healthy, daarna 0.3.13 opnieuw healthy | implemented and live verified |
| Externe identity/mail | versleutelde configuratieboundary | `USER_INPUT_REQUIRED.md` | optional external action |
| Importperformance 0.3.14 | run-lokale caches, evidence bulk sync en scorecopy | geïsoleerde 3-run PostgreSQL-meting en regressietests | implemented and verified |
+1
View File
@@ -84,6 +84,7 @@ Legenda: **I** = geïmplementeerd en getest in de huidige MVP; **P** = gedeeltel
Iedere backlogtaak die een requirement wijzigt, werkt in dezelfde commit deze matrix, relevante acceptatiecriteria en tests bij. Een status wordt alleen naar **I** gezet wanneer de code én het genoemde bewijs bestaan.
## Aanvullende traceability-opmerking
- VR-228 levert release 0.3.14 met een fail-closed disposable PostgreSQL-benchmark, run-lokale importcaches, gebundelde veldprovenance en ongewijzigde score-snapshotcopy. De officiële drie iteraties bewijzen 3.264 queries per 250 items, parser 12/12, dedupeprecision/recall 1,0 en nul rankingchurn; bewijs staat in `docs/audit/IMPORT_PERFORMANCE_*.md` en het machineleesbare artifact.
- VR-227 professionaliseert release 0.3.13 integraal: gecentreerd ultrawideframe, mobiele gastbanner en verticale pipeline, begrensde vacaturepaginering, verplichte zes-viewport-Playwrightgate zonder skips, echte runtimeheartbeat, volledige generieke parserbenchmark en SBOM-generatie. Bewijs staat in `docs/audit/`, de E2E-/auth-/runtime-/adaptertests en `USER_INPUT_REQUIRED.md`.
- VR-102 is gerealiseerd met auditbare policyreviews (`SourcePolicyReview`), robotscache met TTL/size/SSRF-controles en fail-closed policy-gating op verlopen of conflicterende reviews.
- VR-107 is gerealiseerd met `apps/sources/views.py`, `apps/sources/services/manual_import.py`, `templates/sources/list.html`, `static/js/manual_import.js` en bijhorende unit/integration-tests.
+5
View File
@@ -0,0 +1,5 @@
# VacatureRadar 0.3.14
Deze release versnelt herhaalde vacature-imports zonder deduplicatie, scoring of gebruikersdata te veranderen. Een geïsoleerde PostgreSQL-benchmark bewijst 44,74% kortere importduur, minstens 63,73% minder databasequeries en 83,42% hogere throughput tegenover 0.3.13. De runner, regressiebudgetten en queryfamilierapportage maken deze winst reproduceerbaar.
Upgrade vereist geen schemawijziging. Voer zoals altijd `migrate --noinput` uit; rollback kan naar de bewaarde immutable 0.3.13-image zonder dataconversie.