Skip to main content

Runtimes

WorkflowRuntime is responsible for the following tasks:

  1. Managing workflow state
  2. Persisting events
  3. Recovering state from events
  4. Waking up the workflow at the right moments

Each runtime is created per workflow type, and its creation usually involves implementation-specific elements. WorkflowRuntime interface allows creating a WorkflowInstance based on id and input.

trait WorkflowRuntime[F[_], Ctx <: WorkflowContext, WorkflowId, Input] {

def createInstance(id: WorkflowId, input: Input): F[WorkflowInstance[F, WCState[Ctx]]]

}

Available Runtimes

Below is an overview of the available runtimes, with their strengths and limitations:

RuntimeDescriptionGood ForBad For
PekkoRuntimeUses Pekko Persistance and Cluster Sharding to manage the state and distribution of workload.
  • Scalability
  • Sophisticated requirements
  • Small-scale setups
  • Low complexity use-cases
DatabaseRuntimeRelies on database storage and locking mechanisms, without any in-memory state management.
  • Simplicity
  • Low memory footprint
  • High throughput
  • Frequent state access
InMemoryRuntimeBased on Cats Effect; keeps state in memory without persistence.
  • Fast execution
  • Ephemeral workflows
  • Long-running workflows
  • State durability
InMemorySyncRuntimeVanilla Scala implementation, not thread-safe and lacks persistence.
  • Simple workflows
  • Experimentation
  • Single-threaded scenarios
  • Testing
  • Production use cases

WorkflowEngine

Each WorkflowRuntime is parameterized by a WorkflowInstanceEngine, a component that proxies all interactions between the instance and its state, allowing for plugging-in custom behaviours.

Below is an example of building an engine.

val knockerUpper: KnockerUpper.Agent = ???
val registry: WorkflowRegistry.Agent = ???

val engine: WorkflowInstanceEngine = WorkflowInstanceEngine.builder
.withJavaTime()
.withWakeUps(knockerUpper)
.withRegistering(registry)
.withGreedyEvaluation
.withLogging
.get

KnockerUpper

KnockerUpper is a component responsible for waking up the workflow when needed, e.g., after timer has expired or retry is due. See Wake-Ups for additional details.

WorkflowRegistry

WorkflowRegistry is a component responsible for tracking the execution status of workflow instances. See Collecting Instances for additional details.