Created
August 29, 2011 13:54
-
-
Save marianposaceanu/1178437 to your computer and use it in GitHub Desktop.
heartbeat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# we're using the TmpIO class | |
# -*- encoding: binary -*- | |
# :stopdoc: | |
require 'tmpdir' | |
# some versions of Ruby had a broken Tempfile which didn't work | |
# well with unlinked files. This one is much shorter, easier | |
# to understand, and slightly faster. | |
class TmpIO < File | |
# creates and returns a new File object. The File is unlinked | |
# immediately, switched to binary mode, and userspace output | |
# buffering is disabled | |
def self.new | |
fp = begin | |
super("#{Dir::tmpdir}/#{rand}", RDWR|CREAT|EXCL, 0600) | |
rescue Errno::EEXIST | |
retry | |
end | |
unlink(fp.path) | |
fp.binmode | |
fp.sync = true | |
fp | |
end | |
# for easier env["rack.input"] compatibility with Rack <= 1.1 | |
def size | |
stat.size | |
end unless File.method_defined?(:size) | |
end | |
# end | |
# | |
# EXAMPLE | |
# | |
# usage : worker = Worker.new(worker_nr, Unicorn::TmpIO.new) | |
# p TmpIO.new | |
# p TmpIO.new | |
# | |
# Worker class | |
# | |
class Worker < Struct.new(:nr, :tmp, :switched) | |
# worker objects may be compared to just plain Integers | |
def ==(other_nr) # :nodoc: | |
nr == other_nr | |
end | |
end | |
# | |
# EXAMPLE | |
# | |
# we create some workers | |
w1 = Worker.new 1, TmpIO.new | |
w2 = Worker.new 2, TmpIO.new | |
# The chmod will use either ‘1’ or ‘0’ each time this gets executed. | |
# (Assign ‘0’ to the local variable ‘m’, compare it to ‘0’. If it matches (m == 0), m = 1, otherwise m = 0. | |
# A one line toggle.) | |
# this one should be stale | |
p w1.tmp.chmod(m = 0 == m ? 1 : 0) | |
sleep 5 | |
# this one should be ok | |
p w2.tmp.chmod(m = 0 == m ? 1 : 0) | |
WORKERS = [] | |
WORKERS << w1 | |
WORKERS << w2 | |
# Here’s what the master does to check the worker’s status | |
# Even though the file is unlinked it still has metadata associated with it. | |
# Using the file’s #ctime we can check when the file was last mode changed, | |
# and thus when the worker was last alive. | |
timeout = 3 | |
WORKERS.each do |worker| | |
stat = worker.tmp.stat | |
unless (diff = (Time.now - stat.ctime)) <= timeout | |
p "Worker #{worker.nr} has gone stale and needs to be respawned" | |
else | |
p "Worker #{worker.nr} is not stale" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment