Files
aether/AGENTS.md
Hugo Nijhuis 0b44f6664a
All checks were successful
CI / build (pull_request) Successful in 21s
Remove CLAUDE.md, .claude, and .product-strategy; add AGENTS.md
2026-05-21 11:07:56 +02:00

2.7 KiB

Aether

Distributed event sourcing primitives for Go, powered by NATS.


Development Commands

make build    # go build ./...
make test     # go test ./...
make lint     # golangci-lint run
make clean    # go clean

NATS Server Requirement

Integration tests require NATS with JetStream enabled:

brew install nats-server
nats-server -js

Run tests in a separate terminal after starting NATS.

Project Structure

aether/
├── event.go           # Event, ActorSnapshot, EventStore interface
├── eventbus.go        # EventBus, EventBroadcaster interface
├── nats_eventbus.go   # NATSEventBus implementation
├── metrics*.go        # Prometheus metrics
├── store/             # EventStore implementations
│   ├── memory.go      # InMemoryEventStore (testing)
│   └── jetstream.go   # JetStreamEventStore (production)
├── cluster/           # Cluster management
│   ├── manager.go     # ClusterManager
│   ├── discovery.go   # NodeDiscovery
│   ├── hashring.go    # ConsistentHashRing
│   ├── shard.go       # ShardManager
│   ├── leader.go      # LeaderElection
│   └── types.go       # Cluster types
├── examples/          # Usage examples
└── eventstorming/     # Domain modeling reference

Core Patterns

Event Versioning

Events for each actor must have monotonically increasing versions:

currentVersion, _ := store.GetLatestVersion(actorID)
event := &aether.Event{
    ActorID:   actorID,
    Version:   currentVersion + 1,
    // ...
}
err := store.SaveEvent(event)
if errors.Is(err, aether.ErrVersionConflict) {
    // Reload and retry
}

Namespace Isolation

Namespaces provide logical boundaries for events:

// Event bus namespace
ch := eventBus.Subscribe("tenant-abc")
eventBus.Publish("tenant-abc", event)

// Store namespace
store, _ := store.NewJetStreamEventStoreWithNamespace(natsConn, "events", "tenant-abc")

Namespaces sanitize special characters and prefix stream names for complete data isolation.

JetStream Cache Behavior

JetStreamEventStore caches actor versions for performance. Cache is invalidated when GetLatestVersion detects a newer version from external writes.

Testing

  • Unit tests: go test -v ./...
  • Single test: go test -v -run TestName
  • Single file: go test -v ./store/...
  • Benchmarks: go test -bench=. -benchmem

Integration tests require running NATS server first.

Linting

golangci-lint run
golangci-lint run --fix

References