lib/pitchfork/worker.rb in pitchfork-0.1.2 vs lib/pitchfork/worker.rb in pitchfork-0.2.0
- old
+ new
@@ -5,26 +5,26 @@
# This class and its members can be considered a stable interface
# and will not change in a backwards-incompatible fashion between
# releases of pitchfork. Knowledge of this class is generally not
# not needed for most users of pitchfork.
#
- # Some users may want to access it in the before_fork/after_fork hooks.
+ # Some users may want to access it in the after_promotion/after_fork hooks.
# See the Pitchfork::Configurator RDoc for examples.
class Worker
# :stopdoc:
EXIT_SIGNALS = [:QUIT, :TERM]
- @generation = 0
attr_accessor :nr, :pid, :generation
- attr_reader :master
+ attr_reader :master, :requests_count
def initialize(nr, pid: nil, generation: 0)
@nr = nr
@pid = pid
@generation = generation
@mold = false
@to_io = @master = nil
@exiting = false
+ @requests_count = 0
if nr
build_raindrops(nr)
else
promoted!
end
@@ -40,17 +40,21 @@
def exiting?
@exiting
end
+ def outdated?
+ CURRENT_GENERATION_DROP[0] > @generation
+ end
+
def update(message)
message.class.members.each do |member|
send("#{member}=", message.public_send(member))
end
case message
- when Message::WorkerPromoted, Message::PromoteWorker
+ when Message::WorkerPromoted
promoted!
end
end
def register_to_master(control_socket)
@@ -58,28 +62,35 @@
message = Message::WorkerSpawned.new(@nr, Process.pid, generation, @master)
control_socket.sendmsg(message)
@master.close
end
- def acknowlege_promotion(control_socket)
+ def declare_promotion(control_socket)
message = Message::WorkerPromoted.new(@nr, Process.pid, generation)
control_socket.sendmsg(message)
+ CURRENT_GENERATION_DROP[0] = @generation
end
def promote(generation)
send_message_nonblock(Message::PromoteWorker.new(generation))
end
def spawn_worker(new_worker)
send_message_nonblock(Message::SpawnWorker.new(new_worker.nr))
end
+ def promote!
+ @generation += 1
+ promoted!
+ end
+
def promoted!
@mold = true
@nr = nil
@drop_offset = 0
@tick_drop = MOLD_DROP
+ self
end
def mold?
@mold
end
@@ -167,21 +178,17 @@
@tick_drop[@drop_offset]
end
end
def reset
- @requests_drop[@drop_offset] = 0
+ @requests_count = 0
end
- def requests_count
- @requests_drop[@drop_offset]
+ def increment_requests_count(by = 1)
+ @requests_count += by
end
- def increment_requests_count
- @requests_drop.incr(@drop_offset)
- end
-
# called in both the master (reaping worker) and worker (SIGQUIT handler)
def close # :nodoc:
@master.close if @master
@to_io.close if @to_io
end
@@ -213,32 +220,30 @@
end
success
end
MOLD_DROP = Raindrops.new(1)
+ CURRENT_GENERATION_DROP = Raindrops.new(1)
PER_DROP = Raindrops::PAGE_SIZE / Raindrops::SIZE
TICK_DROPS = []
- REQUEST_DROPS = []
class << self
# Since workers are created from another process, we have to
# pre-allocate the drops so they are shared between everyone.
#
# However this doesn't account for TTIN signals that increase the
# number of workers, but we should probably remove that feature too.
def preallocate_drops(workers_count)
0.upto(workers_count / PER_DROP) do |i|
TICK_DROPS[i] = Raindrops.new(PER_DROP)
- REQUEST_DROPS[i] = Raindrops.new(PER_DROP)
end
end
end
def build_raindrops(drop_nr)
drop_index = drop_nr / PER_DROP
@drop_offset = drop_nr % PER_DROP
@tick_drop = TICK_DROPS[drop_index] ||= Raindrops.new(PER_DROP)
- @requests_drop = REQUEST_DROPS[drop_index] ||= Raindrops.new(PER_DROP)
- @tick_drop[@drop_offset] = @requests_drop[@drop_offset] = 0
+ @tick_drop[@drop_offset] = 0
end
end
end