gocron icon indicating copy to clipboard operation
gocron copied to clipboard

add TimerWheel

Open flier opened this issue 9 years ago • 6 comments

  1. new scheduler base on the TimeWheel algorithm for the massive timers scene
  2. add one time job with After(interval uint64) *Job
  3. add new time unit func (j *Job) Milliseconds() (job *Job)
  4. test cases and benchmark for performance
PASS
BenchmarkSchedule-8  2000000           607 ns/op
BenchmarkPending-8  10000000           391 ns/op
BenchmarkCancel-8    2000000          1007 ns/op

flier avatar Dec 16 '15 10:12 flier

@flier This isn't working. The interface you implemented is structured much better than the rest of this project and on all accounts the algorithm you're attempting to implement is way more efficient than what is currently implemented. But, when I try to schedule something simple like this your implementation clearly isn't working. Please let me know if you fix it.

    secondCount := 1
    scheduler.Every(1).Second().Do(func() {
        log.Printf("%d second", secondCount)
        secondCount++
    })
    scheduler.Every(1).Minute().Do(func() {
        log.Printf("%d minute", secondCount/60)
    })
    scheduler.Every(1).Hour().Do(func() {
        log.Printf("%d hour", secondCount/(60*60))
    })

marksalpeter avatar Dec 19 '15 18:12 marksalpeter

@flier Also, I'm working on a version 1 refactor. Check out the Scheduler interface in the new v1 branch. If you can implement those methods with the timer wheel algorithm we can throw out the old scheduler and use your TimeWheel implementation instead.

marksalpeter avatar Dec 20 '15 22:12 marksalpeter

For the TM scheduler, we need start the scheduler first

https://gist.github.com/flier/749b82879b48dbc739eb

On the other hand, I suggest we could split the Scheduler interface to two layers, a BaseScheduler focus on the job itself, a Schduler interface to provider more powerful methods like RunAll/RunAllWithDelay, because some methods are very expensive or be used seldom.

https://gist.github.com/flier/7823f7ef02eff0058a7f

What's your opinion?

Mark Salpeter [email protected]于2015年12月21日周一 上午6:38写道:

@flier https://github.com/flier Also, I'm working on a version 1 refactor. Check out the Scheduler interface in the new v1 branch https://github.com/jasonlvhit/gocron/tree/v1.0. If you can implement those methods with the timer wheel algorithm we can throw out the old scheduler and use your TimeWheel implementation instead.

— Reply to this email directly or view it on GitHub https://github.com/jasonlvhit/gocron/pull/8#issuecomment-166159927.

flier avatar Dec 21 '15 15:12 flier

I actually don't see the use cases for RunAll/RunAllWithDelay, but couldn't those be implemented by iterating over the backing slice of jobs? Is there a good resource for the timer wheel algorithm somewhere so that I can better understand the issue? Is it just a matter of keeping the job slice in sort order at all times?

marksalpeter avatar Dec 21 '15 16:12 marksalpeter

In fact, I implement the time wheel scheduler for some internal networking projects, we need maintain millions of timers/tickers, that's why I must suppress all the routines in O(1) or O(log n) instead of lock a slot too long. That's why I said it may too expensive or be used seldom.

Yes, we can locking and iterating all the slots one by one, if you believe the unified API will be better, but I doubt it is a real requirements in such kind of scene :)

Mark Salpeter [email protected]于2015年12月22日周二 上午12:52写道:

I actually don't see the use cases for RunAll/RunAllWithDelay, but couldn't those be implemented by iterating over the backing slice of jobs? Is there a good resource for the timer wheel algorithm somewhere so that I can better understand the issue?

— Reply to this email directly or view it on GitHub https://github.com/jasonlvhit/gocron/pull/8#issuecomment-166357235.

flier avatar Dec 22 '15 02:12 flier

any progress on that? sounds very promising.

denkhaus avatar Sep 10 '16 14:09 denkhaus