After PHP and Node, we are happy to announce the public release of Zenaton’s Ruby library! 🎉 🎊
If you are curious as to how Zenaton can help you and your team, we will start with a quick recap of what Zenaton is and some of the vocabulary we use. Then, we will get your feet wet by having you run a couple of sample workflows through Zenaton.
Let’s dive right in! 🐬
🗣 Talking the talk ️
Let’s start by defining a couple of common terms used throughout Zenaton:
- Tasks can be either atomic operations such as sending an email, or waiting tasks such as idling for an amount of time, until a certain date, or until a given event happens.
- Events are hooks you can define to trigger one or multiple tasks. An order being placed might be an example of an event.
- Workflows are the control flows where you can define how tasks are executed (sequentially, in parallel, asynchronously, etc), and how events should be processed.
One of nice things about using Zenaton is that you can write any of these in the language you want: Ruby, JavaScript, PHP, Python and Go (with more languages coming soon 🙌). From your side, other than writing your workflows, all you have to do have your application start your workflows and have worker instances provisioned with Zenaton’s Agent to process them.
On the other side, Zenaton will take care of orchestrating tasks execution, abstracting away the message broker, managing the queues and persisting state. Additionally, we also provide you visibility into your workflows, with monitoring and tasks retrial through our dashboard.
For a more detailed presentation you can check some of our past articles:
Enough talking, let’s get down to it and run our very first workflows! 💪
🚶♀️Walking the walk
In order to follow this tutorial, you will need a Zenaton account. If you don’t already have one, head over to https://zenaton.com and sign up for one.
To get you up and running quickly, we have written a small collection of sample workflows, grab them by cloning zenaton/examples-ruby. From the root of directory run bundle install
to install the required gems 💎. Now, copy the provided .env.example
, edit it with your credentials (you can get them from your dashboard), and finally save it as .env
.
Now we need to install the Agent. You have a couple of options:
- Install it locally with
curl https://install.zenaton.com | sh
, which will auto-start the Agent. You can now tell it to listen for new workflows by typingzenaton listen --boot=boot.rb
. - If your OS is not yet supported, such as Windows or some Linux flavours, you can run the Agent inside a Docker container 🐳. The repository contains one ready for consumption. Simply run
docker-compose build; docker-compose up
and you are good to go.
If you are eager to run your first workflow, simply execute from your terminal ruby launch_sequential.rb
. You can see the output in zenaton.out
.
Tip: to see the results as they come in, you may want to run either
tail -f zenaton.out
watch -n 1 cat zenaton.out
If you want a closer look 🔎 at what is happening under the hood, let’s step through some of the different components. To create your own task , you will need to create a class that
- inherits from
Zenaton::Interfaces::Task.
- includes the
Zenaton::Traits::Zenatonable
module, which will add some behaviours to allow us to orchestrate it. - implements an instance method
handle
, which is called when your task is executed by the Agent.
class TaskA < Zenaton::Interfaces::Task
include Zenaton::Traits::Zenatonable
def handle
puts 'Task A starts'
sleep 3 # Task takes some time to complete
puts 'Task A ends'
0 # The result of the task
end
end
Similarly, to create your own workflow, the recipe is almost identical. The only difference being that Zenaton::Interfaces::Workflow
should be the superclass your class inherits from.
class SequentialWorkflow < Zenaton::Interfaces::Workflow
include Zenaton::Traits::Zenatonable
def handle
a = TaskA.new.execute # Let's store the return value from the task
if a > 0 # And use that value to determine which task to run next
TaskB.new.execute
else
TaskC.new.execute
end
TaskD.new.execute # This gets execute in either cases
end
end
Finally, to launch your workflow
- Initialize the client.
- Instantiate your workflow and call
dispatch
on it. This method is provided by theZenatonable
module.
require 'zenaton'
Zenaton::Client.init(
app_id, # You application ID
api_token, # Your API token
app_env # production, staging, development, or whatever you want
)
SequentialWorkflow.new.dispatch
For more details please you follow our tutorial from our website, which walks you through the various examples from the repository:
- Run tasks one after the other:
ruby launch_sequential.rb
- Run tasks in parallel:
ruby launch_parallel.rb
- Run tasks asynchronously:
ruby launch_asynchronous.rb
- Send events to running workflows:
ruby launch_event.rb
- Tell a workflow to wait:
ruby launch_wait.rb
- Tell a workflow to wait for an event:
ruby launch_wait_event.rb
- Launch a workflow from another workflow:
ruby launch_recursive.rb
- Modify running workflows, allowing you to keep old ones running while deploying new versions at the same time:
ruby launch_version.rb
Don’t be afraid to experiment 🔬 , and do share your findings with us. Here are a couple of ideas for you to try:
- Stop the Agent (
zenaton stop
) during a workflow execution, then resume it (zenaton start && zenaton listen boot=boot.rb
) , and see the execution pick up where it left off. - Check you dashboard to monitor your workflows, raise an error inside a task, see it fail on the dashboard, remove the exception from your task, relaunch the task from your dashboard, and see it finish successfully.
For more information, including how to integrate Zenaton with a Ruby on Rails application, check out our documentation. 📖
We hope that reading this will give your imagination some legs. We are curious about what you will come up with or how you might integrate Zenaton into an existing project. If you run into any troubles, have any questions, or want to give us some feedback, you can hit me up at igor@zenaton.com, file an issue on GitHub, or leave a comment 👇.