Class: DeepTest::Warlock
- Inherits:
-
Object
- Object
- DeepTest::Warlock
- Defined in:
- lib/deep_test/warlock.rb
Instance Method Summary collapse
- #any_running? ⇒ Boolean
- #demon_count ⇒ Object
- #exit_when_none_running ⇒ Object
-
#initialize ⇒ Warlock
constructor
A new instance of Warlock.
-
#running?(pid) ⇒ Boolean
stolen from daemons.
- #start(name, &block) ⇒ Object
- #stop_all ⇒ Object
Constructor Details
#initialize ⇒ Warlock
Returns a new instance of Warlock.
3 4 5 6 7 |
# File 'lib/deep_test/warlock.rb', line 3 def initialize @demons_semaphore = Mutex.new @demons = [] @reapers = [] end |
Instance Method Details
#any_running? ⇒ Boolean
86 87 88 89 90 |
# File 'lib/deep_test/warlock.rb', line 86 def any_running? @demons_semaphore.synchronize do @demons.any? {|name, pid| running?(pid)} end end |
#demon_count ⇒ Object
49 50 51 52 53 |
# File 'lib/deep_test/warlock.rb', line 49 def demon_count @demons_semaphore.synchronize do @demons.size end end |
#exit_when_none_running ⇒ Object
76 77 78 79 80 81 82 83 84 |
# File 'lib/deep_test/warlock.rb', line 76 def exit_when_none_running Thread.new do loop do Thread.pass exit(0) unless any_running? sleep(0.01) end end end |
#running?(pid) ⇒ Boolean
stolen from daemons
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/deep_test/warlock.rb', line 93 def running?(pid) # Check if process is in existence # The simplest way to do this is to send signal '0' # (which is a single system call) that doesn't actually # send a signal begin Process.kill(0, pid) return true rescue Errno::ESRCH return false rescue ::Exception # for example on EPERM (process exists but does not belong to us) return true #rescue Errno::EPERM # return false end end |
#start(name, &block) ⇒ Object
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 |
# File 'lib/deep_test/warlock.rb', line 9 def start(name, &block) # Not synchronizing for the fork seems to cause # random errors (Bus Error, Segfault, and GC non-object) # in RemoteWorkerServer processes. # begin pid = nil @demons_semaphore.synchronize do pid = DeepTest.drb_safe_fork do # Fork leaves the semaphore locked and we'll never make it # to end of synchronize block. # # The Ruby 1.8.6 C mutex implementation automatically treats # a mutex locked by a dead thread as unlocked and will raise # an error if we try to unlock it from this thread. # @demons_semaphore.unlock if @demons_semaphore.locked? begin yield rescue Exception => e DeepTest.logger.debug "Exception in #{name} (#{Process.pid}): #{e.}" raise end exit end raise "fatal: fork returned nil" if pid.nil? add_demon name, pid end launch_reaper_thread name, pid rescue => e puts "exception starting #{name}: #{e}" puts "\t" + e.backtrace.join("\n\t") end end |
#stop_all ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/deep_test/warlock.rb', line 55 def stop_all DeepTest.logger.debug("stopping all demons") receivers = @demons_semaphore.synchronize do @demons.reverse end receivers.reverse.each do |demon| name, pid = demon if running?(pid) DeepTest.logger.debug("Sending SIGTERM to #{name}, #{pid}") Process.kill("TERM", pid) end end DeepTest.logger.debug("Warlock: Stopped all receivers") DeepTest.logger.debug("waiting for reapers") @reapers.each {|r| r.join} DeepTest.logger.debug("Warlock: done reaping processes") end |