1. the test code.
require 'eventmachine'
puts 'Start'
EM.run do
EM::add_periodic_timer 1.0 do
puts "time: #{Time.new.to_f.round(1)}"
end
end
2. output in my MacBook Pro.
time: 1298620726.9
time: 1298620728.0
time: 1298620729.1
time: 1298620730.1
time: 1298620731.2
time: 1298620732.3
time: 1298620733.4
time: 1298620734.5
time: 1298620735.5
time: 1298620736.6
time: 1298620737.7
time: 1298620738.8
time: 1298620739.9
time: 1298620741.0
time: 1298620742.0
time: 1298620743.1
time: 1298620744.2
time: 1298620745.3
time: 1298620746.4
time: 1298620747.4
time: 1298620748.5
time: 1298620749.6
As you can see, it drifted 100ms every time. Which is not very good when you want to do some job every 1 second. You might omit some seconds. So, with using the same method that I used for the Periodic ruby service, I made a change to PeriodicTimer. It looks like this.
# Override PeriodicTimer
module EventMachine
class PeriodicTimer
alias :old_initialize :initialize
def initialize interval, callback=nil, &block
# Added two additional instance variables to compensate difference.
@start = Time.now
@fixed_interval = interval
old_initialize interval, callback, &block
end
alias :old_schedule :schedule
def schedule
# print "Started at #{@start}..: "
compensation = (Time.now - @start) % @fixed_interval
@interval = @fixed_interval - compensation
# Schedule
old_schedule
end
end
end
So, here is the result (this is not that accurate like the simple ruby service, but reasonably useable.
time: 1298620683.4
time: 1298620684.4
time: 1298620685.4
time: 1298620686.4
time: 1298620687.4
time: 1298620688.4
time: 1298620689.4
time: 1298620690.4
time: 1298620691.3
time: 1298620692.3
time: 1298620693.4
time: 1298620694.4
time: 1298620695.4
time: 1298620696.4
time: 1298620697.4
time: 1298620698.4
time: 1298620699.4
That's it. :-)
No comments:
Post a Comment