Per-Actor-Policies
Das Object-Storage-Backend kann Store-Level-Defaults für Kompression + Verschlüsselung haben. Aber manchmal brauchen bestimmte Actors andere Einstellungen:
- Ein sensibler Actor braucht Verschlüsselung (andere nicht).
- Ein Actor mit großem State profitiert von hohem zstd-Level (andere verwenden gzip).
- Ein Actor mit kleinem State verzichtet auf Kompression.
Überschreibe pro Actor, indem du die Methoden compression() /
encryption() implementierst:
class SensitiveActor extends DurableStateActor<Cmd, State> { protected encryption() { return { keyRing: sensitiveKeyRing }; }
protected compression() { return { algorithm: 'gzip' as const, level: 9 }; }}Das Framework ruft diese bei jedem Persist/Load auf und wendet die zurückgegebene Config an.
Default vs. Override
Abschnitt betitelt „Default vs. Override“// Store-Level-Config — gilt für jeden Actor, sofern nicht überschrieben:const store = new ObjectStorageDurableStateStore({ backend, compression: { algorithm: 'gzip', level: 6 }, encryption: { keyRing: defaultKeyRing },});
// Per-Actor: Overrideclass MyActor extends DurableStateActor<...> { protected compression() { return { algorithm: 'none' as const }; } // encryption() nicht überschrieben → verwendet defaultKeyRing}Jede Methode ist unabhängig überschreibbar:
- Eigene Config zurückgeben → diese Config gilt.
- Nicht überschreiben → Default des Stores gilt.
undefinedaus der Methode zurückgeben → ebenfalls Default des Stores.
Use Cases
Abschnitt betitelt „Use Cases“Per-Actor-Verschlüsselung
Abschnitt betitelt „Per-Actor-Verschlüsselung“class CreditCardActor extends DurableStateActor<...> { protected encryption() { return { keyRing: pciKeyRing }; // separater Key Ring für PCI-Scope }}
class GenericActor extends DurableStateActor<...> { // Kein Override → verwendet Store-Default (keine Verschlüsselung oder generischer keyRing)}PCI / HIPAA / GDPR-Scope: als sensibel klassifizierte Daten verwenden einen separaten Master-Key von nicht-sensiblen. Kompromittierung eines keyRings exponiert den anderen nicht.
Per-Actor-Kompression
Abschnitt betitelt „Per-Actor-Kompression“class ChatTranscriptActor extends DurableStateActor<...> { // Großer Text-State — hohes zstd-Level gewinnt deutlich protected compression() { return { algorithm: 'zstd' as const, level: 19 }; }}
class CounterActor extends DurableStateActor<...> { // Winziger State — Kompressions-Overhead übersteigt Einsparungen protected compression() { return { algorithm: 'none' as const }; }}Passe die Kompression an die Datenform an. Default gzip ist ein sicherer Mittelweg; Per-Actor-Tuning holt mehr raus.
Was beim Persist passiert
Abschnitt betitelt „Was beim Persist passiert“DurableStateActor.persist(state) ↓serializer.toBinary(state) → JSON- oder CBOR-Bytes ↓this.compression() → angewendet, wenn nicht 'none' ↓this.encryption() → angewendet, wenn gesetzt ↓backend.put(key, ciphertext, opts)Das Framework schaut bei jedem Persist die Overrides des Actors nach — selbst wenn du die Override-Werte dynamisch änderst (selten), verwenden neue Writes neue Einstellungen.
Was beim Load passiert
Abschnitt betitelt „Was beim Load passiert“DurableStateActor.preStart ↓backend.get(key) → Bytes + Metadaten ↓Verschlüsselung aus Metadaten erkennen (key-id) → entschlüsseln ↓Kompression aus Metadaten erkennen (Content-Encoding) → dekomprimieren ↓serializer.fromBinary → StateReads verwenden die mit dem Objekt gespeicherten Metadaten,
nicht die aktuellen Overrides des Actors. Ein unter pciKeyRing
verschlüsseltes Objekt wird über pciKeyRing entschlüsselt,
egal ob das aktuelle encryption() des Actors das sagt oder
nicht.
Das bedeutet: das Rotieren einer Actor-Policy bricht alte Daten nicht, solange die notwendigen Keys / Algorithmen verfügbar sind.
Migration beim Ändern von Policies
Abschnitt betitelt „Migration beim Ändern von Policies“// Alt: keine Verschlüsselung.// Neu: Verschlüsselung unter pciKeyRing.class CreditCardActor extends DurableStateActor<...> { protected encryption() { return { keyRing: pciKeyRing }; }}Alte (unverschlüsselte) Reads funktionieren — keine Metadaten → Plaintext-Pfad. Neue Writes verschlüsseln. Schließlich:
- Ein Re-Encryption-Sweep, gefiltert auf die persistenceIds dieses Actors, migriert den Rest.
Siehe Schlüsselrotation.
Mit dem Snapshot-Store arbeiten
Abschnitt betitelt „Mit dem Snapshot-Store arbeiten“class Account extends PersistentActor<Cmd, Event, State> { // Per-Actor-Kompression für Snapshots: protected compression() { return { algorithm: 'zstd' as const }; }
// Per-Actor-Verschlüsselung für Snapshots: protected encryption() { return { keyRing: accountKeyRing }; }}Gleiche Methoden gelten, wenn der Snapshot-Store durch Object Storage gestützt wird. Persistent Actors und Durable State Actors honorieren beide.
Wie geht’s weiter
Abschnitt betitelt „Wie geht’s weiter“- Object Storage im Überblick — das größere Bild.
- Kompression — Algorithmus- + Level-Details.
- Verschlüsselung — Verschlüsselungs-Setup.
- Snapshot-Store-Backend — für Snapshots in Object Storage.