sqreen 1.21.0.beta3-java → 1.21.0-java
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 +28 -15
- data/lib/sqreen/condition_evaluator.rb +5 -6
- data/lib/sqreen/conditionable.rb +6 -24
- data/lib/sqreen/ecosystem.rb +29 -2
- data/lib/sqreen/ecosystem/databases/database_connection_data.rb +23 -0
- data/lib/sqreen/ecosystem/databases/mongo.rb +39 -0
- data/lib/sqreen/ecosystem/databases/mysql.rb +54 -0
- data/lib/sqreen/ecosystem/databases/postgres.rb +51 -0
- data/lib/sqreen/ecosystem/databases/redis.rb +36 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +4 -2
- data/lib/sqreen/ecosystem/messaging/bunny.rb +61 -0
- data/lib/sqreen/ecosystem/messaging/kafka.rb +70 -0
- data/lib/sqreen/ecosystem/messaging/kinesis.rb +66 -0
- data/lib/sqreen/ecosystem/messaging/sqs.rb +68 -0
- data/lib/sqreen/ecosystem/module_api/message_producer.rb +9 -3
- data/lib/sqreen/ecosystem/module_api/tracing/consumer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_api/tracing/messaging_data.rb +35 -0
- data/lib/sqreen/ecosystem/module_api/tracing/producer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_registry.rb +5 -1
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +7 -3
- data/lib/sqreen/ecosystem/tracing/modules/consumer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/determine_ip.rb +28 -0
- data/lib/sqreen/ecosystem/tracing/modules/producer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_consumer.rb +56 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_producer.rb +56 -0
- data/lib/sqreen/ecosystem_integration.rb +1 -7
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +10 -20
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +4 -8
- data/lib/sqreen/graft/call.rb +1 -21
- data/lib/sqreen/graft/hook.rb +75 -83
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +2 -0
- data/lib/sqreen/metrics.rb +0 -1
- data/lib/sqreen/rules/custom_error_cb.rb +1 -1
- data/lib/sqreen/rules/rule_cb.rb +2 -2
- data/lib/sqreen/runner.rb +12 -27
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +14 -3
- data/lib/sqreen/weave/legacy/instrumentation.rb +94 -145
- metadata +22 -9
- data/lib/sqreen/ecosystem/redis/redis_connection.rb +0 -43
- data/lib/sqreen/metrics/req_detailed.rb +0 -41
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'sqreen/kit/configuration'
|
2
|
+
require 'sqreen/kit/signals/point'
|
3
|
+
require 'sqreen/kit/signals/dto_helper'
|
4
|
+
|
5
|
+
# reference: https://github.com/sqreen/SignalsSchemas/blob/master/schemas/payload/tracing/producer-2020-04-21/schema.cue
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
module Ecosystem
|
9
|
+
module Tracing
|
10
|
+
module Signals
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Sqreen::Ecosystem::Tracing::Signals::TracingProducer < Sqreen::Kit::Signals::Point
|
17
|
+
readonly_attrs :payload_schema, :source, :signal_name
|
18
|
+
|
19
|
+
def initialize(values = {})
|
20
|
+
self.payload_schema = Payload::SCHEMA_VERSION
|
21
|
+
self.source = Sqreen::Kit::Configuration.default_source
|
22
|
+
self.signal_name = 'tracing.producer'
|
23
|
+
self.time = values[:time] || Time.now
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def payload=(payload)
|
28
|
+
unless payload.is_a?(Payload)
|
29
|
+
raise ArgumentError, "Payload should be a #{Payload}"
|
30
|
+
end
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
class Payload
|
35
|
+
include Sqreen::Kit::Signals::DtoHelper
|
36
|
+
|
37
|
+
add_mandatory_attrs :message_type, :host, :tracing_identifier
|
38
|
+
|
39
|
+
SCHEMA_VERSION = 'tracing/producer-2020-04-21'.freeze
|
40
|
+
|
41
|
+
# @return [Symbol]
|
42
|
+
attr_accessor :message_type
|
43
|
+
|
44
|
+
# @return [String]
|
45
|
+
attr_accessor :host
|
46
|
+
|
47
|
+
# @return [String]
|
48
|
+
attr_accessor :ip
|
49
|
+
|
50
|
+
# @return [String]
|
51
|
+
attr_accessor :topic
|
52
|
+
|
53
|
+
# @return [String]
|
54
|
+
attr_accessor :tracing_identifier
|
55
|
+
end
|
56
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'sqreen/log/loggable'
|
2
|
-
require 'sqreen/metrics_store'
|
3
2
|
require 'sqreen/ecosystem'
|
4
3
|
require 'sqreen/ecosystem/dispatch_table'
|
5
|
-
require 'sqreen/ecosystem_integration/around_callbacks'
|
6
4
|
require 'sqreen/ecosystem_integration/instrumentation_service'
|
7
5
|
require 'sqreen/ecosystem_integration/request_lifecycle_tracking'
|
8
6
|
require 'sqreen/ecosystem_integration/signal_consumption'
|
@@ -19,12 +17,9 @@ module Sqreen
|
|
19
17
|
include Sqreen::Log::Loggable
|
20
18
|
|
21
19
|
# @param [Sqreen::Framework] framework
|
22
|
-
|
23
|
-
def initialize(framework, queue, create_binning_metric)
|
20
|
+
def initialize(framework, queue)
|
24
21
|
@framework = framework
|
25
22
|
@queue = queue
|
26
|
-
# XXX: created metrics are insulated from feature upgrades
|
27
|
-
@create_binning_metric = create_binning_metric
|
28
23
|
@request_lifecycle = RequestLifecycleTracking.new
|
29
24
|
@online = false
|
30
25
|
end
|
@@ -33,7 +28,6 @@ module Sqreen
|
|
33
28
|
raise 'already initialized' if @online
|
34
29
|
|
35
30
|
setup_dispatch_table
|
36
|
-
AroundCallbacks.create_metric = @create_binning_metric
|
37
31
|
Ecosystem.init
|
38
32
|
logger.info 'Ecosystem successfully initialized'
|
39
33
|
@online = true
|
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'sqreen/metrics_store'
|
2
1
|
require 'sqreen/log/loggable'
|
3
2
|
require 'sqreen/events/remote_exception'
|
4
3
|
require 'sqreen/mono_time'
|
5
|
-
require 'sqreen/graft/call'
|
6
4
|
|
7
5
|
module Sqreen
|
8
6
|
class EcosystemIntegration
|
@@ -10,32 +8,27 @@ module Sqreen
|
|
10
8
|
class << self
|
11
9
|
include Log::Loggable::ClassMethods
|
12
10
|
|
13
|
-
# @return [Proc]
|
14
|
-
attr_accessor :create_metric
|
15
|
-
|
16
11
|
# for instrumentation hooks
|
17
|
-
# instrumentation hooks already handle budgets
|
12
|
+
# instrumentation hooks already handle budgets, so nothing
|
13
|
+
# to do in that respect
|
18
14
|
def wrap_instrumentation_hook(module_name, action, callable)
|
19
|
-
|
20
|
-
# TODO: move to structured tags to avoid silly string manips
|
21
|
-
action_for_metric = if %w[pre post failing finally].include?(action)
|
22
|
-
action
|
23
|
-
else
|
24
|
-
'pre'
|
25
|
-
end
|
26
|
-
metric_name = "sq.ecosystem_#{module_name}.#{action_for_metric}"
|
27
|
-
create_metric.call(metric_name)
|
15
|
+
perf_notif_name = "ecosystem_#{module_name}"
|
28
16
|
|
29
17
|
Proc.new do |*args|
|
30
18
|
begin
|
19
|
+
start = Sqreen.time
|
31
20
|
callable.call(*args)
|
32
21
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
33
22
|
# 2) rescue exceptions
|
34
23
|
logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
|
35
24
|
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
36
25
|
Sqreen::RemoteException.record(e)
|
37
|
-
|
38
|
-
|
26
|
+
ensure
|
27
|
+
# 3) contribute to performance metrics
|
28
|
+
stop = Sqreen.time
|
29
|
+
Sqreen::PerformanceNotifications.notify(perf_notif_name, action, start, stop)
|
30
|
+
end # end proc
|
31
|
+
end # end begin
|
39
32
|
end
|
40
33
|
|
41
34
|
# XXX: not used yet
|
@@ -43,8 +36,6 @@ module Sqreen
|
|
43
36
|
timer_name = "ecosystem:#{module_name}@#{action}"
|
44
37
|
perf_notif_name = "ecosystem_#{module_name}"
|
45
38
|
|
46
|
-
# XXX: register metric
|
47
|
-
|
48
39
|
Proc.new do |*args|
|
49
40
|
begin
|
50
41
|
req_storage = Thread.current[:sqreen_http_request]
|
@@ -85,7 +76,6 @@ module Sqreen
|
|
85
76
|
if timer
|
86
77
|
req_timer.include_measurements(timer) if req_timer
|
87
78
|
|
88
|
-
# XXX: PerformanceNotifications is used no more
|
89
79
|
Sqreen::PerformanceNotifications.notify(
|
90
80
|
perf_notif_name, action, *timer.start_and_end
|
91
81
|
)
|
@@ -12,26 +12,22 @@ module Sqreen
|
|
12
12
|
hook = Sqreen::Graft::Hook[method].add do
|
13
13
|
if spec[:before]
|
14
14
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'pre', spec[:before])
|
15
|
-
|
16
|
-
before(tag, flow: true, &cb)
|
15
|
+
before(nil, flow: true, &cb)
|
17
16
|
end
|
18
17
|
|
19
18
|
if spec[:after]
|
20
19
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'post', spec[:after])
|
21
|
-
|
22
|
-
after(tag, flow: true, &cb)
|
20
|
+
after(nil, flow: true, &cb)
|
23
21
|
end
|
24
22
|
|
25
23
|
if spec[:raised]
|
26
24
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'failing', spec[:raised])
|
27
|
-
|
28
|
-
raised(tag, flow: true, &cb)
|
25
|
+
raised(nil, flow: true, &cb)
|
29
26
|
end
|
30
27
|
|
31
28
|
if spec[:ensured]
|
32
29
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'finally', spec[:ensured])
|
33
|
-
|
34
|
-
ensured(tag, flow: true, &cb)
|
30
|
+
ensured(nil, flow: true, &cb)
|
35
31
|
end
|
36
32
|
end
|
37
33
|
hook.install
|
data/lib/sqreen/graft/call.rb
CHANGED
@@ -27,10 +27,6 @@ module Sqreen
|
|
27
27
|
def raise(value)
|
28
28
|
Flow.raise(value)
|
29
29
|
end
|
30
|
-
|
31
|
-
def noop
|
32
|
-
Flow.noop
|
33
|
-
end
|
34
30
|
end
|
35
31
|
|
36
32
|
class Flow
|
@@ -50,17 +46,12 @@ module Sqreen
|
|
50
46
|
def raise(value)
|
51
47
|
new(:raise, value)
|
52
48
|
end
|
53
|
-
|
54
|
-
def noop
|
55
|
-
new(:noop, nil)
|
56
|
-
end
|
57
49
|
end
|
58
50
|
|
59
51
|
def initialize(action, value, brk = false)
|
60
52
|
@action = action
|
61
53
|
@value = value
|
62
54
|
@break = brk
|
63
|
-
@passed_conditions = false
|
64
55
|
end
|
65
56
|
|
66
57
|
def return?
|
@@ -100,16 +91,6 @@ module Sqreen
|
|
100
91
|
def break?
|
101
92
|
@break ? true : false
|
102
93
|
end
|
103
|
-
|
104
|
-
def passed_conditions!
|
105
|
-
@passed_conditions = true
|
106
|
-
|
107
|
-
self
|
108
|
-
end
|
109
|
-
|
110
|
-
def passed_conditions?
|
111
|
-
@passed_conditions
|
112
|
-
end
|
113
94
|
end
|
114
95
|
|
115
96
|
class TimerError < StandardError; end
|
@@ -120,7 +101,6 @@ module Sqreen
|
|
120
101
|
end
|
121
102
|
|
122
103
|
attr_reader :tag, :size
|
123
|
-
attr_accessor :conditions_passed
|
124
104
|
|
125
105
|
def initialize(tag, &block)
|
126
106
|
@tag = tag
|
@@ -225,7 +205,7 @@ module Sqreen
|
|
225
205
|
end
|
226
206
|
|
227
207
|
def to_s
|
228
|
-
"#{@tag}: time=%.03fus" % (
|
208
|
+
"#{@tag}: time=%.03fus" % (duration * 1_000_000)
|
229
209
|
end
|
230
210
|
|
231
211
|
protected
|
data/lib/sqreen/graft/hook.rb
CHANGED
@@ -7,8 +7,6 @@ require 'sqreen/graft'
|
|
7
7
|
require 'sqreen/graft/call'
|
8
8
|
require 'sqreen/graft/callback'
|
9
9
|
require 'sqreen/graft/hook_point'
|
10
|
-
require 'sqreen/weave'
|
11
|
-
require 'sqreen/runner' # Sqreen.queue
|
12
10
|
|
13
11
|
module Sqreen
|
14
12
|
module Graft
|
@@ -138,13 +136,6 @@ module Sqreen
|
|
138
136
|
request[:timed_callbacks] << t if request[:timed_level] >= 1
|
139
137
|
end
|
140
138
|
end
|
141
|
-
# very hacky, but the non-local control flow with throw-catch
|
142
|
-
# makes the solution non-obvious. needs to be revisited
|
143
|
-
conditions_passed_proc = proc do
|
144
|
-
if (request = Thread.current[:sqreen_http_request])
|
145
|
-
request[:timed_callbacks].last.conditions_passed = true
|
146
|
-
end
|
147
|
-
end
|
148
139
|
|
149
140
|
Proc.new do |*args, &block|
|
150
141
|
request = Thread.current[:sqreen_http_request]
|
@@ -192,15 +183,18 @@ module Sqreen
|
|
192
183
|
# budget implies request
|
193
184
|
# TODO: make budget depend on a generic context (currently "request")
|
194
185
|
budget = request[:time_budget] if request
|
195
|
-
if
|
186
|
+
if budget
|
187
|
+
budget_threshold = request[:time_budget_threshold]
|
188
|
+
budget_ratio = request[:time_budget_ratio]
|
196
189
|
sqreen_timer = request[:sqreen_timer]
|
190
|
+
request_timer = request[:request_timer]
|
197
191
|
end
|
198
192
|
|
199
193
|
hooked_call = HookedCall.new(self, args)
|
200
194
|
|
201
195
|
begin
|
202
196
|
begin
|
203
|
-
sqreen_timer.start if
|
197
|
+
sqreen_timer.start if budget
|
204
198
|
Thread.current[:sqreen_hook_entered] = true
|
205
199
|
|
206
200
|
# TODO: make Call have #ball to throw by cb
|
@@ -212,34 +206,34 @@ module Sqreen
|
|
212
206
|
# TODO: TimedHookCall TimedCallbackCall
|
213
207
|
# TODO: TimeBoundHookCall TimeBoundCallbackCall TimeBoundFlow?
|
214
208
|
|
209
|
+
request_elapsed = request_timer.elapsed if budget
|
210
|
+
|
215
211
|
hook.before.each do |c|
|
216
212
|
next if c.ignore && c.ignore.call
|
217
213
|
|
218
|
-
if budget && !c.mandatory
|
219
|
-
|
220
|
-
|
214
|
+
if budget && !c.mandatory
|
215
|
+
sqreen_elapsed = sqreen_timer.elapsed
|
216
|
+
if budget_ratio && !request[:time_budget_expended]
|
217
|
+
fixed_budget = budget_threshold
|
218
|
+
proportional_budget = (request_elapsed - sqreen_elapsed) * budget_ratio
|
219
|
+
remaining = (fixed_budget > proportional_budget ? fixed_budget : proportional_budget) - sqreen_elapsed
|
220
|
+
else
|
221
|
+
remaining = budget_threshold - sqreen_elapsed
|
222
|
+
end
|
223
|
+
unless remaining > 0
|
224
|
+
request[:skipped_callbacks] << c
|
225
|
+
request[:time_budget_expended] = true
|
226
|
+
next
|
227
|
+
end
|
221
228
|
end
|
222
229
|
|
223
|
-
remaining = budget - sqreen_timer.elapsed if budget
|
224
|
-
|
225
|
-
timer = nil
|
226
230
|
flow = catch(Ball.new) do |ball|
|
227
|
-
|
228
|
-
timer.measure(ignore: chrono) do
|
231
|
+
Timer.new(c.name, &timed_callbacks_proc).measure(ignore: chrono) do
|
229
232
|
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passed), ball)
|
230
233
|
end
|
231
234
|
end
|
232
235
|
|
233
|
-
if budget && timer
|
234
|
-
remaining -= timer.duration
|
235
|
-
if remaining < 0.0
|
236
|
-
request[:time_budget_expended]
|
237
|
-
request[:overtime_cb] = c.name
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
236
|
next unless c.flow && flow.is_a?(Flow)
|
242
|
-
conditions_passed_proc[] if flow.passed_conditions?
|
243
237
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
244
238
|
hooked_call.args_pass = flow.args and hooked_call.args_passing = true if flow.args?
|
245
239
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
@@ -254,7 +248,7 @@ module Sqreen
|
|
254
248
|
return hooked_call.return if hooked_call.returning
|
255
249
|
ensure
|
256
250
|
Thread.current[:sqreen_hook_entered] = false
|
257
|
-
sqreen_timer.stop if
|
251
|
+
sqreen_timer.stop if budget
|
258
252
|
end unless hook.before.empty?
|
259
253
|
|
260
254
|
begin
|
@@ -267,41 +261,41 @@ module Sqreen
|
|
267
261
|
end
|
268
262
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
269
263
|
begin
|
270
|
-
sqreen_timer.start if
|
264
|
+
sqreen_timer.start if budget
|
271
265
|
Thread.current[:sqreen_hook_entered] = true
|
272
266
|
hooked_call.raised = e
|
273
267
|
|
274
268
|
logger.debug { "[#{Process.pid}] Hook #{hook.point} disabled:#{hook.disabled?} exception:#{e}" } if logger_debug
|
275
269
|
raise if hook.raised.empty?
|
276
270
|
|
271
|
+
request_elapsed = request_timer.elapsed if budget
|
272
|
+
|
277
273
|
hook.raised.each do |c|
|
278
274
|
next if c.ignore && c.ignore.call
|
279
275
|
|
280
|
-
if budget && !c.mandatory
|
281
|
-
|
282
|
-
|
276
|
+
if budget && !c.mandatory
|
277
|
+
sqreen_elapsed = sqreen_timer.elapsed
|
278
|
+
if budget_ratio && !request[:time_budget_expended]
|
279
|
+
fixed_budget = budget_threshold
|
280
|
+
proportional_budget = (request_elapsed - sqreen_elapsed) * budget_ratio
|
281
|
+
remaining = (fixed_budget > proportional_budget ? fixed_budget : proportional_budget) - sqreen_elapsed
|
282
|
+
else
|
283
|
+
remaining = budget_threshold - sqreen_elapsed
|
284
|
+
end
|
285
|
+
unless remaining > 0
|
286
|
+
request[:skipped_callbacks] << c
|
287
|
+
request[:time_budget_expended] = true
|
288
|
+
next
|
289
|
+
end
|
283
290
|
end
|
284
291
|
|
285
|
-
remaining = budget - sqreen_timer.elapsed if budget
|
286
|
-
|
287
|
-
timer = nil
|
288
292
|
flow = catch(Ball.new) do |ball|
|
289
|
-
|
290
|
-
timer.measure(ignore: chrono) do
|
293
|
+
Timer.new(c.name, &timed_callbacks_proc).measure(ignore: chrono) do
|
291
294
|
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed, hooked_call.raised), ball)
|
292
295
|
end
|
293
296
|
end
|
294
297
|
|
295
|
-
if budget && timer
|
296
|
-
remaining -= timer.duration
|
297
|
-
if remaining < 0.0
|
298
|
-
request[:time_budget_expended]
|
299
|
-
request[:overtime_cb] = c.name
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
298
|
next unless c.flow && flow.is_a?(Flow)
|
304
|
-
conditions_passed_proc[] if flow.passed_conditions?
|
305
299
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
306
300
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
307
301
|
hooked_call.retrying = true if flow.retry?
|
@@ -318,40 +312,40 @@ module Sqreen
|
|
318
312
|
raise
|
319
313
|
else
|
320
314
|
begin
|
321
|
-
sqreen_timer.start if
|
315
|
+
sqreen_timer.start if budget
|
322
316
|
Thread.current[:sqreen_hook_entered] = true
|
323
317
|
|
324
318
|
# TODO: hooked_call.returning should be always false here?
|
325
319
|
return hooked_call.returning ? hooked_call.return : hooked_call.returned if hook.after.empty?
|
326
320
|
|
321
|
+
request_elapsed = request_timer.elapsed if budget
|
322
|
+
|
327
323
|
hook.after.each do |c|
|
328
324
|
next if c.ignore && c.ignore.call
|
329
325
|
|
330
|
-
if budget && !c.mandatory
|
331
|
-
|
332
|
-
|
326
|
+
if budget && !c.mandatory
|
327
|
+
sqreen_elapsed = sqreen_timer.elapsed
|
328
|
+
if budget_ratio && !request[:time_budget_expended]
|
329
|
+
fixed_budget = budget_threshold
|
330
|
+
proportional_budget = (request_elapsed - sqreen_elapsed) * budget_ratio
|
331
|
+
remaining = (fixed_budget > proportional_budget ? fixed_budget : proportional_budget) - sqreen_elapsed
|
332
|
+
else
|
333
|
+
remaining = budget_threshold - sqreen_elapsed
|
334
|
+
end
|
335
|
+
unless remaining > 0
|
336
|
+
request[:skipped_callbacks] << c
|
337
|
+
request[:time_budget_expended] = true
|
338
|
+
next
|
339
|
+
end
|
333
340
|
end
|
334
341
|
|
335
|
-
remaining = budget - sqreen_timer.elapsed if budget
|
336
|
-
|
337
|
-
timer = nil
|
338
342
|
flow = catch(Ball.new) do |ball|
|
339
|
-
|
340
|
-
timer.measure(ignore: chrono) do
|
343
|
+
Timer.new(c.name, &timed_callbacks_proc).measure(ignore: chrono) do
|
341
344
|
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed, nil, hooked_call.returned), ball)
|
342
345
|
end
|
343
346
|
end
|
344
347
|
|
345
|
-
if budget && timer
|
346
|
-
remaining -= timer.duration
|
347
|
-
if remaining < 0.0
|
348
|
-
request[:time_budget_expended]
|
349
|
-
request[:overtime_cb] = c.name
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
348
|
next unless c.flow && flow.is_a?(Flow)
|
354
|
-
conditions_passed_proc[] if flow.passed_conditions?
|
355
349
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
356
350
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
357
351
|
break if flow.break?
|
@@ -379,38 +373,36 @@ module Sqreen
|
|
379
373
|
hook.ensured.each do |c|
|
380
374
|
next if c.ignore && c.ignore.call
|
381
375
|
|
382
|
-
if budget && !c.mandatory
|
383
|
-
|
384
|
-
|
376
|
+
if budget && !c.mandatory
|
377
|
+
sqreen_elapsed = sqreen_timer.elapsed
|
378
|
+
if budget_ratio && !request[:time_budget_expended]
|
379
|
+
fixed_budget = budget_threshold
|
380
|
+
proportional_budget = (request_elapsed - sqreen_elapsed) * budget_ratio
|
381
|
+
remaining = (fixed_budget > proportional_budget ? fixed_budget : proportional_budget) - sqreen_elapsed
|
382
|
+
else
|
383
|
+
remaining = budget_threshold - sqreen_elapsed
|
384
|
+
end
|
385
|
+
unless remaining > 0
|
386
|
+
request[:skipped_callbacks] << c
|
387
|
+
request[:time_budget_expended] = true
|
388
|
+
next
|
389
|
+
end
|
385
390
|
end
|
386
391
|
|
387
|
-
remaining = budget - sqreen_timer.elapsed if budget
|
388
|
-
|
389
|
-
timer = nil
|
390
392
|
flow = catch(Ball.new) do |ball|
|
391
|
-
|
392
|
-
timer.measure(ignore: chrono) do
|
393
|
+
Timer.new(c.name, &timed_callbacks_proc).measure(ignore: chrono) do
|
393
394
|
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed, nil, hooked_call.returned), ball)
|
394
395
|
end
|
395
396
|
end
|
396
397
|
|
397
|
-
if budget && timer
|
398
|
-
remaining -= timer.duration
|
399
|
-
if remaining < 0.0
|
400
|
-
request[:time_budget_expended]
|
401
|
-
request[:overtime_cb] = c.name
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
398
|
next unless c.flow && flow.is_a?(Flow)
|
406
|
-
conditions_passed_proc[] if flow.passed_conditions?
|
407
399
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
408
400
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
409
401
|
break if flow.break?
|
410
402
|
end unless hook.ensured.empty? || hook.disabled?
|
411
403
|
|
412
404
|
Thread.current[:sqreen_hook_entered] = false
|
413
|
-
sqreen_timer.stop if
|
405
|
+
sqreen_timer.stop if budget
|
414
406
|
rescue StandardError => e
|
415
407
|
Sqreen::Weave.logger.debug { "exception:#{e.class} message:'#{e.message}' location:\"#{e.backtrace[0]}\"" }
|
416
408
|
Sqreen::RemoteException.record(e) if Sqreen.queue
|