Workflows¶
Suite framework provide a set of features to implement workflows in your application, through which you can specify a set of predefined states and actions to be executed, as a result of transition from one state to the next one.
At a glance, the workflow service architecture is comprised of:
- Workflow client module: providing generic workflow support for entities
- Workflow UI client: providing workflow components to integrate in UIs for querying workflow state and triggering transitions.
- Workflows service: central workflow administration
Workflow client modules¶
Workflow client modules provide everything you need to define and execute workflows in your applications.
Workflows are defined by mean of templates in client modules. Templates combine workflow state, transitions, and actions to provide behavior, fulfilling a specific business case for a given entity type. See here to know more on Workflow templates and definitions
Workflow clients also integrates seamlessly with Suite's GraphQL
module to
expose needed queries and mutations to get and execute workflow transitions.
Workflow UI client¶
Suite's workflows provide a set of UI components, allowing applications developers to easily integrate workflow features into their applications with minimum effort.
Workflow UI components provides features to query entity's workflow state, display and execute available transitions prompting the user for the required action's input arguments.
Workflow service¶
Workflow service centralize and manages workflow templates seeded by client modules. Workflow definitions for an entity are created out a given template. Workflow clients gets notified of workflow definition creations grabbing those definitions to perform stand-alone, staying always in-sync with workflow definition updates coming from workflow service.
Workflow definition lifecycle (handshaking)¶
Client modules define and publish the available templates for each entity supporting workflow. Workflow templates are sent to the Workflow Service, which acts as a central management repository for the whole ecosystem. Once there, a workflow definition can be created out of a given template, which will be used by client module to rule the entity state and behavior defined by the workflow.
Workflow definitions are mirrored locally by client modules, they get notified when workflow definitions get created/updated, in workflow service (central repository), then workflow clients store locally the workflow definition definition affected. Workflow client modules have all the workflow information to perform stand-alone after the handshaking process is completed.
To sum up, the workflow definition lifecycle is as following:
- Applications configure workflow client module by providing available actions and workflow templates for each entity supporting workflow.
- Client module pushes actions and templates to workflow service.
- Workflow service stores actions and templates coming from workflow clients.
- User (as of now this is done by mean of deployment tasks), creates a new workflow definition, for a given entity, based off a template.
- Workflow service notify workflow client modules of the new workflow definition being created.
- Workflow clients acknowledge the workflow definition created by mirroring it locally.
Executing the workflow¶
The workflow runtime uses a generic workflow transition consumer to execute required transition. The lifecycle of the entity being supporting transition can be implemented either by using consumers, as it likely would, or by mean of sagas, preferring the former over the latter.
Typically the workflow starts at the very beginning of the entity's lifetime,
you've just to invoke StartWorkflow
to let the workflow module handle
initialization. When using consumers, you'll need to inject the
IWorkflowEngine
instance and invoke StartWorkflow
on that instance, whereas
when using sagas you must invoke StartWorkflow
extension method.
The workflow engine will handle the initialization process and will transition the workflow entity to its initial state. From that moment on, the workflow transitions will be handled by a generic consumer, no matter the entity has been created managed by a saga or by mean of consumers.
To start workflow using consumers, you should do the following:
Please note that StartWorkflow
must be called just once, most likely when the
entity is being created. The rest of the workflow lifecycle will be managed by
WorkflowTransitionConsumer<TEntity>
which is created and configured by the
workflow client module.
A basic example of a workflow implementation using sagas is shown here below:
From the example, please note that:
- Workflow starts when calling
StartWorkflow
method of theIWorkflowEngine
, or by callingStartWorkflow
saga's extension method when using sagas, at theInitially
state. - Transitions are handled by
WorkflowTransitionConsumer
no matter you are using consumers or sagas.
Please note that, when using sagas the workflow state is kept aside from the saga state, and is used internally by the workflow runtime to determine and manage the current workflow state.
Workflow versioning support¶
Entities keep track of the workflow definition they are bound to. New definitions can be created for the same entity without breaking the current operation flow, for the entities that have started working with the previous version, allowing to evolve workflow templates as the time goes on.
Workflow testing utilities¶
There are utilities for unit/integration testing available:
-
Workflow definition seeder: publishes workflow definition created for a given workflow template. This is handy when testing client module only, but we need the workflow definition event being triggered to acknowledge and mirror it locally, without the presence of the workflow central service.
-
Workflow action handler context mock: this mock facilitates the workflow action's unit testing by abstracting away some dependencies and providing handy methods to assert on different things.