Major Refactoring: Interceptor Architecture & Iterator-based Responses
This PR introduces a significant architectural shift for Gorums, moving towards a more flexible, interceptor-based design and adopting modern Go iterator patterns. These changes simplify the codebase, improve type safety, and offer better composability for users.
🚀 Key Changes
1. Client-Side Interceptor Architecture
The core request/response logic has been refactored to use a composable interceptor pattern, similar to connectrpc.
-
QuorumFunc&Interceptor: Replaces the rigidQuorumSpecinterface. Users can now compose logic usingChainand standard interceptors. -
Unified Logic:
Multicast,Unicast, andQuorumCallnow share a more unified underlying implementation. - Lazy Execution: Requests are now dispatched lazily when response iteration begins (or explicitly triggered), allowing for more flexible setup.
2. Iterator-Based Response Handling (Results[T])
We have adopted a fluent, iterator-based API for handling responses, replacing the previous hardcoded callback/QuorumSpec approach.
-
Results[T]: A new type alias foriter.Seq[NodeResponse[T]]that serves as the receiver for helper methods. -
Fluent API: You can now chain methods for cleaner code:
// Before (Quorum logic hidden in QuorumSpec) // replies, err := config.Read(ctx, req) // After (Explicit control) replies, err := config.Read(ctx, req).Majority() -
Unified Node ID: The
NodeResponse[T]struct now contains theNodeID.
3. Template Overhaul & Simplification
The protoc-gen-gorums templates have been significantly simplified.
-
Removed
QuorumSpecGeneration: The complexQuorumSpecinterface generation has been removed. The runtime now handles this via genericQuorumCallimplementations. - Reduced Code Size: Generated code is now smaller and relies more on the simplified Gorums runtime.
4. Correctable Call Refactoring
Correctable calls have been split into two distinct types to improve clarity and type safety:
-
Correctable: For unary correctable calls (one request, progressive responses). -
CorrectableStream: For streaming correctable calls. This removes the ambiguousserverStreamboolean toggle and simplifies the generated code.
⚠️ Breaking Changes
-
QuorumSpecInterface Removed: The generatedQuorumSpecinterface is gone. Custom quorum logic should now be implemented using the newQuorumFuncorInterceptorpatterns, or by using the built-in aggregators (Majority,All,First). -
New Response pattern: Calls that previously returned a single aggregated value
(like
(*Response, error)) now return a*Responsesobject, requiring a terminal method call (like.Majority()) or iteration to retrieve the result.
📝 Migration Guide
Migrating from QuorumSpec
Calls that relied on QuorumSpec validation now require explicit aggregation or iteration.
Old (Implicit QuorumSpec logic):
// Quorum logic was defined in a separate QSpec struct
resp, err := config.Read(ctx, req)
if err != nil { ... }
New (Explicit Aggregation):
// Use built-in aggregators for standard patterns
resp, err := config.Read(ctx, req).Majority()
// OR use custom iteration for complex logic
for resp := range config.Read(ctx, req).Seq() {
// Process individual responses
if complexCheck(resp) { ... }
}
Here's the code health analysis summary for commits 691cd1b..2306fac. View details on DeepSource ↗.
Analysis Summary
| Analyzer | Status | Summary | Link |
|---|---|---|---|
| ✅ Success | 🎯 6 occurences resolved | View Check ↗ | |
| ✅ Success | View Check ↗ |
💡 If you’re a repository administrator, you can configure the quality gates from the settings.