Executing Logic
Workflows4s supports two ways of embedding custom logic within a workflow:
- Deterministic (Pure) Operations - operations that always produce the same output for the same input, without any side effects
- Nondeterministic Operations - operations that may produce different outputs for the same input, typically involving side effects
Deterministic operations are executed with each workflow recovery, while nondeterministic ones are memoized through event persistance.
Deterministic (Pure) Operations
Without Error
val doThings: WIO[Any, Nothing, MyState] =
WIO.pure(MyState(1)).autoNamed
val doThings2: WIO[MyState, Nothing, MyState] =
WIO.pure
.makeFrom[MyState]
.value(state => MyState(state.counter))
.autoNamed
Rendering Outputs
- Flowchart
- BPMN
- Model
{
"meta" : {
"name" : "Do Things",
"error" : null
},
"_type" : "Pure"
}
With Error
val doThingsWithError: WIO[Any, MyError, Nothing] =
WIO.pure.error(MyError()).autoNamed
val doThingsWithError2: WIO[MyState, MyError, Nothing] =
WIO.pure
.makeFrom[MyState]
.error(_ => MyError())
.autoNamed
Rendering Outputs
- Flowchart
- BPMN
- Model
{
"meta" : {
"name" : "Do Things With Error",
"error" : {
"name" : "My Error"
}
},
"_type" : "Pure"
}
note
Unnamed pure elements are considered technical in nature and are not rendered in diagrams.
To make them visible, use .named("Name")
or .autoNamed
.
Nondeterministic Operations (Side Effects)
Nondeterministic operations involve side effects like API calls, database operations, or other external interactions. These operations need special handling because they shouldn't be re-executed during workflow recovery.
info
Workflows4s currently supports onyl cats-effect IO. If you're interested in other effect systems, please check here.
Without Error
val doThings: WIO[MyState, Nothing, MyState] =
WIO
.runIO[MyState](state => IO(MyEvent()))
.handleEvent((state, event) => MyState(state.counter + 1))
.autoNamed
Rendering Outputs
- Flowchart
- BPMN
- Model
{
"meta" : {
"name" : "Do Things",
"error" : null
},
"_type" : "RunIO"
}
With Error
val doThingsWithError: WIO[MyState, MyError, MyState] =
WIO
.runIO[MyState](state => IO(MyEvent()))
.handleEventWithError((state, event) =>
if (true) MyState(state.counter + 1).asRight
else MyError().asLeft,
)
.autoNamed
Rendering Outputs
- Flowchart
- BPMN
- Model
{
"meta" : {
"name" : "Do Things With Error",
"error" : {
"name" : "My Error"
}
},
"_type" : "RunIO"
}
note
Errors render in flowchart only when they are handled