logo hsb.horse
← Zur Snippets-Übersicht

Snippets

Cache-First, Live-Fetch Orchestrierungsmuster

Orchestrierung, die einen schnellen Pfad aus dem Cache mit einem langsamen Pfad vom Remote-Dienst kombiniert. Misst Cache-Hits/Misses, Latenz und das Endergebnis als Metriken und delegiert Nebeneffekte nach außen.

Veröffentlicht: Aktualisiert:

Beim Kombinieren von Cache und Remote-Fetch neigt die Logik dazu, sich zu vermischen. Das Kapseln in einer Orchestrierungsfunktion trennt die Cache-Hit- und Cache-Miss-Pfade sauber und zentralisiert gleichzeitig die Metrikinstrumentierung und die Delegierung von Nebeneffekten.

Typdefinitionen

interface CacheProvider<T> {
get(key: string): Promise<T | undefined>;
set(key: string, value: T): Promise<void>;
}
interface RemoteProvider<T> {
fetch(key: string): Promise<T>;
}
interface MetricsReporter {
recordCacheHit(key: string, latencyMs: number): void;
recordCacheMiss(key: string): void;
recordFetchLatency(key: string, latencyMs: number): void;
recordOutcome(key: string, outcome: 'success' | 'error', latencyMs: number): void;
}

Orchestrierungsfunktion

async function orchestrate<T>(
key: string,
cache: CacheProvider<T>,
remote: RemoteProvider<T>,
metrics: MetricsReporter,
): Promise<T> {
const start = performance.now();
// Schneller Pfad: Cache-Hit
const cached = await cache.get(key);
if (cached !== undefined) {
metrics.recordCacheHit(key, performance.now() - start);
return cached;
}
// Langsamer Pfad: Live-Fetch
metrics.recordCacheMiss(key);
const fetchStart = performance.now();
try {
const data = await remote.fetch(key);
metrics.recordFetchLatency(key, performance.now() - fetchStart);
// Nebeneffekt nach außen delegiert — fire and forget
void cache.set(key, data);
metrics.recordOutcome(key, 'success', performance.now() - start);
return data;
} catch (error) {
metrics.recordOutcome(key, 'error', performance.now() - start);
throw error;
}
}

Verwendungsbeispiel

const result = await orchestrate(
'user:42',
redisCache,
userApiClient,
datadogMetrics,
);

Erläuterung

  • Schneller Pfad: Bei einem Cache-Treffer wird sofort zurückgegeben — der Remote-Dienst wird nie aufgerufen.
  • Langsamer Pfad: Fallback zum Remote-Dienst nur bei einem Cache-Miss. Nach dem Abrufen wird der Cache als Fire-and-Forget-Nebeneffekt aktualisiert.
  • Metriken: Cache-Hits, -Misses, Fetch-Latenz und das Endergebnis werden vollständig instrumentiert. Die Delegierung an MetricsReporter entkoppelt den Orchestrator von Datadog, Prometheus oder einem anderen Logging-Backend.
  • Nebeneffekt-Delegierung: Cache-Schreibvorgänge und Metrikaufrufe werden nach außen verlagert. Das macht die Orchestrierungsfunktion einfach testbar und erlaubt einen unkomplizierten Austausch der Implementierungen.

Anwendungsgebiete

Dieses Muster eignet sich besonders für:

  • Importer: Bereits verarbeitete Datensätze mit einer schnellen Cache-Prüfung überspringen, bevor die Quelle aufgerufen wird.
  • Datenanreicherungs-Jobs: Bereits vollständige Entitäten nicht erneut anreichern.
  • Synchronisierungs-Handler: Doppelte Abrufe verhindern und gleichzeitig Unterschiede mit Metriken verfolgen.
  • Aufwändige UI-Aktionen: Den Remote-Aufruf nur beim ersten Laden ausführen; nachfolgende Anfragen aus dem Cache bedienen.

Da CacheProvider, RemoteProvider und MetricsReporter als Interfaces definiert sind, kann jede Kombination von Implementierungen — Redis/in-memory, REST/gRPC, Datadog/StatsD — eingebunden werden, ohne die Orchestrierungslogik zu ändern.