feat: add integration tests and examples for cross-node event broadcasting
All checks were successful
CI / build (pull_request) Successful in 1m28s
All checks were successful
CI / build (pull_request) Successful in 1m28s
- Add integration tests for UpdateVersionCache, SubscribeToEventStored - Add cross-node broadcasting integration tests - Add example demonstrating NATSEventBus + JetStreamEventStore integration - Fix unsafe type assertions in example with ok pattern - Add documentation for EventStored schema - Add helper methods: GetCachedVersion, SetBroadcaster, Close - Add constructors: NewNATSEventBusWithBroadcaster, NewNATSEventBusWithStore
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -286,6 +287,28 @@ func (jes *JetStreamEventStore) SaveEvent(event *aether.Event) error {
|
||||
|
||||
// publishEventStored publishes an EventStored event to the broadcaster.
|
||||
// This is called after a successful SaveEvent to notify subscribers.
|
||||
//
|
||||
// EventStored Event Schema:
|
||||
// - EventType: "EventStored" (aether.EventTypeEventStored)
|
||||
// - ActorID: ID of the actor that the original event was about
|
||||
// - Version: version of the stored event
|
||||
// - Data:
|
||||
// - eventId: (string) ID of the stored event
|
||||
// - actorId: (string) ID of the actor
|
||||
// - version: (int64) version of the event
|
||||
// - timestamp: (int64) Unix timestamp of when the event was stored
|
||||
//
|
||||
// Example usage with NATSEventBus:
|
||||
//
|
||||
// eventBus := aether.NewNATSEventBus(natsConn)
|
||||
// store := store.NewJetStreamEventStoreWithBroadcaster(natsConn, "events", eventBus, "")
|
||||
// ch := eventBus.SubscribeToEventStored("*")
|
||||
//
|
||||
// for event := range ch {
|
||||
// actorID := event.Data["actorId"].(string)
|
||||
// version := event.Data["version"].(int64)
|
||||
// store.UpdateVersionCache(actorID, version)
|
||||
// }
|
||||
func (jes *JetStreamEventStore) publishEventStored(originalEvent *aether.Event) {
|
||||
eventStored := &aether.Event{
|
||||
ID: uuid.New().String(),
|
||||
@@ -561,6 +584,9 @@ func sanitizeSubject(s string) string {
|
||||
// UpdateVersionCache updates the version cache for a specific actor.
|
||||
// This is used when receiving events from other nodes via NATS to keep
|
||||
// the version cache consistent across cluster nodes.
|
||||
//
|
||||
// Only updates if the new version is greater than the cached version to prevent
|
||||
// stale cache entries from causing version conflicts.
|
||||
func (jes *JetStreamEventStore) UpdateVersionCache(actorID string, version int64) {
|
||||
jes.mu.Lock()
|
||||
defer jes.mu.Unlock()
|
||||
@@ -571,5 +597,27 @@ func (jes *JetStreamEventStore) UpdateVersionCache(actorID string, version int64
|
||||
}
|
||||
}
|
||||
|
||||
// GetCachedVersion returns the cached version for an actor, if available.
|
||||
func (jes *JetStreamEventStore) GetCachedVersion(actorID string) (int64, bool) {
|
||||
jes.mu.Lock()
|
||||
defer jes.mu.Unlock()
|
||||
|
||||
version, ok := jes.versions[actorID]
|
||||
return version, ok
|
||||
}
|
||||
|
||||
// SetBroadcaster sets the event broadcaster for this store.
|
||||
// The broadcaster is used to publish EventStored events when events are saved.
|
||||
func (jes *JetStreamEventStore) SetBroadcaster(broadcaster aether.EventBroadcaster) {
|
||||
jes.mu.Lock()
|
||||
defer jes.mu.Unlock()
|
||||
jes.broadcaster = broadcaster
|
||||
}
|
||||
|
||||
// Close closes the JetStream event store and cleans up resources.
|
||||
func (jes *JetStreamEventStore) Close(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compile-time check that JetStreamEventStore implements EventStoreWithErrors
|
||||
var _ aether.EventStoreWithErrors = (*JetStreamEventStore)(nil)
|
||||
|
||||
Reference in New Issue
Block a user