Skip to content

Commit

Permalink
support rescheduling/resetting timers when the time source changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Chuck Remes committed Aug 16, 2010
1 parent 64bbd89 commit bb1c86b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
31 changes: 20 additions & 11 deletions lib/zm/reactor.rb
Expand Up @@ -3,25 +3,25 @@
# Author:: Chuck Remes
# Homepage:: http://github.com/chuckremes/zmqmachine
# Date:: 20100602
#
#
#----------------------------------------------------------------------------
#
# Copyright (C) 2010 by Chuck Remes. All Rights Reserved.
# Email: cremes at mac dot com
#
#
# (The MIT License)
#
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# 'Software'), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Expand All @@ -32,13 +32,13 @@
#
#---------------------------------------------------------------------------
#
#
#

module ZMQMachine

class Reactor
attr_reader :name

# +poll_interval+ is the number of milliseconds to block while
# waiting for new 0mq socket events; default is 0
#
Expand All @@ -61,7 +61,7 @@ def initialize name, poll_interval = 0
end

# Returns true when the reactor is running OR while it is in the
# midst of a shutdown request.
# midst of a shutdown request.
#
# Returns false when the reactor thread does not exist.
#
Expand Down Expand Up @@ -124,12 +124,12 @@ def join delay = nil
end
end
end

# Kills the running reactor instance by terminating its thread.
#
# After the thread exits, the reactor attempts to clean up after itself
# and kill any pending I/O.
#
#
def kill
@stopping = true
@thread.kill
Expand Down Expand Up @@ -273,7 +273,7 @@ def sub_socket handler_instance
save_socket sock
sock
end

# Registers the +sock+ for POLLOUT events that will cause the
# reactor to call the handler's on_writable method.
#
Expand Down Expand Up @@ -332,6 +332,15 @@ def periodical_timer delay, timer_proc = nil, &blk
def cancel_timer timer
@timers.cancel timer
end

# Asks all timers to reschedule themselves starting from Timers.now.
# Typically called when the underlying time source for the ZM::Timers
# class has been replaced; existing timers may not fire as expected, so
# we ask them to reset themselves.
#
def reschedule_timers
@timers.reschedule
end


private
Expand Down
31 changes: 27 additions & 4 deletions lib/zm/timers.rb
Expand Up @@ -122,6 +122,19 @@ def fire_expired
save.each { |timer| @timers.add timer }
end

# Runs through all timers and asks each one to reschedule itself
# from Timers.now + whatever delay was originally recorded.
#
def reschedule
timers = @timers.dup
@timers.clear

timers.each do |timer|
timer.reschedule
@timers.add timer
end
end

# Returns the current time using the following algo:
#
# (Time.now.to_f * 1000).to_i
Expand Down Expand Up @@ -158,6 +171,7 @@ class Timer
attr_reader :fire_time

# +time+ is in milliseconds
#
def initialize timers, delay, periodical, timer_proc = nil, &blk
@timers = timers
@delay = delay.to_i
Expand All @@ -178,6 +192,8 @@ def fire
schedule_firing_time if @periodical
end

# Cancels this timer from firing.
#
def cancel
@timers.cancel self
end
Expand All @@ -186,14 +202,22 @@ def <=>(other)
self.fire_time <=> other.fire_time
end

# True when the timer should be fired; false otherwise.
#
def expired? time
time ||= now
time > @fire_time
end

# True when this is a periodical timer; false otherwise.
#
def periodical?
@periodical
end

def reschedule
schedule_firing_time
end


private
Expand All @@ -209,12 +233,11 @@ def periodical?
# next timer to fire at, 17 + delay 5 = 22
# had it not been late, it would fire at 20
def schedule_firing_time
@fire_time = now + @delay
@initiated = Timers.now

@fire_time = @initiated + @delay
end

def now
Timers.now
end
end # class Timer

end # module ZMQMachine

0 comments on commit bb1c86b

Please sign in to comment.