2018-10-22 03:00:50 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-08-07 13:13:02 -04:00
|
|
|
module Gitlab
|
2022-07-25 05:09:05 -04:00
|
|
|
# DEPRECATED. Use Gitlab::BackgroundTask for new code instead.
|
2017-08-07 13:13:02 -04:00
|
|
|
class Daemon
|
2022-06-06 11:09:05 -04:00
|
|
|
# Options:
|
|
|
|
# - recreate: We usually only allow a single instance per process to exist;
|
|
|
|
# this can be overridden with this switch, so that existing
|
|
|
|
# instances are stopped and recreated.
|
|
|
|
def self.initialize_instance(*args, recreate: false, **options)
|
|
|
|
if @instance
|
|
|
|
if recreate
|
|
|
|
@instance.stop
|
|
|
|
else
|
|
|
|
raise "#{name} singleton instance already initialized"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@instance = new(*args, **options)
|
2017-08-07 13:13:02 -04:00
|
|
|
Kernel.at_exit(&@instance.method(:stop))
|
|
|
|
@instance
|
|
|
|
end
|
|
|
|
|
2021-11-22 07:10:20 -05:00
|
|
|
def self.instance(...)
|
|
|
|
@instance ||= initialize_instance(...)
|
2017-08-07 13:13:02 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
attr_reader :thread
|
|
|
|
|
|
|
|
def thread?
|
|
|
|
!thread.nil?
|
|
|
|
end
|
|
|
|
|
2022-02-10 16:15:20 -05:00
|
|
|
# Possible options:
|
|
|
|
# - synchronous [Boolean] if true, turns `start` into a blocking call
|
2021-11-22 07:10:20 -05:00
|
|
|
def initialize(**options)
|
|
|
|
@synchronous = options[:synchronous]
|
2017-08-07 13:13:02 -04:00
|
|
|
@mutex = Mutex.new
|
|
|
|
end
|
|
|
|
|
|
|
|
def enabled?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2019-11-04 07:06:19 -05:00
|
|
|
def thread_name
|
|
|
|
self.class.name.demodulize.underscore
|
|
|
|
end
|
|
|
|
|
2017-08-07 13:13:02 -04:00
|
|
|
def start
|
|
|
|
return unless enabled?
|
|
|
|
|
|
|
|
@mutex.synchronize do
|
2018-04-18 05:19:40 -04:00
|
|
|
break thread if thread?
|
2017-08-07 13:13:02 -04:00
|
|
|
|
2019-10-16 05:07:51 -04:00
|
|
|
if start_working
|
2019-11-04 07:06:19 -05:00
|
|
|
@thread = Thread.new do
|
|
|
|
Thread.current.name = thread_name
|
|
|
|
run_thread
|
|
|
|
end
|
2021-11-22 07:10:20 -05:00
|
|
|
|
|
|
|
@thread.join if @synchronous
|
|
|
|
|
|
|
|
@thread
|
2019-10-16 05:07:51 -04:00
|
|
|
end
|
2017-08-07 13:13:02 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def stop
|
|
|
|
@mutex.synchronize do
|
2018-04-18 05:19:40 -04:00
|
|
|
break unless thread?
|
2017-08-07 13:13:02 -04:00
|
|
|
|
|
|
|
stop_working
|
|
|
|
|
|
|
|
if thread
|
|
|
|
thread.wakeup if thread.alive?
|
2019-08-21 05:32:45 -04:00
|
|
|
begin
|
|
|
|
thread.join unless Thread.current == thread
|
|
|
|
rescue Exception # rubocop:disable Lint/RescueException
|
|
|
|
end
|
2017-08-07 13:13:02 -04:00
|
|
|
@thread = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2019-10-16 05:07:51 -04:00
|
|
|
# Executed in lock context before starting thread
|
|
|
|
# Needs to return success
|
2017-08-07 13:13:02 -04:00
|
|
|
def start_working
|
2019-10-16 05:07:51 -04:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
# Executed in separate thread
|
|
|
|
def run_thread
|
2017-08-07 13:13:02 -04:00
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
|
2019-10-16 05:07:51 -04:00
|
|
|
# Executed in lock context
|
2017-08-07 13:13:02 -04:00
|
|
|
def stop_working
|
|
|
|
# no-ops
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|