jmettraux/rufus-scheduler

Overlap: false query

Closed this issue · 6 comments

If I set overlap: false, and given my scheduled block of code can take varying times, let's consider this scenario.

I want my scheduler to fetch a file from CDN every 5s. My block of code takes 10s.
Will the scheduler immediately execute my block of code at 11th second or would it wait 5s after the first block of code completed and will execute it at 15th second?

What should I do if I want it to immediately execute at 11th?

What should I do if I want it to immediately execute at 11th?

Sorry, but why are you using rufus-scheduler for that?

You can do

Thread.new do
  begin
  loop do
    fetch_file_from_cdn # takes 10 seconds anyway
  end
  rescue => err
   puts "fetching thread intercepted error"
   p err
   puts err.backtrace
  end
end

If you do:

scheduler.every '5s', overlap: false do
  fetch_file_from_cdn # takes 10 seconds
end

it will usually trigger at time t0, trigger at time t0 + 5, notice it's already active and skip, trigger at time t0 + 10 and skips if it's already active, at t0 + 15 the fetching should be done and the job will not skip, ... And so on...

Yeah, I do want to execute every 5s. But if the block code takes more than 5s, it should execute the code block immediately after the first has completed.

Yeah, I do want to execute every 5s. But if the block code
takes more than 5s, it should execute the code block immediately
after the first has completed.

def do_fetch_file_from_cdn(every=5)
  t = Time.now
  fetch_file_from_cdn # your code
  d = Time.now - t
  sleep (every - d) if d < every
rescue => err
  puts "*** file fetching #{t.to_s} failed"
  p err
  puts err.backtrace
end

Thread.new do
  loop { do_fetch_file_from_cdn(5) }
end

I hope this will help you.

Kind regards.

@jmettraux I like other features that rufus-scheduler provides.
Check running status, pause, resume etc.
Can I mimic exact beahvior using rufus? Or you think using rufus for this is an overkill?

Can I mimic exact beahvior using rufus? Or you think using rufus for this is an overkill?

I think that if you relax your requirement you can use rufus-scheduler. Personally, I would simply do

scheduler.every '5s', overlap: false do
  fetch_file_from_cdn
end

and never care for cases where the file is not fetched immediately. At worst, the file gets 10 seconds old (it seems to be your max fetch time).

If you really need to fetch it asap, you could also do:

scheduler.every '0.001s', overlap: false do
   fetch_file_from_cdn
end

and still benefit from status, pause, resume, etc...

Best regards.