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¶
Block¶
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: