Implement decision closing job
[cacert-boardvoting.git] / jobs.go
1 package main
2
3 import "time"
4
5 type Job interface {
6 Schedule()
7 Stop()
8 Run()
9 }
10
11 type jobIdentifier int
12
13 const (
14 JobIdCloseDecisions jobIdentifier = iota
15 )
16
17 var rescheduleChannel = make(chan jobIdentifier, 1)
18
19 func JobScheduler(quitChannel chan int) {
20 var jobs = map[jobIdentifier]Job{
21 JobIdCloseDecisions: NewCloseDecisionsJob(),
22 }
23 logger.Println("INFO started job scheduler")
24
25 for {
26 select {
27 case jobId := <-rescheduleChannel:
28 job := jobs[jobId]
29 logger.Println("INFO reschedule job", job)
30 job.Schedule()
31 case <-quitChannel:
32 for _, job := range jobs {
33 job.Stop()
34 }
35 logger.Println("INFO stop job scheduler")
36 return
37 }
38 }
39 }
40
41 type CloseDecisionsJob struct {
42 timer *time.Timer
43 }
44
45 func NewCloseDecisionsJob() *CloseDecisionsJob {
46 job := &CloseDecisionsJob{}
47 job.Schedule()
48 return job
49 }
50
51 func (j *CloseDecisionsJob) Schedule() {
52 var nextDue *time.Time
53 nextDue, err := GetNextPendingDecisionDue()
54 if err != nil {
55 logger.Fatal("ERROR Could not get next pending due date")
56 if j.timer != nil {
57 j.timer.Stop()
58 j.timer = nil
59 }
60 return
61 }
62 if nextDue == nil {
63 if j.timer != nil {
64 j.timer.Stop()
65 j.timer = nil
66 }
67 } else {
68 logger.Println("INFO scheduling CloseDecisionsJob for", nextDue)
69 when := nextDue.Sub(time.Now())
70 if j.timer != nil {
71 j.timer.Reset(when)
72 } else {
73 j.timer = time.AfterFunc(when, j.Run)
74 }
75 }
76 }
77
78 func (j *CloseDecisionsJob) Stop() {
79 if j.timer != nil {
80 j.timer.Stop()
81 }
82 }
83
84 func (j *CloseDecisionsJob) Run() {
85 logger.Println("INFO running CloseDecisionsJob")
86 err := CloseDecisions()
87 if err != nil {
88 logger.Println("ERROR closing decisions", err)
89 }
90 rescheduleChannel <- JobIdCloseDecisions
91 }
92
93 func (j *CloseDecisionsJob) String() string {
94 return "CloseDecisionsJob"
95 }