Skip to content

Thread-local SCP Tracing Plugin #3

@ffloyd

Description

@ffloyd

Problem

When you're debugging a business logic based on SharedContextPipeline it's nice to have an optional ability to temporarily turn on logging of a steps' execution. But writing it just to a text log is not convenient for debugging - because the text is not data.

Proposal

Let's use thread local variables to store execution history. The code below is merely a basic example and final behavior might be different.

class ApplicationOperation < Flows::SharedContextPipeline
  if Rails.env.development? || Rails.env.test?
    include Flows::Plugin::Tracing
   
    tracing true
  end
end

class MyOperation << ApplicationOperation
  # some steps here
  # some another operation can be executed inside steps
end

# use via wrap
trace = Flows::Plugin::Tracing.wrap do
  MyOperation.call(a: 1, b: 2)
end

# use via toggles
Flows::Plugin::Tracing.start
MyOperation.call(a: 1, b: 2)
trace = Flow::Plugin::Tracing.finish


puts trace.to_s
# Will print all the steps executions for all the operations
# inherited from ApplicationOperation. The order is the execution order.
# Output contains operation class name, step name, context string representation
# at the moment of step execution, a string representation of
# returned Result Object and WALL execution time.

trace.to_a
# returns the same data in the form of an array of 1-level deep hashes.

trace.benchmark.to_s
trace.benchmark.to_a
# contains statistic about slowest operations and steps,
# also counts executions and calculates average execution WALL time

trace.benchmark.to_plantuml
# it's also possible to draw UML Activity diagrams in PlantUML format.
# It includes benchmark info and visualizes execution-time relations between operations.

Implementation hints and requirements

Ruby is mutable. If you just save some hash into tracing data - it can be changed during the rest of execution. #dup, #clone and #freeze have no guarantees about nested data.

Therefore, the most reliable way is to serialize data to String using #inspect and store this string inside tracing data objects.

#6 must be done before this work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions