-
Notifications
You must be signed in to change notification settings - Fork 55
Compare with Cadence Temporal
Migrating from Cadence/Temporal is simple and easy. It's only possible to migrate new workflow executions. Let your applications to only start new workflows in iWF. For the existing running workflows in Cadence/Temporal, keep the Cadence/Temporal workers until they are finished.
There is no non-deterministic errors in iWF workflow code, and hence no versioning API at all in iWF!
Because there is no replay at all for iWF workflow applications. All workflow state executions are stored in Cadence/Temporal activities of the interpreter workflow activities.
Workflow code change will always apply to any running existing and new workflow executions once deployed. This gives flexibility to maintain long-running business applications.
However, making workflow code change will still have backward-compatibility issue like all other microservice applications. Below are the standard ways to address the issues:
- It's rare but if you don't want old workflows to execute the new code, use a flag in new executions to branch out. For example, if changing flow
StateA->StateB
toStateA->StateC
only for new workflows, then set a new flag in the new workflow so that StateA can decide go to StateB or StateC. - Removing state code could cause errors(state not found) if there is any state execution still running. For example, after changed
StateA->StateB
toStateA->StateC
, you may want to delete StateB. If a StateExecution stays at StateB(most commonly waiting for commands to complete), deleting StateB will cause a not found error when StateB is executed.- The error will be gone if you add the StateB back. Because by default, all State APIs will be backoff retried forever.
- If you want to delete StateB as early as possible, use
IwfWorkflowType
andIwfExecutingStateIds
search attributes to confirm if there is any workflows still running at the state. These are built-in search attributes from iWF server.
There is NO ContinueAsNew API exposed to user workflow! ContinueAsNew of Cadence/Temporal is a purely leaked technical details. It's due to the replay model conflicting with the underlying storage limit/performance. As iWF is built on Cadence/Temporal, it will be implemented in a way that is transparent to user workflows.
Internally the interpreter workflow can continueAsNew without letting iWF user workflow to know. This is called "auto continueAsNew" --
After exceeding the action threshold, continueAsNew will happen automatically. AutoContinueAsNew will carry over the pending states, along with all the internal states like DataObjects, interStateChannels, searchAttributes.
Wait, what? There is no activity at all in iWF?
Yes, iWF workflows are essentially a REST service and all the activity code in Cadence/Temporal can just move in iWF workflow code -- waitUntil or execute API of WorkflowState.
A main reason that many people use Cadence/Temporal activity is to take advantage of the history showing input/output in WebUI. This is handy for debugging/troubleshooting.
iWF provides a RecordEvent
API to mimic. It can be called with any arbitrary data, and they will be recorded into history just for debugging/troubleshooting.
Depends on different SDKs of Cadence/Temporal, there are different APIs like SignalMethod/SignalChannel/SignalHandler etc. In iWF, just use SignalCommand as equivalent.
In some use cases, you may have multiple signals commands and use AnyCommandCompleted
CommandWaitingType to wait for any command completed.
There are different timer APIs in Cadence/Temporal depends on which SDK:
- workflow.Sleep(duration)
- workflow.Await(duration, condition)
- workflow.NewTimer(duration)
- ...
In iWF, just use TimerCommand as equivalent.
Again in some use cases, you may combine signal/timer commands and use AnyCommandCompleted
commandWaitingType to wait for any command completed.
Depends on different SDKs of Cadence/Temporal, there are different APIs like QueryHandler/QueryMethod/etc.
In iWF, use DataObjects as equivalent. Unlike Cadence/Temporal, DataObjects should be explicitly defined in WorkflowDefinition.
Note that by default all the DataObjects and SearchAttributes will be loaded into any WorkflowState as LOAD_ALL_WITHOUT_LOCKING
persistence loading policy.
This could be a performance issue if there are too many big items. Consider using different loading policy like LOAD_PARTIAL_WITHOUT_LOCKING
to improve by customizing the WorkflowStateOptions.
Also note that DataObjects are not just for returning data to API, but also for sharing data across different StateExecutions. But if it's just to share data from waitUntil API to execute API in the same StateExecution, using StateLocal
is preferred for efficiency reason.
iWF has the same concepts of Search Attribute. Unlike Cadence/Temporal, SearchAttribute should be explicitly defined in WorkflowDefinition.
In Cadence/Temporal, multi-threading is powerful for complicated applications. But the APIs are hard to understand, to use, and to debug. Especially each language/SDK has its own set of APIs without much consistency.
In iWF, there are just a few concepts that are very straightforward:
- The
execute
API can go to multiple next states. All next states will be executed in parallel -
execute
API can also go back to any previous StateId, or the same StateId, to form a loop. The StateExecutionId is the unique identifier. - Use
InterStateChannel
for synchronization communication. It's just like a signal channel that works internally.
Some notes:
- Any state can decide to complete or fail the workflow, or just go to a dead end(no next state).
- Because of above, there could be zero, or more than one state completing with data as workflow results.
- To get multiple state results from a workflow execution, use the special API
getComplexWorkflowResult
of client API.
Check Client APIs for all the APIs that are equivalent to Cadence/Temporal client APIs.
Features like IdReusePolicy
, CronSchedule
, RetryPolicy
are also supported in iWF.
What's more, there are features that are impossible in Cadence/Temporal are provided like reset workflow by StateId or StateExecutionId. Because WorkflowState are explicitly defined, resetting API is a lot more friendly to use.
For unit testing, user code should be mocking all the dependencies in WorkflowState
implementation, including the input/output of the
waitUntil
and execute
API. Users should be able to use any standard testing frameworks/libraries.
For integration test, iWF provides a SkipTimer API to fire any timer immediately. Although users can always implement this themselves, the API provides a standard way and saves the effort of re-inventing the wheels.
Is that all? For now yes. We believe these are all you need to migrate to iWF from Cadence/Temporal.
The main philosophy of iWF is providing simple and easy to understand APIs to users(as minimist), as apposed to the complicated and also huge number APIs in Cadence/Temporal.
So what about something else like:
- Timeout and backoff retry: State waitUntil/execute APIs have default timeout and infinite backoff retry. You can customize in StateOptions.
- ChildWorkflow can be replaced with regular workflow + signal. See this StackOverflow for why.
- SignalWithStart: Use start + signal API will be the same except for more exception handling work. We have seen a lot of people don't know how to use it correctly in Cadence/Temporal. We will consider provide it in a better way in the future.
- Long-running activity with stateful recovery(heartbeat details): this is indeed a good one that we want to add. But this is not very commonly used yet. Please let us know if you really need it. For now a workaround is use a sub workflow instead(the sub workflow can report back the status with a signal).
If you believe there is something else you really need, open a ticket or join us in the discussion.