daemon.rb 1.37 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5 6
module Gitlab
  class Daemon
    def self.initialize_instance(*args)
      raise "#{name} singleton instance already initialized" if @instance
7

8 9 10 11 12
      @instance = new(*args)
      Kernel.at_exit(&@instance.method(:stop))
      @instance
    end

13 14
    def self.instance(*args)
      @instance ||= initialize_instance(*args)
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
    end

    attr_reader :thread

    def thread?
      !thread.nil?
    end

    def initialize
      @mutex = Mutex.new
    end

    def enabled?
      true
    end

    def start
      return unless enabled?

      @mutex.synchronize do
35
        break thread if thread?
36

37 38 39
        if start_working
          @thread = Thread.new { run_thread }
        end
40 41 42 43 44
      end
    end

    def stop
      @mutex.synchronize do
45
        break unless thread?
46 47 48 49 50

        stop_working

        if thread
          thread.wakeup if thread.alive?
51 52 53 54
          begin
            thread.join unless Thread.current == thread
          rescue Exception # rubocop:disable Lint/RescueException
          end
55 56 57 58 59 60 61
          @thread = nil
        end
      end
    end

    private

62 63
    # Executed in lock context before starting thread
    # Needs to return success
64
    def start_working
65 66 67 68 69
      true
    end

    # Executed in separate thread
    def run_thread
70 71 72
      raise NotImplementedError
    end

73
    # Executed in lock context
74 75 76 77 78
    def stop_working
      # no-ops
    end
  end
end