airbrake-ruby 4.9.0-java → 4.10.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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +55 -6
  3. data/lib/airbrake-ruby/async_sender.rb +3 -3
  4. data/lib/airbrake-ruby/backtrace.rb +2 -2
  5. data/lib/airbrake-ruby/code_hunk.rb +1 -1
  6. data/lib/airbrake-ruby/config.rb +1 -1
  7. data/lib/airbrake-ruby/config/validator.rb +3 -3
  8. data/lib/airbrake-ruby/deploy_notifier.rb +1 -1
  9. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +2 -2
  10. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +2 -2
  11. data/lib/airbrake-ruby/filters/keys_filter.rb +1 -1
  12. data/lib/airbrake-ruby/filters/sql_filter.rb +3 -3
  13. data/lib/airbrake-ruby/filters/thread_filter.rb +1 -1
  14. data/lib/airbrake-ruby/inspectable.rb +2 -2
  15. data/lib/airbrake-ruby/notice.rb +7 -7
  16. data/lib/airbrake-ruby/notice_notifier.rb +1 -1
  17. data/lib/airbrake-ruby/performance_breakdown.rb +1 -1
  18. data/lib/airbrake-ruby/performance_notifier.rb +36 -20
  19. data/lib/airbrake-ruby/query.rb +1 -1
  20. data/lib/airbrake-ruby/queue.rb +2 -2
  21. data/lib/airbrake-ruby/request.rb +1 -1
  22. data/lib/airbrake-ruby/stat.rb +1 -1
  23. data/lib/airbrake-ruby/version.rb +1 -1
  24. data/spec/airbrake_spec.rb +107 -48
  25. data/spec/async_sender_spec.rb +4 -4
  26. data/spec/backtrace_spec.rb +18 -18
  27. data/spec/code_hunk_spec.rb +9 -9
  28. data/spec/config/validator_spec.rb +5 -5
  29. data/spec/config_spec.rb +5 -5
  30. data/spec/deploy_notifier_spec.rb +2 -2
  31. data/spec/filter_chain_spec.rb +1 -1
  32. data/spec/filters/dependency_filter_spec.rb +1 -1
  33. data/spec/filters/gem_root_filter_spec.rb +5 -5
  34. data/spec/filters/git_last_checkout_filter_spec.rb +1 -1
  35. data/spec/filters/git_repository_filter.rb +1 -1
  36. data/spec/filters/git_revision_filter_spec.rb +10 -10
  37. data/spec/filters/keys_blacklist_spec.rb +22 -22
  38. data/spec/filters/keys_whitelist_spec.rb +21 -21
  39. data/spec/filters/root_directory_filter_spec.rb +5 -5
  40. data/spec/filters/sql_filter_spec.rb +53 -53
  41. data/spec/filters/system_exit_filter_spec.rb +1 -1
  42. data/spec/filters/thread_filter_spec.rb +28 -28
  43. data/spec/fixtures/project_root/code.rb +9 -9
  44. data/spec/notice_notifier/options_spec.rb +12 -12
  45. data/spec/notice_notifier_spec.rb +17 -17
  46. data/spec/notice_spec.rb +5 -5
  47. data/spec/performance_notifier_spec.rb +88 -68
  48. data/spec/query_spec.rb +1 -1
  49. data/spec/request_spec.rb +1 -1
  50. data/spec/response_spec.rb +8 -8
  51. data/spec/spec_helper.rb +2 -2
  52. data/spec/stat_spec.rb +2 -2
  53. data/spec/sync_sender_spec.rb +12 -12
  54. data/spec/tdigest_spec.rb +6 -6
  55. data/spec/thread_pool_spec.rb +5 -5
  56. data/spec/timed_trace_spec.rb +1 -1
  57. data/spec/truncator_spec.rb +12 -12
  58. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e05d33daf76111bb1a55538d29cba82f1ac99c97578ee07843af8b88750b7a5
4
- data.tar.gz: e7e11e55e646e58d8740a7ce6f97e0b7f3f27437f732c6d348be24df409a3ad2
3
+ metadata.gz: 8625fd0aed2978b8b727b5a1c7fe45714ab6555a25020ac9d686b2452d146ecc
4
+ data.tar.gz: ecd8983a7b37efb831faa440f294db56c8a59de9b9a05c1d014493d3c3da1e94
5
5
  SHA512:
6
- metadata.gz: f8b47d08818f4dec1b1d3ed5e381e10392e1da33677894e8a10d2e07c9ede4b1adffeab060a931b13da9f26f4d6f9f5ff25b9ec6beba677a674528260246fd0c
7
- data.tar.gz: 4a77aa66088214bddeab8b4c7eac2c82a3f1f7354fe6d37c8e679c4e46a16efde2c753ee3fb02397612f0ea1c93e8430968057aa70b45a6e0a97658158346d46
6
+ metadata.gz: 6aca834636fecad4aab2df4351e38a103450ba1d3ff57724e1dfd6694ff68a1ffe4b47a700b29dc60f843085844fd537636184f1d0ea64446b0884a33e41569a
7
+ data.tar.gz: adba5aecb6240193c212a6f7a4011adde53fcaf87238060d4474eaca012daf66b59d0361b4c982fa5b103a28ea7f4fcc70a5bd75f57f908a08ccdbc2062a56b3
data/lib/airbrake-ruby.rb CHANGED
@@ -135,7 +135,7 @@ module Airbrake
135
135
  # @return [Boolean] true if the notifier was configured, false otherwise
136
136
  # @since v2.3.0
137
137
  def configured?
138
- notice_notifier.configured?
138
+ @notice_notifier && @notice_notifier.configured?
139
139
  end
140
140
 
141
141
  # Sends an exception to Airbrake asynchronously.
@@ -255,10 +255,17 @@ module Airbrake
255
255
  # Airbrake.notify('App crashed!') #=> raises Airbrake::Error
256
256
  #
257
257
  # @return [void]
258
+ # rubocop:disable Style/GuardClause, Style/IfUnlessModifier
258
259
  def close
259
- notice_notifier.close
260
- performance_notifier.close
260
+ if defined?(@notice_notifier) && @notice_notifier
261
+ @notice_notifier.close
262
+ end
263
+
264
+ if defined?(@performance_notifier) && @performance_notifier
265
+ @performance_notifier.close
266
+ end
261
267
  end
268
+ # rubocop:enable Style/GuardClause, Style/IfUnlessModifier
262
269
 
263
270
  # Pings the Airbrake Deploy API endpoint about the occurred deploy.
264
271
  #
@@ -364,6 +371,17 @@ module Airbrake
364
371
  performance_notifier.notify(request)
365
372
  end
366
373
 
374
+ # Synchronously Increments request statistics of a certain +route+ that was
375
+ # invoked on +start_time+ and ended on +end_time+ with +method+, and
376
+ # returned +status_code+.
377
+ # @since v4.10.0
378
+ # @see .notify_request
379
+ def notify_request_sync(request_info, stash = {})
380
+ request = Request.new(request_info)
381
+ request.stash.merge!(stash)
382
+ performance_notifier.notify_sync(request)
383
+ end
384
+
367
385
  # Increments SQL statistics of a certain +query+ that was invoked on
368
386
  # +start_time+ and finished on +end_time+. When +method+ and +route+ are
369
387
  # provided, the query is grouped by these parameters.
@@ -399,6 +417,17 @@ module Airbrake
399
417
  performance_notifier.notify(query)
400
418
  end
401
419
 
420
+ # Synchronously increments SQL statistics of a certain +query+ that was
421
+ # invoked on +start_time+ and finished on +end_time+. When +method+ and
422
+ # +route+ are provided, the query is grouped by these parameters.
423
+ # @since v4.10.0
424
+ # @see .notify_query
425
+ def notify_query_sync(query_info, stash = {})
426
+ query = Query.new(query_info)
427
+ query.stash.merge!(stash)
428
+ performance_notifier.notify_sync(query)
429
+ end
430
+
402
431
  # Increments performance breakdown statistics of a certain route.
403
432
  #
404
433
  # @example
@@ -427,6 +456,16 @@ module Airbrake
427
456
  performance_notifier.notify(performance_breakdown)
428
457
  end
429
458
 
459
+ # Increments performance breakdown statistics of a certain route
460
+ # synchronously.
461
+ # @since v4.10.0
462
+ # @see .notify_performance_breakdown
463
+ def notify_performance_breakdown_sync(breakdown_info, stash = {})
464
+ performance_breakdown = PerformanceBreakdown.new(breakdown_info)
465
+ performance_breakdown.stash.merge!(stash)
466
+ performance_notifier.notify_sync(performance_breakdown)
467
+ end
468
+
430
469
  # Increments statistics of a certain queue (worker).
431
470
  #
432
471
  # @example
@@ -442,16 +481,26 @@ module Airbrake
442
481
  # failed
443
482
  # @option queue_info [Array<Hash{Symbol=>Float}>] :groups Where the job
444
483
  # spent its time
445
- # @param [Hash] stash What needs to be appeneded to the stash, so it's
484
+ # @param [Hash] stash What needs to be appended to the stash, so it's
446
485
  # available in filters
447
486
  # @return [void]
448
487
  # @since v4.9.0
488
+ # @see .notify_queue_sync
449
489
  def notify_queue(queue_info, stash = {})
450
490
  queue = Queue.new(queue_info)
451
491
  queue.stash.merge!(stash)
452
492
  performance_notifier.notify(queue)
453
493
  end
454
494
 
495
+ # Increments statistics of a certain queue (worker) synchronously.
496
+ # @since v4.10.0
497
+ # @see .notify_queue
498
+ def notify_queue_sync(queue_info, stash = {})
499
+ queue = Queue.new(queue_info)
500
+ queue.stash.merge!(stash)
501
+ performance_notifier.notify_sync(queue)
502
+ end
503
+
455
504
  # Runs a callback before {.notify_request} or {.notify_query} kicks in. This
456
505
  # is useful if you want to ignore specific resources or filter the data the
457
506
  # resource contains.
@@ -509,7 +558,7 @@ module Airbrake
509
558
  # @return [void]
510
559
  # @since v4.2.2
511
560
  def reset
512
- close if notice_notifier && configured?
561
+ close
513
562
 
514
563
  self.performance_notifier = PerformanceNotifier.new
515
564
  self.notice_notifier = NoticeNotifier.new
@@ -535,7 +584,7 @@ module Airbrake
535
584
  Airbrake::Filters::RootDirectoryFilter,
536
585
  Airbrake::Filters::GitRevisionFilter,
537
586
  Airbrake::Filters::GitRepositoryFilter,
538
- Airbrake::Filters::GitLastCheckoutFilter
587
+ Airbrake::Filters::GitLastCheckoutFilter,
539
588
  ].each do |filter|
540
589
  notice_notifier.add_filter(filter.new(config.root_directory))
541
590
  end
@@ -54,7 +54,7 @@ module Airbrake
54
54
  ThreadPool.new(
55
55
  worker_size: @config.workers,
56
56
  queue_size: @config.queue_size,
57
- block: proc { |args| sender.send(*args) }
57
+ block: proc { |args| sender.send(*args) },
58
58
  )
59
59
  end
60
60
  end
@@ -71,8 +71,8 @@ module Airbrake
71
71
  message: error[:message],
72
72
  backtrace: error[:backtrace].map do |line|
73
73
  "#{line[:file]}:#{line[:line]} in `#{line[:function]}'"
74
- end.join("\n")
75
- )
74
+ end.join("\n"),
75
+ ),
76
76
  )
77
77
  promise.reject("AsyncSender has reached its capacity of #{@config.queue_size}")
78
78
  end
@@ -147,13 +147,13 @@ module Airbrake
147
147
  return {
148
148
  file: match[:file],
149
149
  line: (Integer(match[:line]) if match[:line]),
150
- function: match[:function]
150
+ function: match[:function],
151
151
  }
152
152
  end
153
153
 
154
154
  logger.error(
155
155
  "can't parse '#{stackframe}' (please file an issue so we can fix " \
156
- "it: https://github.com/airbrake/airbrake-ruby/issues/new)"
156
+ "it: https://github.com/airbrake/airbrake-ruby/issues/new)",
157
157
  )
158
158
  { file: nil, line: nil, function: stackframe }
159
159
  end
@@ -30,7 +30,7 @@ module Airbrake
30
30
  Airbrake::FileCache[file] ||= File.foreach(file)
31
31
  rescue StandardError => ex
32
32
  logger.error(
33
- "#{self.class.name}: can't read code hunk for #{file}: #{ex}"
33
+ "#{self.class.name}: can't read code hunk for #{file}: #{ex}",
34
34
  )
35
35
  nil
36
36
  end
@@ -132,7 +132,7 @@ module Airbrake
132
132
 
133
133
  self.root_directory = File.realpath(
134
134
  (defined?(Bundler) && Bundler.root) ||
135
- Dir.pwd
135
+ Dir.pwd,
136
136
  )
137
137
 
138
138
  self.versions = {}
@@ -29,7 +29,7 @@ module Airbrake
29
29
  return promise.reject(
30
30
  "the 'environment' option must be configured " \
31
31
  "with a Symbol (or String), but '#{config.environment.class}' was " \
32
- "provided: #{config.environment}"
32
+ "provided: #{config.environment}",
33
33
  )
34
34
  end
35
35
 
@@ -46,7 +46,7 @@ module Airbrake
46
46
 
47
47
  if ignored_environment?(config)
48
48
  return promise.reject(
49
- "current environment '#{config.environment}' is ignored"
49
+ "current environment '#{config.environment}' is ignored",
50
50
  )
51
51
  end
52
52
 
@@ -74,7 +74,7 @@ module Airbrake
74
74
  if config.ignore_environments.any? && config.environment.nil?
75
75
  config.logger.warn(
76
76
  "#{LOG_LABEL} the 'environment' option is not set, " \
77
- "'ignore_environments' has no effect"
77
+ "'ignore_environments' has no effect",
78
78
  )
79
79
  end
80
80
 
@@ -27,7 +27,7 @@ module Airbrake
27
27
  @sender.send(
28
28
  deploy_info,
29
29
  promise,
30
- URI.join(@config.host, "api/v4/projects/#{@config.project_id}/deploys")
30
+ URI.join(@config.host, "api/v4/projects/#{@config.project_id}/deploys"),
31
31
  )
32
32
 
33
33
  promise
@@ -22,13 +22,13 @@ module Airbrake
22
22
  attributes = exception.to_airbrake
23
23
  rescue StandardError => ex
24
24
  logger.error(
25
- "#{LOG_LABEL} #{exception.class}#to_airbrake failed. #{ex.class}: #{ex}"
25
+ "#{LOG_LABEL} #{exception.class}#to_airbrake failed. #{ex.class}: #{ex}",
26
26
  )
27
27
  end
28
28
 
29
29
  unless attributes.is_a?(Hash)
30
30
  logger.error(
31
- "#{LOG_LABEL} #{self.class}: wanted Hash, got #{attributes.class}"
31
+ "#{LOG_LABEL} #{self.class}: wanted Hash, got #{attributes.class}",
32
32
  )
33
33
  return
34
34
  end
@@ -52,7 +52,7 @@ module Airbrake
52
52
  parts = line.chomp.split("\t").first.split(' ')
53
53
  if parts.size < MIN_HEAD_COLS
54
54
  logger.error(
55
- "#{LOG_LABEL} Airbrake::#{self.class.name}: can't parse line: #{line}"
55
+ "#{LOG_LABEL} Airbrake::#{self.class.name}: can't parse line: #{line}",
56
56
  )
57
57
  return
58
58
  end
@@ -62,7 +62,7 @@ module Airbrake
62
62
  username: author[0..1].join(' '),
63
63
  email: parts[-3][1..-2],
64
64
  revision: parts[1],
65
- time: timestamp(parts[-2].to_i)
65
+ time: timestamp(parts[-2].to_i),
66
66
  }
67
67
  end
68
68
  # rubocop:enable Metrics/AbcSize
@@ -124,7 +124,7 @@ module Airbrake
124
124
 
125
125
  logger.error(
126
126
  "#{LOG_LABEL} one of the patterns in #{self.class} is invalid. " \
127
- "Known patterns: #{@patterns}"
127
+ "Known patterns: #{@patterns}",
128
128
  )
129
129
  end
130
130
 
@@ -64,7 +64,7 @@ module Airbrake
64
64
  cassandra: %i[
65
65
  single_quotes uuids numeric_literals boolean_literals
66
66
  hexadecimal_literals comments multi_line_comments
67
- ].freeze
67
+ ].freeze,
68
68
  }.freeze
69
69
 
70
70
  # @return [Hash{Symbol=>Regexp}] a set of regexps to check for unmatches
@@ -76,7 +76,7 @@ module Airbrake
76
76
  sqlite: %r{'|/\*|\*/},
77
77
  cassandra: %r{'|/\*|\*/},
78
78
  oracle: %r{'|/\*|\*/},
79
- oracle_enhanced: %r{'|/\*|\*/}
79
+ oracle_enhanced: %r{'|/\*|\*/},
80
80
  }.freeze
81
81
 
82
82
  # @return [Array<Regexp>] the list of queries to be ignored
@@ -89,7 +89,7 @@ module Airbrake
89
89
  /FROM pg_attribute/i,
90
90
  /FROM pg_index/i,
91
91
  /FROM pg_class/i,
92
- /FROM pg_type/i
92
+ /FROM pg_type/i,
93
93
  ].freeze
94
94
 
95
95
  def initialize(dialect)
@@ -16,7 +16,7 @@ module Airbrake
16
16
  String,
17
17
  Symbol,
18
18
  Regexp,
19
- Numeric
19
+ Numeric,
20
20
  ].freeze
21
21
 
22
22
  # Variables starting with this prefix are not attached to a notice.
@@ -21,7 +21,7 @@ module Airbrake
21
21
  project_id: @config.project_id,
22
22
  project_key: @config.project_key,
23
23
  host: @config.host,
24
- filter_chain: @filter_chain.inspect
24
+ filter_chain: @filter_chain.inspect,
25
25
  )
26
26
  end
27
27
 
@@ -30,7 +30,7 @@ module Airbrake
30
30
  q.text("#<#{self.class}:0x#{(object_id << 1).to_s(16).rjust(16, '0')} ")
31
31
  q.text(
32
32
  "project_id=\"#{@config.project_id}\" project_key=\"#{@config.project_key}\" " \
33
- "host=\"#{@config.host}\" filter_chain="
33
+ "host=\"#{@config.host}\" filter_chain=",
34
34
  )
35
35
  q.pp(@filter_chain)
36
36
  q.text('>')
@@ -8,7 +8,7 @@ module Airbrake
8
8
  NOTIFIER = {
9
9
  name: 'airbrake-ruby'.freeze,
10
10
  version: Airbrake::AIRBRAKE_RUBY_VERSION,
11
- url: 'https://github.com/airbrake/airbrake-ruby'.freeze
11
+ url: 'https://github.com/airbrake/airbrake-ruby'.freeze,
12
12
  }.freeze
13
13
 
14
14
  # @return [Hash{Symbol=>String,Hash}] the information to be displayed in the
@@ -16,7 +16,7 @@ module Airbrake
16
16
  CONTEXT = {
17
17
  os: RUBY_PLATFORM,
18
18
  language: "#{RUBY_ENGINE}/#{RUBY_VERSION}".freeze,
19
- notifier: NOTIFIER
19
+ notifier: NOTIFIER,
20
20
  }.freeze
21
21
 
22
22
  # @return [Integer] the maxium size of the JSON payload in bytes
@@ -32,7 +32,7 @@ module Airbrake
32
32
  IOError,
33
33
  NotImplementedError,
34
34
  JSON::GeneratorError,
35
- Encoding::UndefinedConversionError
35
+ Encoding::UndefinedConversionError,
36
36
  ].freeze
37
37
 
38
38
  # @return [Array<Symbol>] the list of keys that can be be overwritten with
@@ -60,10 +60,10 @@ module Airbrake
60
60
  errors: NestedException.new(exception).as_json,
61
61
  context: context,
62
62
  environment: {
63
- program_name: $PROGRAM_NAME
63
+ program_name: $PROGRAM_NAME,
64
64
  },
65
65
  session: {},
66
- params: params
66
+ params: params,
67
67
  }
68
68
  @truncator = Airbrake::Truncator.new(PAYLOAD_MAX_SIZE)
69
69
 
@@ -138,7 +138,7 @@ module Airbrake
138
138
  # Make sure we always send hostname.
139
139
  hostname: HOSTNAME,
140
140
 
141
- severity: DEFAULT_SEVERITY
141
+ severity: DEFAULT_SEVERITY,
142
142
  }.merge(CONTEXT).delete_if { |_key, val| val.nil? || val.empty? }
143
143
  end
144
144
 
@@ -152,7 +152,7 @@ module Airbrake
152
152
  logger.error(
153
153
  "#{LOG_LABEL} truncation failed. File an issue at " \
154
154
  "https://github.com/airbrake/airbrake-ruby " \
155
- "and attach the following payload: #{@payload}"
155
+ "and attach the following payload: #{@payload}",
156
156
  )
157
157
  end
158
158
 
@@ -116,7 +116,7 @@ module Airbrake
116
116
 
117
117
  logger.warn(
118
118
  "#{LOG_LABEL} falling back to sync delivery because there are no " \
119
- "running async workers"
119
+ "running async workers",
120
120
  )
121
121
  @sync_sender
122
122
  end
@@ -39,7 +39,7 @@ module Airbrake
39
39
  'method' => method,
40
40
  'route' => route,
41
41
  'responseType' => response_type,
42
- 'time' => @start_time_utc
42
+ 'time' => @start_time_utc,
43
43
  }.delete_if { |_key, val| val.nil? }
44
44
  end
45
45
  end
@@ -4,6 +4,7 @@ module Airbrake
4
4
  #
5
5
  # @api public
6
6
  # @since v3.2.0
7
+ # rubocop:disable Metrics/ClassLength
7
8
  class PerformanceNotifier
8
9
  include Inspectable
9
10
  include Loggable
@@ -11,7 +12,8 @@ module Airbrake
11
12
  def initialize
12
13
  @config = Airbrake::Config.instance
13
14
  @flush_period = Airbrake::Config.instance.performance_stats_flush_period
14
- @sender = AsyncSender.new(:put)
15
+ @async_sender = AsyncSender.new(:put)
16
+ @sync_sender = SyncSender.new(:put)
15
17
  @payload = {}
16
18
  @schedule_flush = nil
17
19
  @mutex = Mutex.new
@@ -23,21 +25,14 @@ module Airbrake
23
25
  # @see Airbrake.notify_query
24
26
  # @see Airbrake.notify_request
25
27
  def notify(resource)
26
- promise = @config.check_configuration
27
- return promise if promise.rejected?
28
-
29
- promise = @config.check_performance_options(resource)
30
- return promise if promise.rejected?
31
-
32
- @filter_chain.refine(resource)
33
- return if resource.ignored?
34
-
35
- @mutex.synchronize do
36
- update_payload(resource)
37
- @flush_period > 0 ? schedule_flush : send(@payload, promise)
38
- end
28
+ send_resource(resource, sync: false)
29
+ end
39
30
 
40
- promise.resolve(:success)
31
+ # @param [Hash] resource
32
+ # @since v4.10.0
33
+ # @see Airbrake.notify_queue_sync
34
+ def notify_sync(resource)
35
+ send_resource(resource, sync: true).value
41
36
  end
42
37
 
43
38
  # @see Airbrake.add_performance_filter
@@ -53,7 +48,7 @@ module Airbrake
53
48
  def close
54
49
  @mutex.synchronize do
55
50
  @schedule_flush.kill if @schedule_flush
56
- @sender.close
51
+ @async_sender.close
57
52
  logger.debug("#{LOG_LABEL} performance notifier closed")
58
53
  end
59
54
  end
@@ -106,12 +101,32 @@ module Airbrake
106
101
  @payload = {}
107
102
  end
108
103
 
109
- send(payload, Airbrake::Promise.new)
104
+ send(@async_sender, payload, Airbrake::Promise.new)
105
+ end
106
+ end
107
+ end
108
+
109
+ def send_resource(resource, sync:)
110
+ promise = @config.check_configuration
111
+ return promise if promise.rejected?
112
+
113
+ promise = @config.check_performance_options(resource)
114
+ return promise if promise.rejected?
115
+
116
+ @filter_chain.refine(resource)
117
+ return if resource.ignored?
118
+
119
+ @mutex.synchronize do
120
+ update_payload(resource)
121
+ if sync || @flush_period == 0
122
+ send(@sync_sender, @payload, promise)
123
+ else
124
+ schedule_flush
110
125
  end
111
126
  end
112
127
  end
113
128
 
114
- def send(payload, promise)
129
+ def send(sender, payload, promise)
115
130
  signature = "#{self.class.name}##{__method__}"
116
131
  raise "#{signature}: payload (#{payload}) cannot be empty. Race?" if payload.none?
117
132
 
@@ -120,9 +135,9 @@ module Airbrake
120
135
  with_grouped_payload(payload) do |resource_hash, destination|
121
136
  url = URI.join(
122
137
  @config.host,
123
- "api/v5/projects/#{@config.project_id}/#{destination}"
138
+ "api/v5/projects/#{@config.project_id}/#{destination}",
124
139
  )
125
- @sender.send(resource_hash, promise, url)
140
+ sender.send(resource_hash, promise, url)
126
141
  end
127
142
 
128
143
  promise
@@ -157,4 +172,5 @@ module Airbrake
157
172
  end
158
173
  end
159
174
  end
175
+ # rubocop:enable Metrics/ClassLength
160
176
  end