Class: DaemonicThreads::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-daemonic-threads/runner.rb

Constant Summary collapse

RESTART_DELAY =
15

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, config, process) ⇒ Runner

Returns a new instance of Runner.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ruby-daemonic-threads/runner.rb', line 20

def initialize(name, config, process)
  @name = name
  @config = config
  @process = process
  @logger = Rails.logger
  
  @mutex = Mutex.new
  @delay = ConditionVariable.new
  @must_terminate = false
  @restarting = false
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



32
33
34
# File 'lib/ruby-daemonic-threads/runner.rb', line 32

def config
  @config
end

#nameObject (readonly)

Returns the value of attribute name.



32
33
34
# File 'lib/ruby-daemonic-threads/runner.rb', line 32

def name
  @name
end

#processObject (readonly)

Returns the value of attribute process.



32
33
34
# File 'lib/ruby-daemonic-threads/runner.rb', line 32

def process
  @process
end

Instance Method Details

#joinObject



38
39
40
# File 'lib/ruby-daemonic-threads/runner.rb', line 38

def join
  @watchdog_thread.join if @watchdog_thread
end

#restart_daemonObject

Нельзя вызывать restart_daemon(), из initialize(), потому что перестартовывать ещё нечего. Такой вызов может произойти, если в initialize() запускаются треды, которые при ошибке вызывают restart_daemon. Запускайте новые треды в методе initialize_daemon(). Он выполняется после завершения initialize()

Нельзя вызывать restart_daemon() после того, как отработал join(). Таким действием можно непреднамеренно перезапустить новое, только что созданное приложение. Пауза между завершением старого и запуском нового приложения (RESTART_DELAY), несколько снижает вероятность такой ошибки. Польностью ошибку исключить можно, только если в join() делать join для всех запущенных тредов. Это делается автоматически, если использовать методы spawn_daemon и spawn_thread.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/ruby-daemonic-threads/runner.rb', line 66

def restart_daemon
  restart_process_on_exception do
    @mutex.synchronize do
      return if @must_terminate || @restarting

      @restarting = true
      
      unless @daemon
        raise "#{self.class}#restart_daemon @name:`#{@name} -- Called restart_daemon(), but @daemon does not exists! This may occur when you somehow call restart_daemon() from initialize() and then raises then exception from initialize(). Or you spawn threads in initialize() instead of in spawn_threads() and one thread ends with exception before initialize() fully completes. Or it may be both cases." 
      end
      
      @daemon.stop
    end
  end
end

#startObject



34
35
36
# File 'lib/ruby-daemonic-threads/runner.rb', line 34

def start
  @watchdog_thread = Thread.new_with_exception_handling(lambda { @process.controller.stop }, @logger, :fatal, "#{self.class}#watchdog @name:`#{@name}'") { watchdog }
end

#stopObject



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ruby-daemonic-threads/runner.rb', line 42

def stop
  restart_process_on_exception do
    @mutex.synchronize do
      @must_terminate = true
      @delay.signal

      return if @restarting
      
      @daemon.stop if @daemon
    end
  end
end