Skip to content

devdug/trailblazer-activity

 
 

Repository files navigation

Activity

An activity is a collection of connected tasks with one start event and one (or many) end events.

Installation

To use activities you need one gem, only.

gem "trailblazer-activity"

Overview

Since TRB 2.1, we use BPMN lingo and concepts for describing workflows and processes.

An activity is a workflow that contains one or several tasks. It is the main concept to organize control flow in Trailblazer.

The following diagram illustrates an exemplary workflow where a user writes and publishes a blog post.

After writing and spell-checking, the author has the chance to publish the post or, in case of typos, go back, correct, and go through the same flow, again. Note that there's only a handful of defined transistions, or connections. An author, for example, is not allowed to jump from "correct" into "publish" without going through the check.

The activity gem allows you to define this activity and takes care of implementing the control flow, running the activity and making sure no invalid paths are taken.

Your job is solely to implement the tasks and deciders put into this activity - Trailblazer makes sure it is executed it in the right order, and so on.

To eventually run this activity, three things have to be done.

  1. The activity needs be defined. Easiest is to use the Activity.from_hash builder.
  2. It's the programmer's job (that's you!) to implement the actual tasks (the "boxes"). Use tasks for that.
  3. After defining and implementing, you can run the activity with any data by calling it.

Operation vs. Activity

An Activity allows to define and maintain a graph, that at runtime will be used as a "circuit". Or, in other words, it defines the boxes, circles, arrows and signals between them, and makes sure when running the activity, the circuit with your rules will be executed.

Please note that an Operation simply provides a neat DSL for creating an Activity with a railway-oriented wiring (left and right track). An operation always maintains an activity internally.

class Create < Trailblazer::Operation
  step :exists?, pass_fast: true
  step :policy
  step :validate
  fail :log_err
  step :persist
  fail :log_db_err
  step :notify
end

Check the operation above. The DSL to create the activity with its graph is very different to Activity, but the outcome is a simple activity instance.

When calling an operation, several transformations on the arguments are applied, and those are passed to the Activity#call invocation. After the activity finished, its output is transformed into a Result object.

Activity

To understand how an activity works and what it performs in your application logic, it's easiest to see how activities are defined, and used.

Activity: From_Hash

Instead of using an operation, you can manually define activities by using the Activity.from_hash builder.

activity = Activity.from_hash do |start, _end|
  {
    start            => { Trailblazer::Circuit::Right => Blog::Write },
    Blog::Write      => { Trailblazer::Circuit::Right => Blog::SpellCheck },
    Blog::SpellCheck => { Trailblazer::Circuit::Right => Blog::Publish,
                          Trailblazer::Circuit::Left => Blog::Correct },
    Blog::Correct    => { Trailblazer::Circuit::Right => Blog::SpellCheck },
    Blog::Publish    => { Trailblazer::Circuit::Right => _end }
  }
end

The block yields a generic start and end event instance. You then connect every task in that hash (hash keys) to another task or event via the emitted signal.

Activity: Call

To run the activity, you want to call it.

my_options = {}
last_signal, options, flow_options, _ = activity.( nil, my_options, {} )
  1. The start event is called and per default returns the generic signalTrailblazer::Circuit::Right.
  2. This emitted (or returned) signal is connected to the next task Blog::Write, which is now called.
  3. Blog::Write emits another Right signal that leads to Blog::SpellCheck being called.
  4. Blog::SpellCheck defines two outgoing signals and hence can decide what next task to call by emitting either Right if the spell check was ok, or Left if the post contains typos.
  5. ...and so on.

Visualizing an activity as a graph makes it very straight-forward to understanding the mechanics of the flow.

Note how signals translate to edges (or connections) in the graph, and tasks become vertices (or nodes).

The return values are the last_signal, which is usually the end event (they return themselves as a signal), the last options that usually contains all kinds of data from running the activity, and additional args.

More

The full documentation for this gem and many more interesting things can be found on the Trailblazer website.

About

The main element for Trailblazer's BPMN-compliant workflows.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 100.0%