{{ page.title }}

  • Last updated 05 May 2017
  • representable v3.0

Developer

  • Last updated 30 Jan 20

Trailblazer provides a rich set of developer tools to ease debugging and make modelling processes a pleasant experience.

Developer Gem

The developer gem contains tools to help you visualize and debug Trailblazer code. Its development features such as tracing or exception handling are advanced tools and will become your best friends very quickly.

Constant

We advise you to alias the Developer constant to something handy, such as ::Dev in your project. For instance, in Rails you’d have the following line in a config/initializers/trailblazer.rb initializer.


# config/initializers/trailblazer.rb
require "trailblazer/developer"
Dev = Trailblazer::Developer

Wtf?

Use wtf? if you want to

  • Debug an exception happening somewhere deep in your code.
  • Find out which step changed the track to failure.
  • Focus on specific step(s) to find out what ctx mutations are happening inside them.

This will run your activity with tracing enabled, and in case of an exception, print the trace path to the closest point where the exception was thrown.

Your activity will be called using the TaskWrap invoker, a possible exception will be caught and the closest task found. It then prints the “stack trace”, however, on a much higher level based on tasks, not methods.

Please note that this is a higher-level debugging tool that does not confront you with a 200-lines stack trace the way Ruby does it, but pinpoints the exceptional code and locates the problem on a task level.

This is possible due to you structuring code into higher abstractions, tasks and activities.

You can focus on specific steps and variables to find out what ctx comes in and what goes out. The focus_on option allows us to capture any key(s) from ctx and print any mutations happening within given steps.

You need to pass one or more step names (either default name or given by explicit :id) to capture the mutations.


class Memo::Create < Trailblazer::Activity::Path
  step :validate
  step :create, id: :create_memo
  # ...
end

Dev.wtf?(Memo::Create, [ctx, { focus_on: { steps: [:validate, :create_memo] } }])

By default, focusing will capture whole ctx for given steps. But you can also filter on it by passing one or more keys using variables.


Dev.wtf?(Memo::Create, [ctx, { focus_on: { variables: [:params], steps: :validate } }])

Internally, when focus_on option is passed, we call Object#inspect method to collect before-after data from the ctx for given steps. This data is then used while rendering the trace. In case you want to customize the data collection behaviour with your own logic, you can pass the default_inspector.


Dev.wtf?(
  Memo::Create,
  [
    { params: { text: 'Hydrate!', value: nil } },
    {
      focus_on: { steps: :validate, variables: :params },
      default_inspector: ->(value){ value.nil? ? 'UNKNOWN' : value.inspect }
    }
  ]
)

Inspection runs deeply when ctx contains nested structures like hashes or arrays. It’s concept is very simple and handled in Dev::Trace::Inspector module.

The sole purpose to add Dev::Trace::Inspector module is to make custom inspection possible and efficient while tracing. For example, ActiveRecord::Relation#inspect makes additional queries to fetch top 10 records and generate the output everytime.


To avoid this, Inspector will not call inspect method when it finds such objects (deeply nested anywhere).

Instead, it’ll call AR::Relation#to_sql to get plain SQL query which doesn’t make additional queries and is better to understand in tracing output. There is always a possibility to cater such cases and make wtf tracing better. Contributions are welcome :)

The color_map option allows you to customize default coloring scheme being used to render passed or failed steps.

Render

puts Trailblazer::Developer.render(Memo::Create)

Render Linear

Client

The Developer::Client module provides functions to work with activities and workflows created in the PRO editor.

Notes

  • IDs are extracted from the label of the element. They get chomped to remove a potential newline at the end and reduce confusion.
  • It is currently not possible to assign semantics to arrows via the label. In the meantime, use the :query option. # TODO

Editor

Whether you want to visualize a complex operation or model a long-running business process with dozens of steps, resume/suspend points and different branches, the editor will be your best friend.

You can import diagrams from the command line into your project using the trailblazer-developer gem, transform them into Ruby and implement the steps with your own business logic.

We use a subset of BPMN for the visual language in the editor, but added our own set of restrictions and semantics to it. It is possible to organize huge applications and their workflows in our editor backend, model and debug visually, and import them into your real Ruby applications.

Known Bugs

The current editor is first-generation and was about 2 years of work. It is sufficient to work with and allows creating complex workflows and collaborations. We use it in several commercial projects.

There are a bunch of known issues with the first-generation editor. Always save your diagram after you added or rearranged a new element. You can then reload should you encounter a bug.

We decided to invest into refactoring and are working on gen2. The new version simplifies many tasks, has much better handling of arrows, etc.

  • Arrows or connections are a PITA in more complex diagrams. When dragging arrows, they might suddenly snap to some random point or even add another joint. It is very hard to rearrange arrows laying behind other objects. This is one main reason we’re working hard on gen2.
  • You can’t label arrows. This is annoying when a task or event has several outgoing arrows - you’re not able to assign a semantic via the editor. In the meantime, you can do this by #TODO

Hello hello early birds

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ac ligula convallis, mollis velit eu, porta odio. Proin nibh ipsum, bibendum eu auctor volutpat, consectetur vitae erat. Duis condimentum dapibus hendrerit.