質問

I'm using the rufus scheduler to have some tasks execute every so often. I'd like the tasks to all run more or less immediately when the script starts and then at the given interval. This doesn't seem to be supported by API, or am I missing something?

I've resorted to specifying 0.1 seconds as the delay until the first run as follows

scheduler = Rufus::Scheduler.new

scheduler.every '10s', :first_in => 0.1 do
    #do some work
end 

If the :first_in property is set to 0, the scheduler waits the full 10 second before running the first time. If the value is set too low (I suppose to something that evaluates to in the past when it comes to execute the task), or if I use Time.now, the following error is raised:

~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:383:in `first_at=': cannot set first[_at|_in] in the past: 1.0e-07 -> 2014-01-22 10:44:32 +0000 (ArgumentError)
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:445:in `first_at='
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:370:in `initialize'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler/jobs.rb:457:in `initialize'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler.rb:570:in `new'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler.rb:570:in `do_schedule'
    from ~/.ruby/gems/rufus-scheduler-3.0.4/lib/rufus/scheduler.rb:207:in `every'
    from rufus_runner.rb:11:in `<main>'

Any idea what the right way is to do this?

役に立ちましたか?

解決

Pierre-Louis is close:

require 'rufus-scheduler'

s = Rufus::Scheduler.new

p [ :scheduled_at, Time.now ]

s.every '5s', :first_in => 0.4 do
  p [ :every,  Time.now ]
end

s.join

Rufus-scheduler wakes up, by default, thrice per second so 0.4 is a good approximation.

This emits:

[:scheduled_at, Wed Jan 22 20:30:55 +0900 2014]
[:every, Wed Jan 22 20:30:56 +0900 2014]
[:every, Wed Jan 22 20:31:01 +0900 2014]
[:every, Wed Jan 22 20:31:06 +0900 2014]
[:every, Wed Jan 22 20:31:11 +0900 2014]
...

他のヒント

You can wrap the job in a proc and call it immediately the first time:

job = Proc.new do
  # do some work
end.call

scheduler.every '10', &job

EDIT: In a future release you will be able to do:

scheduler.every '10', first: :now

You can do the following:

scheduler.every '10s', first_in: 1.second.since do
  # ...
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top