In: |
lib/rq-3.0.0/refresher.rb
|
Parent: | Object |
the job of the Refresher is to maintain a lease on a file that has been locked. the method is simply to touch the file at a certain interval thereby keeping it ‘fresh’. a separate process, vs. a thread, is used for this task to eliminate any chance that the ruby interpreter might put all threads to sleep for some blocking tasks, like fcntl based locks which are used heavily in RQ, resulting in a a prematurely stale lockfile
SIGNALS | = | %w(SIGTERM SIGINT SIGKILL) |
path | [R] | |
pid | [R] | |
refresh_rate | [R] |
# File lib/rq-3.0.0/refresher.rb, line 21 21: def initialize path, refresh_rate = 8 22: #--{{{ 23: @path = path 24: File::stat path 25: @refresh_rate = Float refresh_rate 26: @pipe = IO::pipe 27: if((@pid = Util::fork)) 28: @pipe.last.close 29: @pipe = @pipe.first 30: @thread = Thread::new{loop{@pipe.gets}} 31: Process::detach @pid 32: else 33: begin 34: pid = Process::pid 35: ppid = Process::ppid 36: $0 = "#{ path }.refresher.#{ pid }" 37: SIGNALS.each{|sig| trap(sig){ raise }} 38: @pipe.first.close 39: @pipe = @pipe.last 40: loop do 41: FileUtils::touch @path 42: sleep @refresh_rate 43: Process::kill 0, ppid 44: @pipe.puts pid 45: end 46: rescue Exception => e 47: exit! 48: end 49: end 50: #--}}} 51: end
# File lib/rq-3.0.0/refresher.rb, line 52 52: def kill 53: #--{{{ 54: begin 55: @thread.kill rescue nil 56: @pipe.close rescue nil 57: SIGNALS.each{|sig| Process::kill sig, @pid rescue nil} 58: ensure 59: =begin 60: n = 42 61: dead = false 62: begin 63: n.times do |i| 64: Process::kill 0, @pid 65: sleep 1 66: end 67: rescue Errno::ESRCH 68: dead = true 69: end 70: raise "runaway refresher <#{ @pid }> must be killed!" unless dead 71: =end 72: 73: end 74: #--}}} 75: end