feat: rewrite durablestream store using conformance-tested client#48
Conversation
- Add 🌍 Remote storage feature to README - Add Remote Storage section with durable-streams example - Add Storage Backends table documenting all available options - Update StoredEvent structure to use Offset type instead of Position - Add SQLite and Durable-Streams store usage examples - Update EventStore interface to new Append/Read signatures - Add SubscriptionStore and EventStoreStreamer interfaces - Update all replay examples to use eventbus.OffsetOldest Closes #42 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add reference to Electric's announcement blog post explaining the Durable Streams protocol specification. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update link to point to the official durable-streams organization repository instead of the fork. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace custom HTTP client with ahimsalabs/durable-streams-go - a conformance-tested Go client library that passes the official durable-streams test suite. Changes: - Create standalone module with go.mod (like sqlite store) - Use ahimsalabs/durable-streams-go for protocol compliance - Remove custom client.go and export_test.go - Simplify options (remove retry config, handled by client library) - Update API: New(baseURL, streamPath, opts...) for clearer separation - Maintain 100% test coverage using ahimsalabs in-memory handler - Compatible with any durable-streams server implementation - Update README and PERSISTENCE docs with new API Breaking changes: - New() signature changed from New(streamURL) to New(baseURL, streamPath) - WithRetry() option removed (client handles retries internally) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code Review: Durable-Streams Store RewriteSummaryThis PR replaces the custom durable-streams HTTP client with the conformance-tested ahimsalabs/durable-streams-go library. This is a significant improvement that ensures protocol compliance and reduces maintenance burden. ✅ Strengths1. Excellent Architectural Decision
2. Comprehensive Test Coverage
3. Clean API Design
4. Error Handling
🔍 Code Quality Observations1. Synthetic Offsets Pattern (stores/durablestream/store.go:168-176)The synthetic offset generation is clever but has a critical limitation that's properly documented: // Synthesize unique offset: "nextOffset/index"
// These are ephemeral - use nextOffset for reliable resumption
eventOffset = eventbus.Offset(fmt.Sprintf("%s/%d", result.NextOffset, i))Observation: This is well-documented in comments, but the limitation is significant:
Recommendation: Consider adding a runtime warning or panic if synthetic offsets are used with 2. Missing SubscriptionStore ImplementationThe store implements
Question: Is this intentional? The PR description mentions "Maintain 100% test coverage" but doesn't address subscription tracking. Should this store also implement 3. Timestamp Handling (stores/durablestream/store.go:199-210)The func parseTimestamp(s string) time.Time {
if s == "" {
return time.Time{}
}
t, err := time.Parse(time.RFC3339Nano, s)
if err != nil {
return time.Time{} // Silent failure
}
return t
}Observation: While there's a test for invalid timestamps, the silent failure might mask data issues. Recommendation: Consider logging invalid timestamps when 4. Context.Background() in New() (stores/durablestream/store.go:43)func New(baseURL string, streamPath string, opts ...Option) (*Store, error) {
return NewWithContext(context.Background(), baseURL, streamPath, opts...)
}Observation: Using Good: The comment documents this and provides Consideration: In production, stream creation might involve network calls that could hang. Users should prefer 🛡️ Security & PerformanceSecurity: ✅ No Concerns
Performance: ✅ Generally GoodStrengths:
Minor Consideration:
📝 Best Practices AdherenceFollows Go Idioms: ✅
Documentation: ✅ Excellent
🧪 TestingCoverage: Based on the test file, coverage should be ~100%The tests cover:
Recommendation: Before merging, run: cd stores/durablestream && go test -coverprofile=coverage.out ./... && go tool cover -func=coverage.outVerify 100% coverage as mentioned in CLAUDE.md. 🚨 Breaking Changes: Well DocumentedThe PR clearly documents breaking changes:
Both are reasonable and well-communicated. 📋 RecommendationsHigh Priority
Medium Priority
Low Priority (Nice to Have)
✅ VerdictApprove with minor suggestions. This is a well-executed refactoring that:
The code is production-ready. The main question is around Recommendation: Merge after:
Great work on this refactoring! 🎉 |
Summary
Replace our custom HTTP client implementation with ahimsalabs/durable-streams-go - a conformance-tested Go client library that passes the official durable-streams test suite.
Why this change?
Changes
New(baseURL, streamPath, opts...)for clearer separationBreaking Changes
New()signature changed fromNew(streamURL)toNew(baseURL, streamPath)WithRetry()option removed (client handles retries internally)Test plan
🤖 Generated with Claude Code