dexkit 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -1
- data/README.md +63 -254
- data/gemfiles/mongoid_no_ar.gemfile.lock +2 -2
- data/guides/llm/EVENT.md +25 -26
- data/guides/llm/FORM.md +200 -59
- data/guides/llm/OPERATION.md +115 -57
- data/guides/llm/QUERY.md +56 -0
- data/guides/llm/TOOL.md +308 -0
- data/lib/dex/context_dsl.rb +56 -0
- data/lib/dex/context_setup.rb +2 -33
- data/lib/dex/event/bus.rb +79 -11
- data/lib/dex/event/handler.rb +18 -1
- data/lib/dex/event/metadata.rb +15 -20
- data/lib/dex/event/processor.rb +2 -16
- data/lib/dex/event/test_helpers.rb +1 -1
- data/lib/dex/event.rb +3 -10
- data/lib/dex/form/context.rb +27 -0
- data/lib/dex/form/export.rb +128 -0
- data/lib/dex/form/nesting.rb +2 -0
- data/lib/dex/form.rb +119 -3
- data/lib/dex/id.rb +125 -0
- data/lib/dex/operation/async_proxy.rb +22 -4
- data/lib/dex/operation/guard_wrapper.rb +1 -1
- data/lib/dex/operation/jobs.rb +5 -4
- data/lib/dex/operation/once_wrapper.rb +1 -0
- data/lib/dex/operation/outcome.rb +14 -0
- data/lib/dex/operation/record_backend.rb +2 -1
- data/lib/dex/operation/record_wrapper.rb +14 -4
- data/lib/dex/operation/result_wrapper.rb +0 -12
- data/lib/dex/operation/test_helpers/assertions.rb +0 -88
- data/lib/dex/operation/test_helpers.rb +11 -1
- data/lib/dex/operation/ticket.rb +268 -0
- data/lib/dex/operation/trace_wrapper.rb +20 -0
- data/lib/dex/operation.rb +3 -0
- data/lib/dex/operation_failed.rb +14 -0
- data/lib/dex/query/export.rb +64 -0
- data/lib/dex/query.rb +41 -0
- data/lib/dex/test_log.rb +62 -4
- data/lib/dex/timeout.rb +14 -0
- data/lib/dex/tool.rb +388 -5
- data/lib/dex/trace.rb +291 -0
- data/lib/dex/version.rb +1 -1
- data/lib/dexkit.rb +22 -3
- metadata +12 -3
- data/lib/dex/event/trace.rb +0 -56
- data/lib/dex/event_test_helpers.rb +0 -3
data/lib/dex/trace.rb
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dex
|
|
4
|
+
module Trace
|
|
5
|
+
FIBER_KEY = :_dex_trace
|
|
6
|
+
FRAME_TYPES = %i[actor operation handler].freeze
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def start(actor: nil, trace_id: nil)
|
|
10
|
+
previous = _dump_state
|
|
11
|
+
_set_state(trace_id: (trace_id || Dex::Id.generate("tr_")).to_s, frames: [], event_context: nil)
|
|
12
|
+
_state[:frames] << _normalize_actor(actor) if actor
|
|
13
|
+
yield
|
|
14
|
+
ensure
|
|
15
|
+
_restore_state(previous)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def ensure_started!(trace_id: nil)
|
|
19
|
+
return false if active?
|
|
20
|
+
|
|
21
|
+
_state[:trace_id] = (trace_id || Dex::Id.generate("tr_")).to_s
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def active?
|
|
26
|
+
!trace_id.nil?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def with_frame(frame)
|
|
30
|
+
auto_started = ensure_started!
|
|
31
|
+
pushed = false
|
|
32
|
+
push(frame)
|
|
33
|
+
pushed = true
|
|
34
|
+
yield
|
|
35
|
+
ensure
|
|
36
|
+
pop if pushed
|
|
37
|
+
stop! if auto_started
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def with_event_context(event)
|
|
41
|
+
auto_started = ensure_started!(trace_id: event.trace_id)
|
|
42
|
+
previous = _state[:event_context]
|
|
43
|
+
_state[:event_context] = _build_event_context(event)
|
|
44
|
+
yield
|
|
45
|
+
ensure
|
|
46
|
+
_state[:event_context] = previous
|
|
47
|
+
stop! if auto_started
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def restore_event_context(event_id:, trace_id:, event_class: nil, event_ancestry: [])
|
|
51
|
+
previous = _dump_state
|
|
52
|
+
effective_trace_id = trace_id&.to_s || _state[:trace_id]
|
|
53
|
+
_set_state(
|
|
54
|
+
trace_id: effective_trace_id,
|
|
55
|
+
frames: _normalize_frames(_state[:frames]),
|
|
56
|
+
event_context: {
|
|
57
|
+
id: event_id&.to_s,
|
|
58
|
+
trace_id: effective_trace_id,
|
|
59
|
+
event_class: event_class,
|
|
60
|
+
event_ancestry: Array(event_ancestry).compact.map(&:to_s)
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
yield
|
|
64
|
+
ensure
|
|
65
|
+
_restore_state(previous)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def push(frame)
|
|
69
|
+
_state[:frames] << _normalize_frame(frame)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def pop
|
|
73
|
+
_state[:frames].pop
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def current
|
|
77
|
+
_deep_copy(_state[:frames])
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def trace_id
|
|
81
|
+
_state[:trace_id]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def current_id
|
|
85
|
+
_state[:frames].last&.dig(:id)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def actor
|
|
89
|
+
frame = _state[:frames].find { |entry| entry[:type] == :actor }
|
|
90
|
+
frame ? _deep_copy(frame) : nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def current_event_id
|
|
94
|
+
current_event_context&.dig(:id)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def current_event_context
|
|
98
|
+
context = _state[:event_context]
|
|
99
|
+
return _deep_copy(context) if context
|
|
100
|
+
|
|
101
|
+
handler = _state[:frames].reverse.find { |frame| frame[:type] == :handler && frame[:event_id] }
|
|
102
|
+
return nil unless handler
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
id: handler[:event_id],
|
|
106
|
+
trace_id: trace_id,
|
|
107
|
+
event_class: handler[:event_class],
|
|
108
|
+
event_ancestry: _deep_copy(Array(handler[:event_ancestry]))
|
|
109
|
+
}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def dump
|
|
113
|
+
return nil unless active?
|
|
114
|
+
|
|
115
|
+
data = {
|
|
116
|
+
trace_id: trace_id,
|
|
117
|
+
frames: current
|
|
118
|
+
}
|
|
119
|
+
data[:event_context] = _deep_copy(_state[:event_context]) if _state[:event_context]
|
|
120
|
+
data
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def restore(data)
|
|
124
|
+
return yield unless data
|
|
125
|
+
|
|
126
|
+
previous = _dump_state
|
|
127
|
+
_set_state(
|
|
128
|
+
trace_id: _fetch(data, :trace_id)&.to_s,
|
|
129
|
+
frames: _normalize_frames(_fetch(data, :frames)),
|
|
130
|
+
event_context: _normalize_event_context(_fetch(data, :event_context))
|
|
131
|
+
)
|
|
132
|
+
yield
|
|
133
|
+
ensure
|
|
134
|
+
_restore_state(previous)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def to_s
|
|
138
|
+
current.filter_map { |frame| _format_frame(frame) }.join(" > ")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def clear!
|
|
142
|
+
Fiber[FIBER_KEY] = nil
|
|
143
|
+
end
|
|
144
|
+
alias_method :stop!, :clear!
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def _state
|
|
149
|
+
Fiber[FIBER_KEY] ||= { trace_id: nil, frames: [], event_context: nil }
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def _set_state(trace_id:, frames:, event_context:)
|
|
153
|
+
Fiber[FIBER_KEY] = {
|
|
154
|
+
trace_id: trace_id,
|
|
155
|
+
frames: frames,
|
|
156
|
+
event_context: event_context
|
|
157
|
+
}
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def _dump_state
|
|
161
|
+
state = _state
|
|
162
|
+
return nil unless state[:trace_id] || !state[:frames].empty? || state[:event_context]
|
|
163
|
+
|
|
164
|
+
{
|
|
165
|
+
trace_id: state[:trace_id],
|
|
166
|
+
frames: _deep_copy(state[:frames]),
|
|
167
|
+
event_context: _deep_copy(state[:event_context])
|
|
168
|
+
}
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def _restore_state(state)
|
|
172
|
+
if state
|
|
173
|
+
_set_state(
|
|
174
|
+
trace_id: state[:trace_id],
|
|
175
|
+
frames: _normalize_frames(state[:frames]),
|
|
176
|
+
event_context: _normalize_event_context(state[:event_context])
|
|
177
|
+
)
|
|
178
|
+
else
|
|
179
|
+
clear!
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def _normalize_frames(frames)
|
|
184
|
+
Array(frames).map { |frame| _normalize_frame(frame) }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def _normalize_actor(actor)
|
|
188
|
+
raise ArgumentError, "actor must be a Hash" unless actor.is_a?(Hash)
|
|
189
|
+
|
|
190
|
+
normalized = _symbolize(actor)
|
|
191
|
+
actor_type = normalized[:type]
|
|
192
|
+
raise ArgumentError, "actor must include :type" if actor_type.nil? || actor_type.to_s.strip.empty?
|
|
193
|
+
|
|
194
|
+
frame = { type: :actor, actor_type: actor_type.to_s }
|
|
195
|
+
frame[:id] = normalized[:id].to_s if normalized.key?(:id) && !normalized[:id].nil?
|
|
196
|
+
|
|
197
|
+
normalized.each do |key, value|
|
|
198
|
+
next if %i[type id].include?(key)
|
|
199
|
+
|
|
200
|
+
frame[key] = _deep_copy(value)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
frame
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def _normalize_frame(frame)
|
|
207
|
+
raise ArgumentError, "trace frame must be a Hash" unless frame.is_a?(Hash)
|
|
208
|
+
|
|
209
|
+
normalized = _symbolize(frame)
|
|
210
|
+
type = normalized[:type]&.to_sym
|
|
211
|
+
raise ArgumentError, "trace frame type is required" unless type
|
|
212
|
+
raise ArgumentError, "unknown trace frame type: #{type.inspect}" unless FRAME_TYPES.include?(type)
|
|
213
|
+
|
|
214
|
+
normalized[:type] = type
|
|
215
|
+
normalized[:id] = normalized[:id].to_s if normalized.key?(:id) && !normalized[:id].nil?
|
|
216
|
+
normalized[:actor_type] = normalized[:actor_type].to_s if normalized.key?(:actor_type) && !normalized[:actor_type].nil?
|
|
217
|
+
normalized[:event_id] = normalized[:event_id].to_s if normalized.key?(:event_id) && !normalized[:event_id].nil?
|
|
218
|
+
normalized[:event_ancestry] = Array(normalized[:event_ancestry]).compact.map(&:to_s) if normalized.key?(:event_ancestry)
|
|
219
|
+
normalized
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def _normalize_event_context(context)
|
|
223
|
+
return nil unless context
|
|
224
|
+
|
|
225
|
+
{
|
|
226
|
+
id: _fetch(context, :id)&.to_s,
|
|
227
|
+
trace_id: _fetch(context, :trace_id)&.to_s,
|
|
228
|
+
event_class: _fetch(context, :event_class),
|
|
229
|
+
event_ancestry: Array(_fetch(context, :event_ancestry)).compact.map(&:to_s)
|
|
230
|
+
}
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def _build_event_context(event)
|
|
234
|
+
{
|
|
235
|
+
id: event.id.to_s,
|
|
236
|
+
trace_id: event.trace_id.to_s,
|
|
237
|
+
event_class: event.class.name,
|
|
238
|
+
event_ancestry: Array(event.metadata.event_ancestry).compact.map(&:to_s)
|
|
239
|
+
}
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def _symbolize(hash)
|
|
243
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
244
|
+
result[key.respond_to?(:to_sym) ? key.to_sym : key] = _deep_copy(value)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def _deep_copy(value)
|
|
249
|
+
case value
|
|
250
|
+
when Hash
|
|
251
|
+
value.each_with_object({}) { |(key, nested), result| result[key] = _deep_copy(nested) }
|
|
252
|
+
when Array
|
|
253
|
+
value.map { |nested| _deep_copy(nested) }
|
|
254
|
+
else
|
|
255
|
+
value
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def _fetch(hash, key)
|
|
260
|
+
hash[key] || hash[key.to_s]
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def _format_frame(frame)
|
|
264
|
+
case frame[:type]
|
|
265
|
+
when :actor
|
|
266
|
+
return nil unless frame[:actor_type]
|
|
267
|
+
|
|
268
|
+
frame[:id] ? "#{frame[:actor_type]}:#{frame[:id]}" : frame[:actor_type]
|
|
269
|
+
when :operation
|
|
270
|
+
name = frame[:class] || "Operation"
|
|
271
|
+
id = _display_id(frame[:id])
|
|
272
|
+
id ? "#{name}(#{id})" : name
|
|
273
|
+
when :handler
|
|
274
|
+
event_class = frame[:event_class] || "Event"
|
|
275
|
+
handler_name = frame[:class] || "Handler"
|
|
276
|
+
id = _display_id(frame[:id])
|
|
277
|
+
id ? "[#{event_class}] #{handler_name}(#{id})" : "[#{event_class}] #{handler_name}"
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def _display_id(id)
|
|
282
|
+
return nil unless id
|
|
283
|
+
|
|
284
|
+
prefix, suffix = id.split("_", 2)
|
|
285
|
+
return id[0, 10] unless suffix
|
|
286
|
+
|
|
287
|
+
"#{prefix}_#{suffix[0, 7]}"
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
data/lib/dex/version.rb
CHANGED
data/lib/dexkit.rb
CHANGED
|
@@ -10,13 +10,18 @@ require_relative "dex/concern"
|
|
|
10
10
|
require_relative "dex/ref_type"
|
|
11
11
|
require_relative "dex/type_coercion"
|
|
12
12
|
require_relative "dex/props_setup"
|
|
13
|
+
require_relative "dex/context_dsl"
|
|
13
14
|
require_relative "dex/context_setup"
|
|
14
15
|
require_relative "dex/error"
|
|
16
|
+
require_relative "dex/operation_failed"
|
|
17
|
+
require_relative "dex/timeout"
|
|
15
18
|
require_relative "dex/settings"
|
|
16
19
|
require_relative "dex/pipeline"
|
|
17
20
|
require_relative "dex/executable"
|
|
18
21
|
require_relative "dex/registry"
|
|
19
22
|
require_relative "dex/type_serializer"
|
|
23
|
+
require_relative "dex/id"
|
|
24
|
+
require_relative "dex/trace"
|
|
20
25
|
require_relative "dex/operation"
|
|
21
26
|
require_relative "dex/event"
|
|
22
27
|
require_relative "dex/tool"
|
|
@@ -25,15 +30,13 @@ require_relative "dex/query"
|
|
|
25
30
|
|
|
26
31
|
module Dex
|
|
27
32
|
class Configuration
|
|
28
|
-
attr_accessor :record_class, :event_store
|
|
33
|
+
attr_accessor :record_class, :event_store
|
|
29
34
|
attr_reader :transaction_adapter
|
|
30
35
|
|
|
31
36
|
def initialize
|
|
32
37
|
@record_class = nil
|
|
33
38
|
@transaction_adapter = nil
|
|
34
39
|
@event_store = nil
|
|
35
|
-
@event_context = nil
|
|
36
|
-
@restore_event_context = nil
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
def transaction_adapter=(adapter)
|
|
@@ -77,6 +80,22 @@ module Dex
|
|
|
77
80
|
configuration.transaction_adapter = adapter
|
|
78
81
|
end
|
|
79
82
|
|
|
83
|
+
def actor
|
|
84
|
+
frame = Dex::Trace.actor
|
|
85
|
+
return nil unless frame
|
|
86
|
+
|
|
87
|
+
payload = frame.dup
|
|
88
|
+
payload.delete(:type)
|
|
89
|
+
payload[:type] = payload.delete(:actor_type) if payload.key?(:actor_type)
|
|
90
|
+
payload
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def system(name = nil)
|
|
94
|
+
h = { type: :system }
|
|
95
|
+
h[:name] = name.to_s if name
|
|
96
|
+
h.freeze
|
|
97
|
+
end
|
|
98
|
+
|
|
80
99
|
CONTEXT_KEY = :_dex_context
|
|
81
100
|
EMPTY_CONTEXT = {}.freeze
|
|
82
101
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dexkit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jacek Galanciak
|
|
@@ -167,7 +167,9 @@ files:
|
|
|
167
167
|
- guides/llm/FORM.md
|
|
168
168
|
- guides/llm/OPERATION.md
|
|
169
169
|
- guides/llm/QUERY.md
|
|
170
|
+
- guides/llm/TOOL.md
|
|
170
171
|
- lib/dex/concern.rb
|
|
172
|
+
- lib/dex/context_dsl.rb
|
|
171
173
|
- lib/dex/context_setup.rb
|
|
172
174
|
- lib/dex/error.rb
|
|
173
175
|
- lib/dex/event.rb
|
|
@@ -180,12 +182,13 @@ files:
|
|
|
180
182
|
- lib/dex/event/suppression.rb
|
|
181
183
|
- lib/dex/event/test_helpers.rb
|
|
182
184
|
- lib/dex/event/test_helpers/assertions.rb
|
|
183
|
-
- lib/dex/event/trace.rb
|
|
184
|
-
- lib/dex/event_test_helpers.rb
|
|
185
185
|
- lib/dex/executable.rb
|
|
186
186
|
- lib/dex/form.rb
|
|
187
|
+
- lib/dex/form/context.rb
|
|
188
|
+
- lib/dex/form/export.rb
|
|
187
189
|
- lib/dex/form/nesting.rb
|
|
188
190
|
- lib/dex/form/uniqueness_validator.rb
|
|
191
|
+
- lib/dex/id.rb
|
|
189
192
|
- lib/dex/match.rb
|
|
190
193
|
- lib/dex/operation.rb
|
|
191
194
|
- lib/dex/operation/async_proxy.rb
|
|
@@ -207,12 +210,16 @@ files:
|
|
|
207
210
|
- lib/dex/operation/test_helpers/assertions.rb
|
|
208
211
|
- lib/dex/operation/test_helpers/execution.rb
|
|
209
212
|
- lib/dex/operation/test_helpers/stubbing.rb
|
|
213
|
+
- lib/dex/operation/ticket.rb
|
|
214
|
+
- lib/dex/operation/trace_wrapper.rb
|
|
210
215
|
- lib/dex/operation/transaction_adapter.rb
|
|
211
216
|
- lib/dex/operation/transaction_wrapper.rb
|
|
217
|
+
- lib/dex/operation_failed.rb
|
|
212
218
|
- lib/dex/pipeline.rb
|
|
213
219
|
- lib/dex/props_setup.rb
|
|
214
220
|
- lib/dex/query.rb
|
|
215
221
|
- lib/dex/query/backend.rb
|
|
222
|
+
- lib/dex/query/export.rb
|
|
216
223
|
- lib/dex/query/filtering.rb
|
|
217
224
|
- lib/dex/query/sorting.rb
|
|
218
225
|
- lib/dex/railtie.rb
|
|
@@ -221,7 +228,9 @@ files:
|
|
|
221
228
|
- lib/dex/settings.rb
|
|
222
229
|
- lib/dex/test_helpers.rb
|
|
223
230
|
- lib/dex/test_log.rb
|
|
231
|
+
- lib/dex/timeout.rb
|
|
224
232
|
- lib/dex/tool.rb
|
|
233
|
+
- lib/dex/trace.rb
|
|
225
234
|
- lib/dex/type_coercion.rb
|
|
226
235
|
- lib/dex/type_serializer.rb
|
|
227
236
|
- lib/dex/version.rb
|
data/lib/dex/event/trace.rb
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Dex
|
|
4
|
-
class Event
|
|
5
|
-
module Trace
|
|
6
|
-
STACK_KEY = :_dex_event_trace_stack
|
|
7
|
-
|
|
8
|
-
class << self
|
|
9
|
-
include ExecutionState
|
|
10
|
-
|
|
11
|
-
def with_event(event, &block)
|
|
12
|
-
stack = _stack
|
|
13
|
-
stack.push(event.trace_frame)
|
|
14
|
-
yield
|
|
15
|
-
ensure
|
|
16
|
-
stack.pop
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def current_event_id
|
|
20
|
-
_stack.last&.dig(:id)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def current_trace_id
|
|
24
|
-
_stack.last&.dig(:trace_id)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def dump
|
|
28
|
-
frame = _stack.last
|
|
29
|
-
return nil unless frame
|
|
30
|
-
|
|
31
|
-
{ id: frame[:id], trace_id: frame[:trace_id] }
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def restore(data, &block)
|
|
35
|
-
return yield unless data
|
|
36
|
-
|
|
37
|
-
stack = _stack
|
|
38
|
-
stack.push(data)
|
|
39
|
-
yield
|
|
40
|
-
ensure
|
|
41
|
-
stack.pop if data
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def clear!
|
|
45
|
-
_execution_state[STACK_KEY] = []
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
49
|
-
|
|
50
|
-
def _stack
|
|
51
|
-
_execution_state[STACK_KEY] ||= []
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|