fix(store): Implement version cache invalidation strategy for JetStreamEventStore
Implements cache invalidation on GetLatestVersion when external writers modify the JetStream stream. The strategy ensures consistency in multi-store scenarios while maintaining performance for the single-writer case. Changes: - Add cache invalidation logic to GetLatestVersion() that detects stale cache - Document version cache behavior in JetStreamEventStore struct comment - Add detailed documentation in CLAUDE.md about cache invalidation strategy - Add TestJetStreamEventStore_CacheInvalidationOnExternalWrite integration test - Cache is invalidated by deleting entry, forcing fresh fetch on next check The implementation follows the acceptance criteria by: 1. Documenting the single-writer assumption in code comments 2. Implementing cache invalidation on GetLatestVersion miss 3. Adding comprehensive test for external write scenarios Closes #126 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
24
CLAUDE.md
24
CLAUDE.md
@@ -122,6 +122,30 @@ if errors.Is(err, aether.ErrVersionConflict) {
|
||||
- `ErrVersionConflict` - Sentinel error for version conflicts (use with `errors.Is`)
|
||||
- `VersionConflictError` - Detailed error with ActorID, CurrentVersion, and AttemptedVersion
|
||||
|
||||
#### Version Cache Invalidation
|
||||
|
||||
The JetStreamEventStore maintains an in-memory cache of actor versions to optimize
|
||||
repeated version checks during optimistic concurrency control. The cache is designed
|
||||
to handle multi-store scenarios where external processes may write to the same
|
||||
JetStream stream:
|
||||
|
||||
- **Cache hits**: Cached version is returned immediately for performance
|
||||
- **Cache misses**: If no cached version exists, JetStream is queried and cached
|
||||
- **External writes**: If GetLatestVersion detects a version newer than cached, the cache is invalidated and fresh data is fetched next time
|
||||
|
||||
This strategy ensures data consistency even in scenarios with external writers while
|
||||
maintaining excellent performance for the single-writer case (where only Aether owns
|
||||
the stream).
|
||||
|
||||
**Implementation detail**: The cache is invalidated by deleting the entry, forcing
|
||||
a fresh fetch from JetStream on the next version check for that actor. This is
|
||||
safe because:
|
||||
|
||||
1. SaveEvent uses getLatestVersionLocked() which checks JetStream on cache miss
|
||||
2. GetLatestVersion always fetches fresh data and detects stale cache entries
|
||||
3. Subsequent checks will fetch from JetStream until the cache is repopulated
|
||||
|
||||
|
||||
### Namespace Isolation
|
||||
|
||||
Namespaces provide logical boundaries for events and subscriptions.
|
||||
|
||||
Reference in New Issue
Block a user