Installation
Add to yourCargo.toml:
Basic usage
Loader
The loader pattern enables dynamic decision loading from any source. ZEN Engine provides several built-in loaders.FilesystemLoader
Load decisions from a directory:MemoryLoader
Store decisions in memory:Closure loader
Define custom loading logic with an async callback:Custom loader
Implement theDecisionLoader trait for full control:
Cloud storage loaders
For production-ready cloud storage loaders (AWS S3, Azure Blob Storage, Google Cloud Storage) with zip support, see the reference implementation:GoRules Agent
Reference implementation with cloud storage loaders for S3, Azure, and GCS
Pre-compilation
Pre-compile decisions for improved evaluation performance:Error handling
Tracing
Enable tracing to inspect decision execution:Expression utilities
Thezen-expression crate provides expression evaluation outside of decisions:
High performance with Isolate
For repeated evaluations, useIsolate to reuse allocated memory:
Design notes
Single-threaded expression engine
The expression engine is single-threaded by design for maximum performance. This avoids synchronization overhead and enables optimizations like memory reuse inIsolate.
Thread-pinned futures
Althoughevaluate is async, the returned Future is !Send — it must complete on the same thread where it was started. This is intentional: sending data across threads would be costly in this scenario, and pinning enables significant performance gains. However, this can be awkward with async runtimes that expect Send futures.
For multi-threaded workloads, use LocalPoolHandle from tokio-util to spawn pinned tasks:
Best practices
UseFilesystemLoader with keep_in_memory: true. This caches parsed decisions in memory for optimal performance.
Initialize the engine once. Create a single DecisionEngine instance at application startup and reuse it for all evaluations.
Use Isolate for repeated expression evaluation. It reuses allocated memory, drastically improving throughput.