The only requirements to write a workflow are:
Zenaton.abstracts.workflow.Workflow
class that requires only a handle
method that will be
called to run the workflow;
zenaton.traits.zenatonable.Zenatonable
class, that defines dispatch
and execute
methods
Idempotence implies that any actions (such as requesting a database, writing/reading a file, using current time, sending an email, echoing in console, etc.) that have side effects or that need access to potentially changing information MUST be done within tasks (not from within workflows).
As Zenaton engine triggers the execution of the class describing a workflow each time it has to decide what to do next, failing to follow the idempotence requirement will lead to multiple executions of actions wrongly present in it.The provided methods
execute
anddispatch
are internally implemented to ensure idempotency.
Example:
Copyfrom zenaton.abstracts.workflow import Workflow from zenaton.traits.zenatonable import Zenatonable class WelcomeFlow(Workflow, Zenatonable): def __init__(self, user): self.email = user.email self.slack_id = user.slack_id def handle(self): SendWelcomeEmail(self.email).execute() IntroduceUserThroughSlack(self.slack_id).execute()
You need to setup Zenaton with your credentials:
CopyZenaton.client.Client(app_id, api_token, app_env)
Then launching a workflow is as easy as:
CopyWelcomeFlow(self.user).dispatch();
If you want to reference this workflow later, just implement a id
public method in your workflow implementation that provides the id Zenaton should
use to retrieve this workflow instance, eg in
WelcomeFlow.py
Copy... def id(self) return self.email ...
To be valid, this id
method MUST be unique (meaning in the same environment,
you can not have two running instances of the same workflow with the same id).
You can pause a workflow’s instance
CopyWelcomeFlow().where_id(email).pause()
and later resume it
CopyWelcomeFlow().where_id(email).resume()
or even kill it
CopyWelcomeFlow().where_id(email).kill()
It is also possible to pause, resume or kill worklows directly from Zenaton Interface.
They are the attributes of your task/workflow classes.
Copyfrom zenaton.abstracts.workflow import Workflow from zenaton.traits.zenatonable import Zenatonable class WelcomeFlow(Workflow, Zenatonable): def __init__(self, user): self.email = user.email self.slack_id = user.slack_id def handle(self): ... self.foo = TaskA(self.email).execute() ... self.foo = "..."
For example here, you have three properties, email
, slack_id
and foo
.
The two first are created inside your constructor.
But you can also create a new one later like foo
, inside the handle method or the on_event method.
You can use and mutate it when you want.
It's just regular class attributes!
Notice that we expose them in the dashboard.
You can either get them from the SDK or view them in the Zenaton Dashboard.
You can view task and workflow properties for each instance. You can also see all their different values through steps.
If an error occurred during a task execution, then this workflow instance will automatically be paused and you will have to resume it manually here. You can also retry them manually directly from the interface.