Skip to main content

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)