Documentation§
Wiggle is a durable workflow engine: a JAR and a database. You define a business process as pure topology (named steps and how they chain, branch, and rejoin); Wiggle persists every instance as tokens moving over that graph, so a process survives restarts, retries, and worker death and resumes exactly where it left off. Steps are executed by pull-based workers over gRPC — your services, in your processes, in your language.
Where to start§
| If you want to… | Read |
|---|---|
| Run something in the next ten minutes | Onboarding & configuration |
| See every operator in runnable code | Cookbook |
| Split one flow's steps across many microservices | Queues |
| Cut server round-trips for step-heavy flows | Local execution |
| Write workers in Go or Python | Go & Python clients |
| Copy a working shape for a real process | The patterns library |
The mental model in five sentences§
- A workflow definition is a compiled graph — data the server owns, versioned by the content hash of the graph. There is no workflow code on the server, so there is no replay and no determinism contract.
- A running instance is a set of tokens positioned on that graph (in the spirit of a Petri net), each token a database row. Recovery is reading the rows.
- Handlers are plain methods in your services, matched to steps by name. A method's
signature picks its kind:
booleanreturn = gate,void= effect, anything else = a task whose return replaces the context. - Nothing merges implicitly. Fork branches run on isolated context copies and rejoin only
through an explicit combine step;
forEachmaps elements and hands you the collected results. - Workers pull. They long-poll queues over gRPC with lease-based claims — no inbound connectivity to your services, backpressure by construction, at-least-once execution with exactly-once dispatch.
Running modes§
Start embedded, grow into a cluster — the same workflows run unchanged in all three postures:
| Mode | What it is |
|---|---|
| Embedded | WiggleServer inside your JVM, in-memory store — dev and tests |
| Standalone | one node, gRPC :8080, in-memory or a database |
| Cluster | several nodes sharing one database; a leader runs timers and recovery |
The onboarding guide walks through each, including the ops console.
Execution modes§
Where a step runs is a property of the workflow, not of the deployment. A worker-run flow picks
one of three with executeInServer(), executeInLocalSync() or executeInLocalAsync():
| Mode | Who runs the step | What the server does |
|---|---|---|
SERVER |
a worker, one round-trip per step | dispatches every step, commits every completion |
LOCAL_SYNC / LOCAL_ASYNC |
a worker, chaining same-queue steps | commits per step, or once per batch — local execution |
Every mode lands in the same Performance view of the console: per-step p50/p95 by the handler's own clock, and queue wait for worker-run steps.