Template Engine Architecture
The template engine provides{{variable}} interpolation for workflows. It uses the pongo2 template library (Django-compatible) with custom optimizations for high-concurrency scenarios.
Template Syntax
Standard Variables
Standard template variables use{{variable}} syntax:
Secondary Variables (Foreach)
Foreach loops use[[variable]] syntax to avoid conflicts:
Generator Functions
Generator functions provide dynamic values:Engine Types
The template system provides two engine implementations:| Engine | Description | Use Case |
|---|---|---|
Engine | Standard single-threaded engine | Simple workflows |
ShardedEngine | High-performance sharded cache | High concurrency |
TemplateEngine Interface
BatchRenderer Interface
For high-throughput scenarios, theBatchRenderer interface extends TemplateEngine:
ShardedEngine Architecture
TheShardedEngine distributes templates across multiple shards to reduce lock contention:
Configuration
Performance Features
- Sharded Caching: Templates are distributed across shards using FNV-1a hash, reducing lock contention.
- RWMutex per Shard: Read-heavy workloads benefit from reader-writer locks.
-
Quick Path: Templates without
{{are returned immediately without processing. - Lock-Free Execution: Compiled pongo2 templates are thread-safe; execution happens outside locks.
- Context Pooling: Reusable context maps reduce GC pressure.
Render Flow
Precompiled Templates
ThePrecompiledRegistry stores pre-compiled templates for workflows:
Precompiler Interface
Usage
Context Pooling
Context maps are pooled to reduce memory allocations:Normalized Boolean Handling
Boolean values are normalized for template compatibility:Generator Functions
Generator functions produce dynamic values:Usage
Batch Rendering
For high-throughput scenarios, batch rendering reduces lock acquisitions:Secondary Template Rendering
Foreach loops use[[variable]] to avoid conflicts with pre-rendered {{variables}}:
Performance Benchmarks
Typical performance characteristics:| Operation | Single-threaded | 10 Concurrent | 100 Concurrent |
|---|---|---|---|
| Simple render | 500ns | 600ns | 800ns |
| Cached render | 200ns | 250ns | 400ns |
| Batch render (10) | 1.5µs | 2µs | 3µs |
| Pre-compiled | 150ns | 200ns | 350ns |
Best Practices
- Use pre-compilation for frequently executed workflows
- Enable pooling for high-concurrency scenarios
- Use batch rendering when rendering multiple templates with the same context
- Avoid unnecessary templates - only use
{{}}when variable substitution is needed - Use secondary syntax
[[]]for foreach loop variables to avoid double-rendering issues