What is a workflow?
A specification and container for a topology of connected builders that generate a final data. It has the following meta:
- Builders - List of Builders
- Target Data - The name of the Data being generated by this data flow. Once this is produced, the workflow is complete. It can, however, be re-opened by feeding new data.
Definition
Workflows must implement the IWorkflow
interface.
type IWorkflow interface {
GetWorkflowMeta() WorkflowMeta
}
Let's take the example of a cab ride workflow. Essentially, for a cab ride workflow, builders (units of work) could be:
- User initiating a request
- Cabbie match
- Cabbie reaches source
- Ride starts
- Cabbie reaches destination
- User makes payment
- Ride ends
type CabRideWorkflow struct {
}
func (cr CabRideWorkflow) GetWorkflowMeta() WorkflowMeta {
return WorkflowMeta{
Builders: []IBuilder{
UserInitiation{},
CabbieMatching{},
CabbieArrivalAtSource{},
CabDepartureFromSource{},
CabArrivalAtDest{},
UserPayment{},
RideEnds{}
},
TargetData: WorkflowTerminated{},
}
}
You don't have to sequentially define the builders in order of execution. Polaris will figure it out. However, you should if you can. It helps readability.
Registering a workflow
polaris.RegisterWorkflow(workflowKey, workflow)
Executing a workflow
executor := polaris.Executor{
Before: func(builder reflect.Type, delta []IData) {
fmt.Printf("Builder %s is about to be run with new data %v\n", builder, delta)
}
After: func(builder reflect.Type, produced IData) {
fmt.Printf("Builder %s produced %s\n", builder, produced)
}
}
// sequentially execute builders
response, err := executor.Sequential(workflowKey, workflowId, dataDelta)
// concurrently execute builders (does not guarantee parallelism!)
response, err := executor.Parallel(workflowKey, workflowId, dataDelta)