System Overview
EvidentSource is designed as a cloud-native event sourcing platform that combines the reliability of a database with the flexibility of an application platform. This page provides an overview of the system architecture and key design decisions.
High-Level Architecture
Section titled “High-Level Architecture”graph TB subgraph "Clients" A[JVM Client] B[REST Client] C[gRPC Client] end
subgraph "API Layer" D[REST API] E[gRPC API] F[Web UI] end
subgraph "Core Server" G[Command Handler] H[Query Engine] I[WebAssembly Runtime] J[Index Manager] end
subgraph "Storage Layer" K[Storage Adapter Interface] L[In-Memory] M[DynamoDB+SNS] N[DynamoDB+Kafka] end
A --> E B --> D C --> E D --> G D --> H E --> G E --> H F --> D G --> K H --> K H --> I I --> K J --> K K --> L K --> M K --> NCore Components
Section titled “Core Components”API Layer
Section titled “API Layer”The API layer provides multiple interfaces for interacting with EvidentSource:
- gRPC API: High-performance binary protocol for programmatic access
- REST API: HTTP/JSON interface for web applications and simple integrations
- Web UI: Browser-based interface for exploration and management
All APIs provide the same core functionality:
- Database management (create, delete, list)
- Event transactions (write batches with constraints)
- Event queries (flexible filtering and temporal queries)
- State View management and querying
Command Handler
Section titled “Command Handler”Processes write operations:
- Batch Validation: Ensures events meet CloudEvents specification
- Constraint Checking: Validates optimistic concurrency constraints
- Atomic Commits: All-or-nothing batch transactions
- Revision Assignment: Assigns monotonic revision numbers
- Metadata Capture: Records origin context (HTTP/gRPC/Kafka) for auditing
Query Engine
Section titled “Query Engine”Handles read operations efficiently:
- Index Navigation: Uses stream, subject, and type indexes
- Temporal Queries: Supports bi-temporal querying
- Event Selection: Complex AND/OR filtering logic
- Streaming Results: Efficient iteration over large result sets
WebAssembly Runtime
Section titled “WebAssembly Runtime”Executes user-defined components:
- Wasmtime Integration: High-performance WebAssembly runtime
- Component Model: Support for WASI preview2 components
- State Views: Reduce functions for materialized views
- State Changes: Command processors that emit events
- Isolation: Each component runs in its own sandbox
Index Manager
Section titled “Index Manager”Maintains queryable indexes:
- Multi-Dimensional Indexing: By stream, subject, type, and time
- Lazy Construction: Indexes built on first query
- Incremental Updates: Efficient append-only updates
- Memory Efficiency: Shared immutable data structures
Storage Architecture
Section titled “Storage Architecture”Storage Adapter Interface
Section titled “Storage Adapter Interface”EvidentSource uses a pluggable storage architecture:
trait StorageAdapter { // Database operations async fn create_database(&self, name: &str) -> Result<()>; async fn delete_database(&self, name: &str) -> Result<()>;
// Event operations async fn append_events(&self, db: &str, events: Vec<Event>) -> Result<Revision>; async fn read_events(&self, db: &str, range: Range<Revision>) -> Result<Vec<Event>>;
// Index operations async fn update_indexes(&self, db: &str, events: &[Event]) -> Result<()>; async fn query_index(&self, db: &str, query: &Query) -> Result<Vec<Revision>>;}Storage Adapters
Section titled “Storage Adapters”In-Memory Adapter
Section titled “In-Memory Adapter”For development and testing:
- All data stored in RAM
- Fast performance for small datasets
- No persistence between restarts
- Perfect for unit tests and local development
DynamoDB + SNS Adapter
Section titled “DynamoDB + SNS Adapter”For AWS production deployments:
- DynamoDB Tables:
- Events table: Stores all events
- Indexes table: Stream, subject, type indexes
- Databases table: Database metadata
- SNS Topics: Real-time event notifications
- S3 Integration: Large event storage (planned)
- Auto-scaling: Handles varying workloads
DynamoDB + Kafka Adapter
Section titled “DynamoDB + Kafka Adapter”Alternative streaming option:
- Same DynamoDB storage as above
- Kafka for event streaming instead of SNS
- Better for high-throughput scenarios
- Supports replay and consumer groups
Data Flow
Section titled “Data Flow”Write Path
Section titled “Write Path”- Client Request: Batch of events with constraints
- Validation: CloudEvents format and size limits
- Constraint Check: Verify optimistic concurrency
- Storage Write: Atomic append to event log
- Index Update: Update relevant indexes
- Notification: Publish to SNS/Kafka
- Response: Return new revision number
Read Path
Section titled “Read Path”- Client Query: Event selection criteria
- Index Lookup: Find matching revisions
- Event Fetch: Retrieve events by revision
- State View: Optional materialization via WASM
- Response: Stream results to client
Scalability Design
Section titled “Scalability Design”Horizontal Scaling
Section titled “Horizontal Scaling”- Stateless Servers: Any server can handle any request
- Shared Storage: All state in DynamoDB/S3
- Load Balancing: Standard ALB/NLB support
- Auto-scaling Groups: Scale based on load
Performance Optimizations
Section titled “Performance Optimizations”- Index Chunking: Large indexes split into chunks
- Lazy Loading: Indexes loaded on demand
- Caching: Multi-level caching strategy
- Batch Processing: Efficient batch operations
- Zero-Copy: Minimize data copying
Limits and Quotas
Section titled “Limits and Quotas”- Event Size: 64KB per event
- Batch Size: 25 events per batch (configurable)
- Database Name: 63 characters, DNS-compliant
- Query Results: Paginated for large datasets
Security Architecture
Section titled “Security Architecture”Authentication & Authorization
Section titled “Authentication & Authorization”- API Keys: For programmatic access
- IAM Integration: For AWS deployments
- TLS/HTTPS: Encrypted transport
- Database Isolation: Complete separation between databases
Data Protection
Section titled “Data Protection”- Encryption at Rest: Via DynamoDB/S3
- Encryption in Transit: TLS 1.2+
- Immutable Events: No modification after write
- Audit Trail: Every change is recorded
Reliability Features
Section titled “Reliability Features”Fault Tolerance
Section titled “Fault Tolerance”- Atomic Batches: All-or-nothing semantics
- Idempotent Operations: Safe to retry
- Consistency Guarantees: Strong consistency
- Graceful Degradation: Partial availability
Disaster Recovery
Section titled “Disaster Recovery”- Point-in-Time Recovery: Via DynamoDB
- Cross-Region Replication: DynamoDB Global Tables
- Backup/Restore: Full database snapshots
- Event Replay: Rebuild from event log
Monitoring & Observability
Section titled “Monitoring & Observability”Metrics
Section titled “Metrics”- Event Rate: Events per second
- Query Latency: Response time percentiles
- Storage Usage: By database and index
- Error Rates: By operation type
Logging
Section titled “Logging”- Structured Logs: JSON format
- Correlation IDs: Request tracing
- Error Details: Full error context
- Performance Logs: Slow query logging
Tracing
Section titled “Tracing”- OpenTelemetry: Distributed tracing
- Span Context: Through full request lifecycle
- Custom Attributes: Business context
- Integration: Works with Jaeger, Zipkin, etc.
Design Principles
Section titled “Design Principles”Event-First
Section titled “Event-First”Everything is an event:
- State changes are events
- Commands produce events
- Views are derived from events
- History is preserved in events
Immutability
Section titled “Immutability”Data is append-only:
- Events cannot be modified
- Indexes are immutable structures
- History is permanent
- Corrections are new events
Simplicity
Section titled “Simplicity”Keep it simple:
- CloudEvents standard format
- REST/gRPC standard protocols
- WebAssembly standard runtime
- SQL-like query language
Extensibility
Section titled “Extensibility”User-defined behavior:
- Custom State Views
- Custom State Changes
- Pluggable storage
- Standard interfaces
Next Steps
Section titled “Next Steps”- Explore Storage Adapters in detail
- Learn about the WebAssembly Runtime
- See Deployment Options for production
- Check API Reference for implementation details