Zum Inhalt

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() und add_condition(), aber Dutzende weitere bare save() 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;