← Alle Projekte
Highlight Open Source 2026

super_cache

Produktionsreifer LRU- und TTL-Cache für Flutter und Dart, mit mehrschichtiger Speicherung und Schutz vor Mehrfachanfragen.

Eine Cache-Bibliothek für Flutter und Dart, die doppelte API-Aufrufe verhindert, in O(1) verdrängt und die Trefferquote live ausgibt. Der Kern kommt ohne externe Abhängigkeiten aus.

#dart#flutter#caching#lru#open-source#pub-dev

super_cache ist eine Cache-Bibliothek für Flutter und Dart, veröffentlicht auf pub.dev unter MIT. Der Kern hat keine externen Abhängigkeiten und läuft unter Android, iOS, Web, macOS, Windows und Linux.

Sie entstand aus einem konkreten Problem: Drei Widgets, die im selben Moment denselben Nutzer anfordern, lösen drei identische Netzwerkaufrufe aus. super_cache bündelt sie zu einem. Ein Schlüssel, der bereits unterwegs ist, bedeutet eine Anfrage, und alle Aufrufer warten auf dasselbe Future.

Darum herum liegen ein LRU in O(1) mit TTL, drei Cache-Schichten, die Einträge bei einem Treffer nach oben befördern, und Metriken, die sich zur Laufzeit ablesen lassen.

Hauptfunktionen

LRU in O(1) mit TTL

Eine Hash-Map zusammen mit einer doppelt verketteten Liste hält get, put und Verdrängung unabhängig von der Größe bei konstanter Zeit. TTL arbeitet pro Eintrag absolut oder gleitend, sodass ein Sitzungstoken und eine Produktliste im selben Cache nach unterschiedlichen Regeln ablaufen können.

Schutz vor Mehrfachanfragen

Gleichzeitige Lesezugriffe auf einen bereits laufenden Schlüssel teilen sich ein Future, statt jeweils eine eigene Anfrage zu stellen. Drei gleichzeitig eingehängte Widgets erzeugen einen Netzwerkaufruf.

Drei Schichten mit Beförderung

Arbeitsspeicher, ein mit AES-256-GCM verschlüsselter Puffer und Festplattenspeicher mit einer Datei pro Eintrag. Ein Treffer auf der Platte befördert den Eintrag nach oben, der zweite Zugriff ist damit ein Speicherzugriff.

Strategien pro Aufrufstelle

CacheAside liest verzögert, WriteThrough holt immer frische Daten, und RefreshAhead liefert den veralteten Wert, während im Hintergrund aktualisiert wird. Die Strategie ist ein Argument, keine globale Einstellung.

Beobachtbare Metriken

Trefferquote, Anzahl der Verdrängungen und Anzahl der Einträge gibt es als Momentaufnahme oder als Broadcast-Stream. Das Cache-Verhalten lässt sich damit zur Laufzeit beobachten, statt es aus Netzwerkprotokollen abzuleiten.

Deterministische Tests

Ein Begleitpaket liefert FakeCache und ManualClock, sodass TTL-Ablauf und Verdrängung geprüft werden können, ohne die Testsuite schlafen zu legen.

Tech-Stack

DartFlutterLRUTTLAES-256-GCM

Architektur

Drei Schichten liegen hinter einem einzigen Orchestrator. L1 ist ein LRU im Arbeitsspeicher, bei einem Treffer synchron. L2 ist ein mit AES-256-GCM verschlüsselter Puffer im Speicher. L3 ist Festplattenspeicher mit einer Datei pro Eintrag und Integritätsprüfung. Ein Lesezugriff fällt von L1 über L2 nach L3 durch und befördert das Gefundene wieder nach oben, sodass wiederholte Zugriffe im Speicher landen.

Die API liefert FutureOr<V?> statt immer ein Future. Ein L1-Treffer löst synchron auf und gibt die Kontrolle nie an die Event-Loop ab. Genau das hält einen Speicherzugriff bei etwa 0,04 Mikrosekunden, statt für einen bereits vorliegenden Wert einen asynchronen Sprung zu bezahlen.

Die Verdrängung lässt sich über die Anzahl der Einträge steuern oder, mit einem sizeEstimator, über Bytes. Ein evictFraction()-Haken erlaubt es außerdem, einen Teil des Caches freizugeben, wenn die Plattform Speicherdruck meldet, statt auf die Beendigung zu warten.

Das Kernpaket hängt von nichts außerhalb des SDK ab. Verschlüsselung, Festplattenpersistenz und Test-Doubles liegen in eigenen Begleitpaketen, sodass eine App, die nur einen LRU im Speicher braucht, flutter_secure_storage nicht mitzieht.

Herausforderungen & Lösungen

Die schwierigen Probleme, und wie ich sie gelöst habe.

01

Einen Speichertreffer aus der Event-Loop heraushalten

Jeden Lesezugriff als Future zu gestalten ist der naheliegende Entwurf und kostet bei Werten, die bereits im Speicher liegen, einen Durchlauf durch die Event-Loop. FutureOr zurückzugeben lässt einen L1-Treffer synchron auflösen: gemessen 0,04 Mikrosekunden pro Lesezugriff gegenüber 0,22, sobald der Orchestrator eine asynchrone Schicht hinzufügt. Der Preis ist ein etwas sperrigerer Typ an den Aufrufstellen, den das Repository-Mixin verbirgt.
02

Ehrlich bleiben, was die verschlüsselte Schicht schützt

SecureCache verschlüsselt Werte im Ruhezustand im Speicher, entschlüsselte Werte liegen aber weiterhin im Prozess. Das sichere Speicherung zu nennen wäre eine falsche Behauptung, deshalb sagt die Dokumentation klar, dass es kein Schutz durch eine Hardware-Enklave ist. Die README nennt außerdem die Fälle, in denen das Paket das falsche Werkzeug ist: weniger als fünf Werte, Zugriff über mehrere Isolates, oder Objekte über 50 MB, wo eine lokale Datenbank die bessere Antwort ist.

Interesse an einer Zusammenarbeit?

Ich bin immer offen für Gespräche über neue Projekte und Möglichkeiten.