summaryrefslogtreecommitdiff
path: root/lib/gitlab/runtime.rb
blob: 97f7a8e28006c6bb9d9ee3194ac9737fdfb1f38b (plain)
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
80
81
82
# frozen_string_literal: true

module Gitlab
  # Provides routines to identify the current runtime as which the application
  # executes, such as whether it is an application server and which one.
  module Runtime
    IdentificationError = Class.new(RuntimeError)
    AmbiguousProcessError = Class.new(IdentificationError)
    UnknownProcessError = Class.new(IdentificationError)

    class << self
      def identify
        matches = []
        matches << :puma if puma?
        matches << :unicorn if unicorn?
        matches << :console if console?
        matches << :sidekiq if sidekiq?
        matches << :rake if rake?
        matches << :rspec if rspec?

        if matches.one?
          matches.first
        elsif matches.none?
          raise UnknownProcessError.new(
            "Failed to identify runtime for process #{Process.pid} (#{$0})"
          )
        else
          raise AmbiguousProcessError.new(
            "Ambiguous runtime #{matches} for process #{Process.pid} (#{$0})"
          )
        end
      end

      def puma?
        !!defined?(::Puma)
      end

      # For unicorn, we need to check for actual server instances to avoid false positives.
      def unicorn?
        !!(defined?(::Unicorn) && defined?(::Unicorn::HttpServer))
      end

      def sidekiq?
        !!(defined?(::Sidekiq) && Sidekiq.server?)
      end

      def rake?
        !!(defined?(::Rake) && Rake.application.top_level_tasks.any?)
      end

      def rspec?
        Rails.env.test? && process_name == 'rspec'
      end

      def console?
        !!defined?(::Rails::Console)
      end

      def web_server?
        puma? || unicorn?
      end

      def multi_threaded?
        puma? || sidekiq?
      end

      def process_name
        File.basename($0)
      end

      def max_threads
        if puma?
          Puma.cli_config.options[:max_threads]
        elsif sidekiq?
          Sidekiq.options[:concurrency]
        else
          1
        end
      end
    end
  end
end