-
Notifications
You must be signed in to change notification settings - Fork 47
Designing Workflows
A step is a node in a workflow graph - it can have its own properties and it consists of a workload function that is to be executed when the step is run. The workflow function is executed either for its side effects (e.g. sending an email) or for the value(s) it is supposed to return (e.g. load customer data from CRM system).
{:name "hello-world"
:revision 5
:properties {:name "World"}
:steps [{:id "clojure-hello-world"
:type :custom
:supertype :tasklet
:next []
:workload-fn #titanoboa.exp/Expression{:value "(fn [p] {\"greeting\" (str \"Hello \" (:name p) \"!\")})"
:type "clojure"}
:properties {}}]}
There can be couple of different step supertypes (denoted by :supertype
key in step definition):
- :tasklet - basic workflow step executed just for its side effects or return value
- :join - same as tasklet, but also serves as rendezvous point for branches of the workflow that were being executed in parallel
- :map - based on a sequence returned by this step's workload function, many separate atomic jobs are created
- :reduce - performs reduce function over results returned by jobs triggered by a map step
Apart from :supertype
there is also :type
attribute for each step. Currently is is just being used by titanoboa GUI for step visualization (to pick a corresponding icon) and also you can use it there to pick from ready-made step templates - but during job processing it is mostly ignored. Outside of GUI its purpose is mainly just to annotate the general purpose of the step.
### `:workload-fn` The workload is either defined as: 1. **clojure library function** that is supposed to be executed (e.g. as a _package/method_ name that is on the classpath or in a library in specified maven repository/artifact): ```clojure :workload-fn 'titanoboa.tasklet.httpclient/request ``` 2. **java class** that implements [io.titanoboa.java.IWorkloadFn](https://github.com/mikub/titanoboa-java/blob/master/src/main/java/io/titanoboa/java/IWorkloadFn.java) interface. The class will be used to automatically instantiate a singleton bean (so it has to have a constructor with no argumet) and all subsequent references to it from any workflow-fn will invoke its __invoke__ method: ```clojure :workload-fn 'io.titanoboa.java.SampleWorkloadImpl ``` or in GUI: [![]( https://github.com/mikub/titanoboa/blob/master/doc/java-workload.png )](https://raw.githubusercontent.com/mikub/titanoboa/master/doc/java-workload.png ) 3. clojure **anonymous function code** wrapped in `titanoboa.exp.Expression` record: ```clojure (titanoboa.exp/map->Expression {:value "(fn [p] \n {:message (str \"Hello \" (:name p))})", :type "clojure"}) ``` or ```clojure #titanoboa.exp.Expression{:value "(fn [p] \n {:message (str \"Hello \" (:name p))})", :type "clojure"} ``` 4. **java lambda function code** wrapped in `titanoboa.exp.Expression` record: ```clojure #titanoboa.exp.Expression{:value " p -> {String greeting = (String) p.get(\"greeting\"); greeting = greeting + \" Nice to meet you!\"; java.util.HashMap propertiesToReturn = new java.util.HashMap (); propertiesToReturn.put (\"greeting\" , greeting); return clojure.lang.PersistentArrayMap.create(propertiesToReturn); }", :type "java"} ``` Anonymous code (options 3. & 4.) is not that usable programmatically, but t is primarily used by GUI for rapid development: [![]( https://github.com/mikub/titanoboa/blob/master/doc/generate-report17-change-details.png )](https://raw.githubusercontent.com/mikub/titanoboa/master/doc/generate-report17-change-details.png )