Polycrate API 0.14.16
Polycrate API 0.14.16
Release-Datum: 19. März 2026
Typ: Hotfix
Highlights
- FTS Signal-Guard Fix – 0.14.15 reduzierte unnötige GIN-Rebuilds für
set_state()undadd_condition(), aber Dutzende weitere baresave()calls in Reconciliation-Pfaden (k8s/models.py,endpoints/models.py,s3/models.py, …) blieben unberührt; Tuple I/O blieb nach 0.14.15 unverändert bei ~750/5min
Artefakte
Docker Image
docker pull cargo.ayedo.cloud/polycrate/polycrate-api:0.14.16
Block
polycrate pull cargo.ayedo.cloud/ayedo/k8s/polycrate-api:0.9.13
polycrate run polycrate-api install
Fixes
FTS Signal-Guard: Invertierter Default
Ursache: Der Signal-Guard in signals.py hatte den Default semantisch falsch herum:
# Alt (kaputt): Guard greift nur wenn update_fields explizit gesetzt
if not created and update_fields is not None:
if not relevant: return
# → Bei update_fields=None (bare save): fällt immer durch → triggert immer
0.14.15 patchte set_state() und add_condition() auf save(update_fields=...). Die Codebase enthält aber noch Dutzende weitere bare save() calls in Reconciliation-Pfaden — allein in k8s/models.py an fünf Stellen in run_reconciliation(), _import_backups(), _reconcile_endpoints() u.a. Das schrittweise Patchen aller Call-Sites ist nicht wartbar.
Fix: Default invertiert — bare saves (update_fields=None) triggern per Default kein Re-Indexing:
# Neu: eine Zeile stoppt alle Reconciliation-Trigger auf einmal
if not created:
if update_fields is None:
return # bare save → skip
if not (set(update_fields) & search_relevant):
return
Semantik nach Fix:
| Ereignis | Verhalten |
|---|---|
Neues Objekt (created=True) |
✅ indexiert |
Bare save ohne update_fields (Reconciliation) |
✅ skip |
save(update_fields=["state"]) |
✅ skip (kein FTS-Feld) |
save(update_fields=["name"]) |
✅ indexiert |
Explizites Re-Indexing in perform_update() für API-Updates
DRF's serializer.save() ist ebenfalls ein bare save ohne update_fields. Mit dem invertierten Guard würden API-Updates (User ändert Name, Beschreibung, Labels) den Search Index nicht mehr aktualisieren.
Fix: perform_update() dispatcht update_search_index_task explizit nach jedem API-Update:
# views.py — ManagedObjectViewSet.perform_update()
update_search_index_task.delay(str(instance.id), instance.__class__.__name__)
API-Updates sind seltene User-Interaktionen (kein Loop), der Overhead ist vernachlässigbar.
Nach dem Deployment
Nach dem Deployment empfiehlt sich — sofern nicht bereits nach 0.14.15 geschehen — ein manuelles VACUUM ANALYZE auf der SearchIndex-Tabelle:
ALTER TABLE polycrate_api_searchindex SET (
autovacuum_vacuum_scale_factor = 0.02,
autovacuum_analyze_scale_factor = 0.01,
autovacuum_vacuum_cost_delay = 2
);
VACUUM ANALYZE polycrate_api_searchindex;