Zenaton white logo

Overview

Introduction

Zenaton is a backend service for implementing and running data and business processes into your software whether it is a background task or a long running workflow. Zenaton makes it easy to integrate external services and APIs into your app - and trigger a sequence of actions in your code based on events - or a lack of response - from APIs and other data sources.

  • Trigger tasks based or external events or user behaviour.
  • Fetch data and put it into storage.
  • Orchestration of tasks between internal and external services.
  • Build data pipelines or simple ETL processes.
  • Send real time alerts triggered by data from multiple services and complicated logic.

Browse through some of our real world examples ETL process, document validation, employee onboarding, real-time notifications, e-commerce workflows, ...

Instead of building and managing infrastructure to watch and manage background scripts and jobs, Zenaton allows you just write the business logic of your processes into your code, install the Zenaton agent on your servers and the Zenaton workflow engine handles the complex calculations and queuing. The agent on your workers will listen to a queuing system hosted for you by Zenaton, and when a task should be executed, the Agent will launch it and collect the output to send back to your Zenaton dashboard.

We provide a sophisticated backend engine to manage the orchestration of tasks by managing the queues and pushing the decisions down to your workers. And it's easy to scale up quickly just by adding more workers.

In addition, the Zenaton dashboard offers real-time monitoring for all of your tasks and workflows.

  • Real time monitoring of all tasks and workflows
  • Error handling and retry capabilities
  • Agent activity and server performance

Workflow monitoring

We provide a sophisticated backend engine to manage the orchestration of tasks by managing the queues and pushing the decisions down to your workers. To scale up quickly, just add more workers.

Why Zenaton?

We built Zenaton to give one developer the power and control of an entire team of software developers to manage sophisticated business and data processes.

Let's be honest. Building and managing infrastructure to manage background jobs is a pain. It includes spinning up a special server to manage the queuing system, managing states in a database, and then writing cron jobs and a lot of logic in your code. All of this infrastructure must be maintained, and there is very little visibility into how things are running. So when something goes wrong you have to read log files and check lots of places to figure out the problem and fix it.

With Zenaton, you can write the business logic for your tasks or workflows directly into your code in an easily readable format so that anyone on the team can understand the logic, troubleshoot and make changes.

We have made it easy to manage all of your background processes without having to worry about... well, everything.

  • Real-time monitoring of all of your background tasks and workflows on the Zenaton dashboard
  • Add new workers by installing the Zenaton Agent on your servers
  • Get notified when tasks fail and view or retry errors on the Zenaton dashboard
  • Read and change business logic through your code
  • Take advantage of our customer support! Just reach out.

Here is how it works:

  • when your code dispatches a task or a workflow, our library sends a request to a listening Agent
  • the Agent forwards this request to our Engine, which will orchestrate and monitor its processing
  • when a task should be processed immediately, our Engine sends a request to listening Agents (through queues that are automaticaly deployed and hosted for you)
  • the Agent receiving this message triggers the processing of the requested task, and sends back the result to our Engine
  • in case of a workflow, or if an error occurs, the Engine will handle the situation accordingly.

Zenaton why

Single Task vs. Workflows

When running background processes with Zenaton you can either write a single task or a write a sequence of related tasks within a workflow.

Single Task

Tasks are the basic building blocks of Zenaton. Tasks are where you code perform your actual work and there is no limitation on what you can do there. Processing of tasks is offloaded onto one of your servers (called a worker then), but usually different from the one from which they were dispatched.

A few examples of tasks:

  • Transform an image
  • Extract, Transform or Load data
  • Send a slack notification
  • Send an email

Using Zenaton library, writing a task is as simple as

<?php
use Zenaton\Interfaces\TaskInterface;
use Zenaton\Traits\Zenatonable;

class MyTask implements TaskInterface
{
    use Zenatonable;

    public function __construct(...)
    {
        // initialize properties
    }

    public function handle()
    {
        // task implementation
    }
}
const { Task } = require("zenaton");

module.exports = Task("MyTask", {
  init(...) {
    // initialize properties
  },
  async handle() {
    // task implementation
  }
});
require 'zenaton'

class MyTask < Zenaton::Interfaces::Task
  include Zenaton::Traits::Zenatonable

  def initialize(...)
    # initialize properties
  end

  def handle
    # task implementation
  end
end
from zenaton.abstracts.task import Task
from zenaton.traits.zenatonable import Zenatonable

class MyTask(Task, Zenatonable):
    def __init__(self, ...):
        # initialize properties
        
    def handle(self):
        # Your task implementation

Once Zenaton configured, dispatching a task to be processed on one of your workers is as easy as

(new MyTask())->dispatch();
await new MyTask().dispatch();
MyTask.new.dispatch
MyTask().dispatch()

Workflows

Workflows are a set of tasks intended to be processed in a specific order, despite the fact that each of them can have been processed on different machines. Things you can do with a workflow:

  • Handle errors in payment process
  • Operate data pipelines with multiple steps
  • Orchestrate an order from online request to delivery

Implementing worklows implies dealing with (notoriously difficult) distributed systems, where you have to deal with:

  • Task failures
  • Network failures
  • Lack of monitoring or alerting tools
  • Difficulty of having a global understanding of a workflow state
  • Complexity of updating workflow's logic
  • Managing intermediary systems such as crons or states in database

With Zenaton, writing such sequences is very easy. Whatever the complexity of your case, we handle all of the complexity for you:

  • Resuming a failed tasks is easy, it also resumes the workflow from where it failed
  • Automatically recovering from network issues
  • Real-time monitoring of your tasks and workflow
  • Real-time monitoring of infrastructure
  • Modifying your workflows is easy, even if some instances are still running
  • Coding your workflows is easy, even for time-sensitive or event-driven workflows

Using Zenaton library, writing a workflow is as simple as

<?php
    
use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Traits\Zenatonable;

class MyWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function __construct(...)
    {
        // initialize properties
    }

    public function handle()
    {
        // workflow implementation
    }
}
const { Workflow } = require("zenaton");

module.exports = Workflow("MyWorkflow", {
  init(...) {
    // initialize properties
  },
  async handle() {
    // workflow implementation
  }
});
require 'zenaton'

class MyWorkflow < Zenaton::Interfaces::Workflow
  include Zenaton::Traits::Zenatonable

  def initialize(...)
    # initialize properties
  end

  def handle
    # workflow implementation
  end
end
from zenaton.abstracts.workflow import Workflow
from zenaton.traits.zenatonable import Zenatonable

class MyWorkflow(Workflow, Zenatonable):
    def __init__(self, ...):
        # initialize properties
        
    def handle(self):
        # Your workflow implementation

Once Zenaton configured, dispatching a workflow to be processed on your workers is as easy as

(new MyWorkflow(...))->dispatch();
await new MyWorkflow(...).dispatch();
MyWorkflow.new(...).dispatch
MyWorkflow(...).dispatch()

With Zenaton, implementing a workflow is very easy as we use our prefered language. For example:

public function handle()
{
    $a = (new TaskA())->execute();

    if (0 < $a) {
        $b = (new TaskB($a))->execute();
    } else {
        $b = (new TaskC($a))->execute();
    }
    (new TaskD($b))->execute();
}
async handle() {
  const a, b;
  
  a = new TaskA().execute();

  if (0 < a) {
        b = new TaskB(a).execute();
    } else {
        b = new TaskC(a).execute();
    }
    new TaskD(b).execute();
}
def handle
    a = TaskA.new.execute

    if a > 0
      b = TaskB.new(a).execute
    else
      b = TaskC.new(a).execute
    end

    TaskD.new(b).execute
  end
def handle(self):

    a = TaskA().execute()

    if a > 0:
        b = TaskB(a).execute()
    else:
        b = TaskC(a).execute()

    TaskD(b).execute()