Fault tolerance and resilience patterns for Go
A new Go library, failsafe-go, brings patterns like retries, circuit breakers and resilience policies—well known from Java’s Failsafe and .NET’s Polly—into the Go ecosystem to improve fault tolerance in distributed systems. Commenters debate how far such libraries can go without persistent queues or external infrastructure, and whether they risk over-engineering or misconfiguration in real-world deployments. The release also reignites broader arguments about Go’s design trade-offs (simplicity vs. features like nullable types, richer enums, and exceptions) and how its approach compares to runtimes like Erlang/Elixir’s OTP and platforms such as Kubernetes.
Fault-tolerance libraries and patterns
- The linked Go library is seen as a port of existing ideas: from a mature Java version of the same project and strongly resembling the .NET Polly library.
- Some praise having these resilience patterns (retries, circuit breakers, etc.) in Go; others warn they’re often misused, causing more outages (e.g., over-aggressive circuit breakers in internal services).
- One commenter notes the library is in-memory only; true “fail-safe” behavior often requires persistent queues or logs, though not all systems can tolerate that latency or complexity.
Go’s design goals and evolving feature set
- Debate over whether Go was intentionally designed for relatively inexperienced engineers at large companies, emphasizing simplicity and fast onboarding.
- Some argue adding more features (generics, better enums, nullability) risks turning Go into a worse Java; others say languages must evolve to remain useful.
- Generics’ late arrival (after ~12–13 years) is framed both as a strength (conservative, theoretically grounded design) and as a missed opportunity, given earlier generics in other languages.
Nil, nullable types, and error handling
- Frequent nil pointer panics are described as a real pain point; some call the lack of non-nullable types a design flaw.
- Others counter that pointers already act as nullable types and nil issues usually signal architectural or discipline problems.
- Patterns suggested: factory functions, strict error checking (
errcheck), never using a value when an error is present. - Several argue this manual style is an implicit, verbose reimplementation of exceptions; others respond that ease of bubbling errors (exceptions) encourages deferring real handling.
- References to C#, Rust (
Option), and tools like NilAway illustrate alternative approaches to null-safety.
Enums, type systems, and “Go-like” style
- Disagreement over whether Go’s
iota-based constants are “real” enums; critics say they’re weak compared to classic enum constructs or sum types. - Broader view: many modern languages prefer sum types over traditional enums; Go intentionally keeps an “antiquated” feel.
OTP, Erlang/Elixir, and Kubernetes
- Many note Go libraries and cloud tooling (e.g., resilience patterns, microservices, Kubernetes) resemble concepts long present in Erlang/Elixir’s OTP.
- Some see K8s as a language-agnostic replacement that “does OTP better”; others call it a “poor man’s OTP.”
- Reasons OTP/BEAM isn’t more widely used despite its strengths: dynamic typing, unusual syntax, weaker performance for some workloads, small ecosystem, and hiring/learning friction.
- Counterpoint: teams report success with Erlang/Elixir in production, but acknowledge ecosystem gaps and limited adoption compared to Go, Java, etc.
API design critique of failsafe-go
- A few commenters feel the library’s heavy use of generics and many small packages “don’t feel like Go” and are over-engineered.
- The author defends the design as enabling strong type safety and composability, while another compares it to a simpler state-machine approach.