Skip to content

Commit

Permalink
make Debugger an activity, which is much easier now to follow.
Browse files Browse the repository at this point in the history
  • Loading branch information
apotonick committed May 31, 2024
1 parent 6e539f5 commit 8a21668
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 60 deletions.
2 changes: 1 addition & 1 deletion lib/trailblazer/pro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ module Pro
require_relative "pro/client"
require_relative "pro/trace/store"
require_relative "pro/trace/wtf"
require_relative "pro/debugger"
require_relative "pro/debugger/push"
require_relative "pro/debugger"
require_relative "pro/call/activity"
require_relative "pro/operation/call"
require_relative "pro/operation/WTF"
Expand Down
95 changes: 41 additions & 54 deletions lib/trailblazer/pro/debugger.rb
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
module Trailblazer
module Pro
module Debugger
module_function

# Called in {Trace::Present.call} as {:render_method}.
# This method always returns [output, *], where {output}
# is an arbitrary string to be written to the logger or CLI.
def call(activity:, render_wtf: false, **options)
output = ""

trace_data = render_trace_data(activity: activity, **options)
trace_envelope = trace_envelope_for(activity: activity, trace_data: trace_data)

session, stored_trace_id, session_updated = push(trace_envelope, activity: activity, **options)

if render_wtf
output += render_original_wtf_trace(**options)
end

# This block covers when something in {push} above went wrong.
if session.nil?
output += stored_trace_id
return output, []
end

debugger_link, debugger_url = render_debugger_link(stored_trace_id: stored_trace_id, activity: activity)

output += debugger_link

returned_values = [session, stored_trace_id, debugger_url, trace_envelope, session_updated]

return output, returned_values
# Called in {Trace::Present.call} as {:render_method}.
# This method always returns [output, *], where {output}
# is an arbitrary string to be written to the logger or CLI.
def self.invoke_debugger(**kws)
_, (ctx, _) = Activity::TaskWrap.invoke(Debugger, [{now: DateTime.now, **kws, output: []}, {}])

return ctx[:output], [ctx[:session], ctx[:id], ctx[:debugger_url], ctx[:data_to_store], ctx[:session_updated]]
end

# This is the {:render_method} implementation (for Trace::Present)
# when using PRO's wtf.
class Debugger < Trailblazer::Activity::Railway
step :render_trace_data
step :trace_envelope_for
step Subprocess(Push)
step :render_original_wtf_trace
fail :render_original_wtf_trace, id: "fail.render_original_wtf_trace"
fail :trace_with_appended_error_message
step :render_debugger_link
step :compile_output
fail :compile_output, id: "fail.compile_output"

def trace_with_appended_error_message(ctx, error_message:, output:, **)
ctx[:output] << error_message
end

def render_trace_data(debugger_trace:, activity:, **)
def render_trace_data(ctx, debugger_trace:, activity:, **)
flat_tree_json = debugger_trace.to_a.collect do |debugger_node|

# TODO: do we even need to grab tw by path here?
introspect_nodes_node = OpenStruct.new(task: debugger_node.task)
tw_render = Developer::Render::TaskWrap.render_for(debugger_node.activity, introspect_nodes_node)

# This rendering code has deep knowledge of Trace/pro/v1 tracing interface.
{
ctx[:trace_data] = {
id: debugger_node.id.to_s,
runtime_id: debugger_node.runtime_id,
level: debugger_node.level,
Expand All @@ -58,15 +51,15 @@ def render_trace_data(debugger_trace:, activity:, **)
}
end

JSON.dump(
ctx[:trace_data] = JSON.dump(
nodes: flat_tree_json,
variable_versions: debugger_trace.to_h[:variable_versions].to_h,
pro_version: Pro::VERSION.to_s,
)
end

def trace_envelope_for(activity:, trace_data:)
{
def trace_envelope_for(ctx, activity:, trace_data:, **)
ctx[:data_to_store] = {
fields: {
activity_name: {stringValue: activity},
trace: {stringValue: trace_data},
Expand All @@ -75,36 +68,30 @@ def trace_envelope_for(activity:, trace_data:)
}
end

def render_original_wtf_trace(debugger_trace:, renderer:, color_map: Developer::Wtf::Renderer::DEFAULT_COLOR_MAP, **)
def render_original_wtf_trace(ctx, render_wtf: false, debugger_trace:, renderer:, output:, color_map: Developer::Wtf::Renderer::DEFAULT_COLOR_MAP, **)
return true unless render_wtf
# TODO: take the color_map from outside caller.
wtf_output = Developer::Trace::Present.render(debugger_trace: debugger_trace, renderer: renderer, color_map: Developer::Wtf::Renderer::DEFAULT_COLOR_MAP) # , activity: activity

output = [wtf_output, output].join("\n")
ctx[:output] << wtf_output
end

def render_debugger_link(stored_trace_id:, activity:)
debugger_url = "https://ide.trailblazer.to/#{stored_trace_id}"
# :id is :stored_trace_id.
def render_debugger_link(ctx, id:, activity:, **)
debugger_url = "https://ide.trailblazer.to/#{id}"
# output = "[TRB PRO] view trace (#{activity}) at #{debugger_url}"
# output = Developer::Wtf::Renderer::String.bold(output)
link = Developer::Wtf::Renderer::String.bold("[TRB PRO] view trace (#{activity}) at ")
link += debugger_url # DISCUSS: what do we want bold here?

return link, debugger_url
end
ctx[:link] = link
ctx[:debugger_url] = debugger_url

# DISCUSS: who defaults {:now}?
def push(trace_data, activity:, now: DateTime.now, **options)
# signal, (ctx, _) = Trailblazer::Developer.wtf?(Push, [{now: now, data_to_store: trace_data, **options}, {}])
signal, (ctx, _) = Trailblazer::Activity.(Push, {now: now, data_to_store: trace_data, **options})
# signal, (ctx, _) = Push.invoke([{now: now, data_to_store: trace_data, **options}, {}])

session = ctx[:session]
stored_trace_id = ctx[:id]
session_updated = ctx[:session_updated]

return [nil, ctx[:error_message]] if signal.to_h[:semantic] == :failure # TODO: what to return?
ctx[:output] << link
end

return session, stored_trace_id, session_updated
def compile_output(ctx, output:, **)
ctx[:output] = output.join("\n")
end
end # Debugger
end
Expand Down
2 changes: 1 addition & 1 deletion lib/trailblazer/pro/debugger/push.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Trailblazer
module Pro
module Debugger
class Debugger < Trailblazer::Activity::Railway
class Push < Trailblazer::Activity::Railway
step Subprocess(Client::Connect), # TODO: assert that success/failure go to right Track.
Output(:failure) => Track(:failure),
Expand Down
3 changes: 2 additions & 1 deletion lib/trailblazer/pro/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def self.deserialize(json)
# pass session, e.g. from RAils/tmp
def self.initialize!(api_key:, id_token: nil, render_wtf: true, **options)
Session.wtf_present_options = {
render_method: Trailblazer::Pro::Debugger,
# render_method: Trailblazer::Pro::Debugger,
render_method: Trailblazer::Pro.method(:invoke_debugger),
render_wtf: render_wtf,
# api_key: api_key,
# **options
Expand Down
41 changes: 41 additions & 0 deletions test/debugger_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,45 @@ def self.call(ctx, **)
assert_equal ctx[:error_message], %(Custom token couldn't be retrieved. HTTP status: 502)
assert_equal ctx[:session].trailblazer_pro_host, "https://testbackend-pro.trb.to"
end

it "what" do
class Create < Trailblazer::Activity::Railway
step :model

def model(ctx, **)
ctx[:model] = Object.new
end
end

Trailblazer::Pro.initialize!(api_key: api_key, trailblazer_pro_host: trailblazer_pro_host)

# Compute a {Debugger::Trace} using the normal {Wtf} and {Trace::Present} logic.
signal, (ctx, flow_options), circuit_options, output, returned_args = Trailblazer::Developer.wtf?(
Create,
[{}, {}],
present_options: {
render_method: ->(debugger_trace:, **) { ["i am the output", debugger_trace] }, # whatever we return from {:render_method} is available as {returned_args}
},
)

debugger_trace = returned_args

# NOTE: this tests private internals and hence looks a bit clumsy (especially retrieving the {debugger_trace}).
signal, (ctx, _) = Trailblazer::Developer.wtf?(Trailblazer::Pro::Debugger, [
{
debugger_trace: debugger_trace,
activity: Create,
renderer: Trailblazer::Developer::Trace::Present.method(:default_renderer),

output: [],
session: Trailblazer::Pro::Session.session,
# http: stubbed_http,
# data_to_store: {fields: {a: 1}},
# firestore_fields_template: session_static_options[:firestore_fields_template],
}, {}])

assert_equal ctx[:session].class, Trailblazer::Pro::Session # initialized session.
assert_equal ctx[:session_updated], true
assert_equal ctx[:id].size, 20
end
end
6 changes: 3 additions & 3 deletions test/present_options_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def model(ctx, **)
signal, (ctx, _), _, output, (token, trace_id, debugger_url, trace_envelope) = Trailblazer::Developer.wtf?(
Create,
[ctx, {}],
present_options: {render_method: Trailblazer::Pro::Debugger, session: uninitialized_session, render_wtf: true}, # FIXME: why do we have to pass {:session} here?
present_options: {render_method: Trailblazer::Pro.method(:invoke_debugger), session: uninitialized_session, render_wtf: true}, # FIXME: why do we have to pass {:session} here?
)

assert_equal output, %(PresentOptionsTest::Create
Expand All @@ -33,7 +33,7 @@ def model(ctx, **)
signal, (ctx, _), _, output, (token, trace_id, debugger_url, trace_envelope) = Trailblazer::Developer.wtf?(
Create,
[ctx, {}],
present_options: {render_method: Trailblazer::Pro::Debugger, session: uninitialized_session, render_wtf: false}, # FIXME: why do we have to pass {:session} here?
present_options: {render_method: Trailblazer::Pro.method(:invoke_debugger), session: uninitialized_session, render_wtf: false}, # FIXME: why do we have to pass {:session} here?
)

assert_equal output, %(\e[1m[TRB PRO] view trace (PresentOptionsTest::Create) at \e[22mhttps://ide.trailblazer.to/#{trace_id})
Expand All @@ -46,7 +46,7 @@ def model(ctx, **)
signal, (ctx, _), _, output, (token, trace_id, debugger_url, trace_envelope) = Trailblazer::Developer.wtf?(
Create,
[ctx, {}],
present_options: {render_method: Trailblazer::Pro::Debugger, session: uninitialized_session},
present_options: {render_method: Trailblazer::Pro.method(:invoke_debugger), session: uninitialized_session},
)

assert_equal trace_id.size, 20
Expand Down

0 comments on commit 8a21668

Please sign in to comment.