-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcron-actions.go
140 lines (119 loc) · 3.02 KB
/
cron-actions.go
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"fmt"
"strings"
"sync"
"github.com/mileusna/crontab"
"github.com/reeveci/reeve-lib/schema"
)
func NewCronActions(plugin *GiteaPlugin) *CronActions {
a := &CronActions{
plugin: plugin,
repos: make(map[string]cronActionSet),
}
return a
}
type CronActions struct {
lock sync.Mutex
plugin *GiteaPlugin
repos map[string]cronActionSet
}
func (a *CronActions) UpdateRules(repository string, rules CronRuleset) {
a.lock.Lock()
defer a.lock.Unlock()
prev, found := a.repos[repository]
if found {
if prev.rules.compare(rules) {
return
}
prev.handler.Clear()
prev.handler.Shutdown()
}
if len(rules) == 0 {
if found {
a.plugin.Log.Info(fmt.Sprintf("clearing cron triggers for repository %s", repository))
delete(a.repos, repository)
}
return
}
a.plugin.Log.Info(fmt.Sprintf("updating cron triggers for repository %s", repository))
handler := crontab.New()
a.repos[repository] = cronActionSet{handler, rules}
for cron, actions := range rules {
actionNames := make([]string, 0, len(actions))
messages := make([]schema.Message, 0, len(actions))
for action, enabled := range actions {
if enabled {
actionNames = append(actionNames, string(action))
messages = append(messages, schema.Message{
Target: PLUGIN_NAME,
Options: map[string]string{
"type": "action",
"action": string(action),
},
})
}
}
if len(messages) > 0 {
err := handler.AddJob(string(cron), a.sendMessages, fmt.Sprintf("triggering scheduled cron actions - %s", strings.Join(actionNames, ", ")), messages)
if err != nil {
a.plugin.Log.Error(fmt.Sprintf("error registering Cron job - %s", err))
}
}
}
}
func (a *CronActions) Close() {
a.lock.Lock()
defer a.lock.Unlock()
for _, set := range a.repos {
set.handler.Clear()
set.handler.Shutdown()
}
a.repos = nil
}
func (a *CronActions) sendMessages(logMessage string, messages []schema.Message) {
a.plugin.Log.Info(logMessage)
err := a.plugin.API.NotifyMessages(messages)
if err != nil {
a.plugin.Log.Error(fmt.Sprintf("error sending Cron actions - %s", err))
}
}
type cronActionSet struct {
handler *crontab.Crontab
rules CronRuleset
}
func NewCronRuleset() CronRuleset {
return make(CronRuleset)
}
type CronRuleset map[Cron]map[ActionName]bool
type Cron string
type ActionName string
func (r CronRuleset) Add(cronExpression, action string) {
if cronExpression == "" || action == "" {
return
}
cron := Cron(cronExpression)
actionName := ActionName(action)
if actions, found := r[cron]; found {
actions[actionName] = true
} else {
r[cron] = map[ActionName]bool{(actionName): true}
}
}
func (r CronRuleset) compare(other CronRuleset) bool {
if len(r) != len(other) {
return false
}
for cron, actions := range r {
otherActions, found := other[cron]
if !found || len(actions) != len(otherActions) {
return false
}
for action, enabled := range actions {
if otherEnabled, found := otherActions[action]; !found || enabled != otherEnabled {
return false
}
}
}
return true
}