A workflow is a series of steps or activities that are executed either in parallel or in sequence, or in a combination of the two. Since activities can be executed in parallel, they can perform jobs across multiple services at the same time without being blocked.
The following are the features of workflows:
- Ability to recover from failure: A workflow can be hydrated, meaning its state can be saved at well-defined points within the workflow. If the workflow fails, it starts again from the last saved state rather than from beginning. This feature is also known as checkpoints.
- Long-running: Workflows are generally long-running in nature. They can run from minutes to hours or days. They again save the state when they are waiting for an external action to complete and can start again from the last saved state once the external activity is complete.
- Execute steps in parallel: We've already discussed this point, but this is a major benefit of a workflow compared to sequence programming.
- Maintaining state: Workflows typically are stateful in nature. They maintain state such that in the event of failure or the restart of a workflow, the workflow does not start from beginning, but can continue from these checkpoints.
Azure Functions need to have finished executing within 5 minutes. This means they are short-lived, and composing workflows with them can really be difficult. There is the possibility of implementing multiple functions and ensuring they are coordinated to execute one after another. Even this endeavor has its limitations.
This is more of a hack and needs considerable effort, design, and operations. All the Functions will need to have inputs tied to the outputs of their previous Function, and each Function will still run for few minutes. Another drawback of implementing workflows this way is that it is extremely difficult to understand their connectivity, dependency, and sequence of execution at a glance. In short, Azure Functions are good for implementing a single responsibility that is short-lived. They are not well suited for implementing workflows.
Another important feature of Azure Functions is that they are stateless. This means that the Functions are fleeting, available only at the time they are being executed. One Function instance execution has no relation to the previous or consequent running instance. This means there is no possibility of storing state with Azure Functions.
Azure Functions can run on any server behind the scenes, and that server might not be the same as in subsequent executions. This means Functions cannot store their state in the server they are executed on.
The only way to save state in Azure Functions is to store state externally in data stores such as Cosmos DB, SQL databases, or Azure Storage. But this design will have significant performance issues, since every time the Function executes, it would need to connect to a data store, retrieve, and eventually write to it. Now that we have looked into understanding workflows, we will proceed with Durable Functions.