deep-dives

19 posts

Deine Retry-Schleife geht davon aus, dass der erste Request fehlgeschlagen ist. Das hat er wahrscheinlich nicht.

Ein Timeout oder Crash bedeutet nicht, dass dein API-Request verloren ging. So machen Idempotency-Keys Retrys sicher – und das Storage-Pattern, das tatsächlich Duplikate verhindert.

Dein Service stürzt mitten in einem -Request ab. Der Client sieht einen Timeout und versucht es erneut. Du hast jetzt zwei Abbuchungen. Der Kunde ist sauer.…

Ein Lock, der den Prozess überlebt: Wie distributed Leases tatsächlich funktionieren

In-Memory-Mutexes verschwinden, wenn der Server neu startet. Hier erfährst du, wie distributed Leases mit Fencing Tokens und TTLs doppelte Arbeit über Crashes hinweg verhindern – und wo sie trotzdem versagen.

Dein überlebt kein . Er überlebt keinen OOM, kein Deployment-Rollout und keinen Node-Reboot. Sobald der Prozess beendet wird, ist der Lock weg. Wenn dieser…

Ein Circuit Breaker ohne Goroutines, ohne Timer und ohne Hintergrund-Overhead

Die meisten Circuit-Breaker-Bibliotheken starten Hintergrund-Threads, um die Wiederherstellung zu prüfen. Das brauchen Sie nicht. Hier ist ein request-getriebener Entwurf, der jeglichen Hintergrund-Overhead eliminiert – ohne Korrektheit zu opfern.

Jeder Circuit Breaker, den ich in Produktion geprüft habe, startet irgendwann einen Hintergrund-Thread. Das kann eine Go-Goroutine, ein Javaoder ein…

Dein Web-Service hat einen Graceful-Shutdown-Pfad. Das ist der Bug.

Crash-only-Software behandelt jeden Fehler als Crash und jeden Start als Recovery. Für Web-Services bedeutet das, die Shutdown-Logik zu löschen und einen Zustand zu entwerfen, der ein `kill -9` überlebt.

Dein Web-Service hat einen Shutdown-Handler. Er flushed Buffer, schließt Verbindungen, schreibt Checkpoints. Du hast ihn vielleicht einmal getestet. In…

Wie man einen überlebenden Mutanten killt, wenn man nicht versteht, was er geändert hat

Mutation Testing hat einen Überlebenden gefunden und du hast keine Ahnung, was die Mutation überhaupt macht. Hier ist eine Schritt-für-Schritt-Methode, um den richtigen Test zu schreiben, ohne den Mutanten zuerst zu verstehen.

Dein Mutation-Testing-Report ist voller Überlebender, und mindestens einer von ihnen ergibt für dich keinen Sinn. Das Tool sagt, es habe ein zu einem in Zeile…

Deine Tests laufen durch. Dein Mutation-Score liegt bei 40 %. Das ist es, was überlebende Mutanten dir wirklich sagen.

Code-Coverage sagt, du bist auf der sicheren Seite. Mutation-Testing sagt, deine Tests sind größtenteils Dekoration. So decken überlebende Mutanten die Lücke auf – und so schließt du sie.

Deine Tests laufen durch. Dein Coverage-Report zeigt 87 %. Aber dein Mutation-Score liegt bei 40 %, und die Hälfte deiner Mutanten lebt noch. Diese 40 %…

Mutation Testing in Rust funktioniert, aber deine Compile-Zeiten werden es hassen

cargo-mutants findet die Tests, die nur so tun, als würden sie deinen Code prüfen. Hier erfährst du, wie Mutation Testing in Rust funktioniert, was es findet und ob sich der Compile-Time-Aufwand lohnt.

Du hast 100% Line Coverage. Jeder Branch wird getroffen. Jede Funktion wird aufgerufen. Dann ändert jemand ein in ein in deiner Pricing-Logik, führt die Tests…

100 Testläufe sind eine Lüge: Wie du Property-Based Tests richtig dimensionierst

Die Standardanzahl von 100 Beispielen beim Property-Based Testing ist ein sozialer Kompromiss, keine statistische Strategie. So wählst du eine Anzahl an Läufen, die deinem Vertrauensbedürfnis und deinem CI-Budget entspricht.

Wenn du Property-Based Tests mit den Standard-100 Beispielen ausführst, bekommst du das Schlechteste aus beiden Welten. Deine CI ist langsamer als nötig, und…

Property-Based Tests in Rust finden die Bugs, die deine Unit Tests übersehen

Beispielbasiertes Testing deckt nur die Inputs ab, an die du gedacht hast. Property-Based Testing generiert zufällige Daten, prüft Invarianten und reduziert Fehler auf minimale Gegenbeispiele.

Du hast eine -Funktion geschrieben. Du hast sie mit und getestet. Sie besteht. Du veröffentlichst sie. Ein Nutzer übergibt einen Slice mit einem einzigen…

Rust-Runtime-Contracts können in Release-Builds kostenlos sein, aber der Compiler macht das nicht für dich

Rust entfernt Debug-Assertions automatisch, aber echtes Design-by-Contract braucht mehr als debug_assert!. So baust du zero-cost runtime contracts, die aus deinem Release-Binary verschwinden.

Rust kann runtime contracts in der Entwicklung erzwingen und sie komplett aus Release-Builds entfernen. Die Einschränkung ist, dass die Sprache contracts nicht…

Null, Eins oder Zwölf: Wie viele Assertions eine Funktion im Production-Code wirklich braucht

Entwickler verteilen Assertions entweder wie Konfetti oder meiden sie komplett. Hier ist das Entscheidungs-Framework, das nützliche Invariants von Production-Crash-Triggern unterscheidet.

Die meisten Production-Codebases gehören zu einem von zwei Lagern. Lager A behandelt als dekoratives Gewürz, streut es in jede zweite Zeile, bis die Funktion…