File: background_worker.rb

package info (click to toggle)
ruby-sentry-ruby 5.18.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 564 kB
  • sloc: ruby: 4,701; makefile: 8; sh: 4
file content (79 lines) | stat: -rw-r--r-- 2,225 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# frozen_string_literal: true

require "concurrent/executor/thread_pool_executor"
require "concurrent/executor/immediate_executor"
require "concurrent/configuration"

module Sentry
  class BackgroundWorker
    include LoggingHelper

    attr_reader :max_queue, :number_of_threads
    # @deprecated Use Sentry.logger to retrieve the current logger instead.
    attr_reader :logger
    attr_accessor :shutdown_timeout

    DEFAULT_MAX_QUEUE = 30

    def initialize(configuration)
      @shutdown_timeout = 1
      @number_of_threads = configuration.background_worker_threads
      @max_queue = configuration.background_worker_max_queue
      @logger = configuration.logger
      @debug = configuration.debug
      @shutdown_callback = nil

      @executor =
        if configuration.async
          log_debug("config.async is set, BackgroundWorker is disabled")
          Concurrent::ImmediateExecutor.new
        elsif @number_of_threads == 0
          log_debug("config.background_worker_threads is set to 0, all events will be sent synchronously")
          Concurrent::ImmediateExecutor.new
        else
          log_debug("Initializing the Sentry background worker with #{@number_of_threads} threads")

          executor = Concurrent::ThreadPoolExecutor.new(
            min_threads: 0,
            max_threads: @number_of_threads,
            max_queue: @max_queue,
            fallback_policy: :discard
          )

          @shutdown_callback = proc do
            executor.shutdown
            executor.wait_for_termination(@shutdown_timeout)
          end

          executor
        end
    end

    # if you want to monkey-patch this method, please override `_perform` instead
    def perform(&block)
      @executor.post do
        begin
          _perform(&block)
        rescue Exception => e
          log_error("exception happened in background worker", e, debug: @debug)
        end
      end
    end

    def shutdown
      log_debug("Shutting down background worker")
      @shutdown_callback&.call
    end

    def full?
      @executor.is_a?(Concurrent::ThreadPoolExecutor) &&
        @executor.remaining_capacity == 0
    end

    private

    def _perform(&block)
      block.call
    end
  end
end