Duroxide Provider Implementation Skill
February 22, 2026 · View on GitHub
Summary
This skill enables AI assistants to help implement custom storage providers for Duroxide, a durable execution runtime for Rust. Providers are storage backends that persist orchestration state, manage work queues, and ensure atomic operations.
Key Concepts
Provider Role
- Providers are "dumb storage" — they store and retrieve data exactly as instructed
- Runtime owns all logic — providers never interpret events or make orchestration decisions
- ID generation is runtime's job — providers MUST NOT generate
execution_idorevent_id
Architecture
- Two work queues: Orchestrator queue (completions, timers) and Worker queue (activities)
- Event history: Append-only log per instance/execution
- Peek-lock semantics: Items locked during processing, deleted on ack
Core Trait Methods
| Method | Purpose | Complexity |
|---|---|---|
read() | Load history for latest execution | Easy |
append_with_execution() | Append events to history | Easy |
fetch_work_item() | Fetch and lock from worker queue | Medium |
ack_work_item() | Delete from queue, enqueue completion | Medium |
fetch_orchestration_item() | Fetch turn with instance lock | Complex |
ack_orchestration_item() | Atomic commit of turn | Complex |
Critical Requirements
- Atomicity:
ack_orchestration_item()must be a single transaction - Lock validation: Always check lock is still valid before commit
- Instance-level locking: All messages for one instance processed together
- Ordering: Enqueue worker items BEFORE cancelling (for same-turn schedule+cancel)
- Error classification: Use
ProviderError::retryable()vspermanent()
Activity Cancellation
Implemented via lock stealing:
- Runtime calls
ack_orchestration_item()withcancelled_activitieslist - Provider deletes those entries from worker queue (same transaction)
- Worker's next lock renewal fails → triggers cancellation
Implementation Guidance
When implementing a provider:
- Start with history —
read()andappend_with_execution()are simplest - Add worker queue —
enqueue_for_worker(),fetch_work_item(),ack_work_item() - Add orchestrator queue — Similar pattern but with instance-level locking
- Handle advanced features — Lock renewal, cancellation, ProviderAdmin
Common Pitfalls
- ❌ Generating IDs in the provider (runtime's job)
- ❌ Non-atomic ack operations (use transactions)
- ❌ Creating instances in
enqueue_orchestrator_work()(only in ack) - ❌ DELETE before INSERT for cancelled activities (wrong order)
- ❌ Silently succeeding on lock renewal failure (must return error)
References
- Implementation Guide: docs/provider-implementation-guide.md
- Testing Guide: docs/provider-testing-guide.md
- Reference Implementations:
- SQLite (bundled):
src/providers/sqlite.rs - PostgreSQL: duroxide-pg
- SQLite (bundled):
- Provider Trait:
src/providers/mod.rs - Validation Tests:
tests/sqlite_provider_validations.rs
Usage
When asked to implement a Duroxide provider:
- Review the implementation guide for detailed method semantics
- Use SQLite or PostgreSQL implementations as reference
- Follow the "simplest path" — history → worker queue → orchestrator queue
- Run validation tests to verify correctness
- Consider implementing
ProviderAdminfor production use