File: tickrunner.go

package info (click to toggle)
receptor 1.5.5-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,772 kB
  • sloc: python: 1,643; makefile: 305; sh: 174
file content (38 lines) | stat: -rw-r--r-- 1,065 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package tickrunner

import (
	"context"
	"time"
)

// Run runs a task at a given periodic interval, or as requested over a channel.
// If many requests come in close to the same time, only run the task once.
// Callers can ask for the task to be run within a given amount of time, which
// overrides defaultReqDelay. Sending a zero to the channel runs it after defaukltReqDelay.
func Run(ctx context.Context, f func(), periodicInterval time.Duration, defaultReqDelay time.Duration) chan time.Duration {
	runChan := make(chan time.Duration)
	go func() {
		nextRunTime := time.Now().Add(periodicInterval)
		for {
			select {
			case <-time.After(time.Until(nextRunTime)):
				nextRunTime = time.Now().Add(periodicInterval)
				f()
			case req := <-runChan:
				proposedTime := time.Now()
				if req == 0 {
					proposedTime = proposedTime.Add(defaultReqDelay)
				} else {
					proposedTime = proposedTime.Add(req)
				}
				if proposedTime.Before(nextRunTime) {
					nextRunTime = proposedTime
				}
			case <-ctx.Done():
				return
			}
		}
	}()

	return runChan
}