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