Creating Workflows
Workflows are a sequence of steps that define the logic and flow of a process. They are used to automate business processes, manage data, and coordinate tasks. The Workflow Engine provides a flexible and scalable platform for creating and executing workflows.
Workflows can be created using a code-first approach or a designer-first approach. The code-first approach involves writing workflows using a programming language, while the designer-first approach involves using a visual designer in the Workflow Studio to create workflows.
Please see the Creating Workflows Using the Workflow Studio guide for more information on the designer-first approach.
This guide details the technical, but more powerfull code-first approach to writing workflows. It covers the lifecycle methods, behind-the-scenes workings, and provides an example workflow to help you get started.
Workflow Lifecycle
A workflow in the Workflow Engine goes through several stages during its lifecycle. The main stages are:
- Authorization: The workflow checks if it has the necessary permissions to proceed.
- Initiation: The workflow starts and processes the initial payload.
- Hibernate: The workflow pauses and waits for a specific event or message.
- Resume: The workflow resumes from the hibernated state.
- Terminate: The workflow completes its execution and performs cleanup.
- Recover: The workflow recovers from a failure or restart.
Diagram of the Workflow Lifecycle
Creating a Workflow
To create a new workflow, you need to define a class that extends the Workflow
class. The new class should implement the necessary lifecycle methods to handle the workflow logic.
Example Workflow Class Definition
import Workflow from '../../classes/Workflow.js';
export default class ExampleWorkflow extends Workflow {
static workflowName = "ExampleWorkflow";
static workflowVersion = "2.0";
constructor(instanceId = null, workflowDeadlineInMinutes = 1440) {
super(instanceId, workflowDeadlineInMinutes);
this.name = ExampleWorkflow.workflowName;
this.version = ExampleWorkflow.workflowVersion;
}
async OnAuthorize(payload) {
console.log(`📝 Authorization in process...`);
return true;
}
async OnInitiate(payload) {
console.log(`👤 ExampleWorkflow \${this.instanceId} initiated`);
await this.TestActivity(payload);
return { instanceId: this.instanceId, message: "Workflow initiated successfully." };
}
async TestActivity(payload) {
console.log(`👤 Running TestActivity with payload: \${JSON.stringify(payload)}`);
await this.Wait(payload.correlationId, this.ResumeAndTerminate.bind(this), 5);
}
async OnHibernate() {
console.log("👤 ******Going to Sleep*****");
}
async OnResume() {
await super.OnResume();
console.log("👤 ******Resumed...*****");
await this.ResumeAndTerminate();
}
async ResumeAndTerminate(payload) {
console.log("👤 After Resume:");
console.log(`👤 Response received for workflow \${this.instanceId}`);
await this.Terminate();
}
async OnRecover() {
await super.OnResume();
console.log("👤 ******Recovered...*****");
await this.OnInitiate(); // Start over
}
async OnTerminate() {
console.log(`👤 ExampleWorkflow \${this.instanceId} specific termination logic executed.`);
}
}
Lifecycle Methods
OnAuthorize
The OnAuthorize
method is called to authorize the workflow. It should return a boolean indicating whether the authorization was successful.
async OnAuthorize(payload) {
console.log(`📝 Authorization in process...`);
return true; // or false based on the logic
}
OnInitiate
The OnInitiate
method is called to initiate the workflow. It processes the initial payload and sets up the workflow state.
async OnInitiate(payload) {
console.log(`👤 ExampleWorkflow \${this.instanceId} initiated`);
await this.TestActivity(payload);
return { instanceId: this.instanceId, message: "Workflow initiated successfully." };
}
OnHibernate
The OnHibernate
method is called when the workflow is hibernated.
async OnHibernate() {
console.log("👤 ******Going to Sleep*****");
}
OnResume
The OnResume
method is called when the workflow is resumed.
async OnResume() {
await super.OnResume();
console.log("👤 ******Resumed...*****");
await this.ResumeAndTerminate();
}
OnTerminate
The OnTerminate
method is called when the workflow is terminated.
async OnTerminate() {
console.log(`👤 ExampleWorkflow \${this.instanceId} specific termination logic executed.`);
}
OnRecover
The OnRecover
method is called to recover the workflow after a failure or restart.
async OnRecover() {
await super.OnResume();
console.log("👤 ******Recovered...*****");
await this.OnInitiate(); // Start over
}
Behind the Scenes
Workflow Management
The WorkflowManagement
class is responsible for managing the lifecycle of workflow instances. It provides methods to add, retrieve, remove, and persist workflow instances.
Instance Map Store
The InstanceMapStore
class is a singleton that stores workflow instances in memory. It provides methods to add, retrieve, and remove instances.
Message Distribution
The MessageDistributionService
class handles the distribution of messages to workflow instances. It subscribes to various events and distributes messages accordingly.
Queue Management
The QueueManager
class manages a queue of messages that need to be processed. It ensures that messages are processed efficiently and handles retries.
Example Workflow
Here's an example of how to create and run the ExampleWorkflow
workflow:
import ExampleWorkflow from './workflows/ExampleWorkflow.mjs';
const payload = {
alias: "agent123",
requestId: "req-456",
metadata: {
customerName: "John Doe",
customerEmail: "john.doe@example.com"
},
skipVoiceCheck: false
};
async function runWorkflow() {
const workflow = new ExampleWorkflow();
await workflow.OnAuthorize(payload);
await workflow.OnInitiate(payload);
await workflow.TestActivity(payload);
}
runWorkflow().catch(error => {
console.error("Error running ExampleWorkflow:", error);
});
Conclusion
This documentation provides a comprehensive guide on how to write a workflow using the Workflow Engine. It covers the lifecycle methods, behind-the-scenes workings, and provides an example workflow to help you get started. By following this guide, you can create robust and maintainable workflows for various use cases.