$ show jmettraux/ruote
Ruote is a mature Ruby workflow engine (BPM) that orchestrates long-running business processes through a tree of expressions (sequence, concurrence, if, participant, etc.). The engine routes workitems to registered participants, persists process state via pluggable storage backends (in-memory, file system, composite), and supports process definitions in Ruby DSL, XML, JSON, and a custom Radial format. It provides a full API via Ruote::Dashboard for launching, canceling, pausing, and inspecting processes, along with error handling, timers, observers, and cross-process communication via await/listen. The codebase is well-structured with a clear expression lifecycle, participant abstraction, and a service-oriented architecture. However, the project is explicitly deprecatedβthe README states 'Do not involve ruote in your new project' and directs users to the successor flor. Development ceased around 2013, and the code relies on outdated Ruby idioms and dependencies (e.g., sourcify, parslet 1.4.0), making it unsuitable for modern Ruby projects without significant adaptation.
The LLM identified 5 files worth highlighting for reuse:
Base class for all workflow expressions. Provides the `apply`, `reply`, `cancel`, `fail`, `pause`, `resume` lifecycle, tree management, tag handling, and timer scheduling. Demonstrates a clean template-method pattern where subclasses override `apply` and `reply` to implement specific behavior. Includes persistence logic (`persist_or_raise`, `do_persist`) and error handling. This is a well-crafted, self-contained abstraction that could be reused or studied for building custom expression engines.
Implements the `concurrence` expression, which runs multiple branches concurrently and merges results. Supports a variety of merge strategies (`override`, `mix`, `isolate`, `stack`, `union`, `concat`, `deep`, `ignore`) and configuration options like `count`, `wait_for`, `remaining`, and `timeout`. The implementation is non-trivial, handling dynamic branch addition, partial results, and error propagation. The merge strategies are reusable patterns for combining hashes or workitems in different contexts.
Mixin module for implementing participants in ruote. Defines the expected interface (`on_workitem`, `on_cancel`, `on_reply`, `on_error`, `accept?`, `do_not_thread?`) and provides default implementations. This is a clean, reusable pattern for building participant adapters that can be registered with the engine. Can be extracted and adapted for other workflow systems.
Utility for accessing, setting, and deleting values in nested Ruby hashes and arrays using dot-separated keys (e.g., `'a.b.0.c'`). Supports deep traversal, array indexing, and key existence checks. The implementation is concise, handles edge cases, and is fully self-contained. This is a gem-quality utility that can be reused in any Ruby project for manipulating nested data structures.
Service that performs `${}` substitution in strings, pulling values from workitem fields, process variables, engine environment, and Ruby evaluation. Supports nested expressions, chaining, and default values. The implementation is intricate, handling recursive substitution, escaping, and security checks via TreeChecker. Demonstrates a robust pattern for dynamic interpolation in workflow or template engines.