This commit is contained in:
ppom 2023-07-12 17:45:16 +02:00
parent 98f7f15ae0
commit 075b9252b7
6 changed files with 25 additions and 13 deletions

View File

@ -50,9 +50,9 @@ func (a *ActionStore) Quit() {
a.mutex.Lock() a.mutex.Lock()
defer a.mutex.Unlock() defer a.mutex.Unlock()
for _, actions := range a.store { for _, actions := range a.store {
for _, sigs := range actions { for action, sigs := range actions {
for sig := range sigs { for sig := range sigs {
close(sig) sig <- action.OnExit
} }
} }
} }

View File

@ -76,6 +76,7 @@ func sleep(d time.Duration) chan bool {
func (a *Action) exec(match string, advance time.Duration) { func (a *Action) exec(match string, advance time.Duration) {
defer wgActions.Done() defer wgActions.Done()
doExec := true
// Wait for either end of sleep time, or actionStore requesting stop // Wait for either end of sleep time, or actionStore requesting stop
if a.afterDuration != 0 && a.afterDuration > advance { if a.afterDuration != 0 && a.afterDuration > advance {
@ -83,13 +84,14 @@ func (a *Action) exec(match string, advance time.Duration) {
select { select {
case <-sleep(a.afterDuration - advance): case <-sleep(a.afterDuration - advance):
// no-op // no-op
case _, _ = <-stopAction: case doExec = <-stopAction:
// no-op // no-op
} }
// Let's not wait for the lock // Let's not wait for the lock
go actionStore.Unregister(a, match, stopAction) go actionStore.Unregister(a, match, stopAction)
} }
if doExec {
computedCommand := make([]string, 0, len(a.Cmd)) computedCommand := make([]string, 0, len(a.Cmd))
for _, item := range a.Cmd { for _, item := range a.Cmd {
computedCommand = append(computedCommand, strings.ReplaceAll(item, a.filter.patternWithBraces, match)) computedCommand = append(computedCommand, strings.ReplaceAll(item, a.filter.patternWithBraces, match))
@ -102,6 +104,7 @@ func (a *Action) exec(match string, advance time.Duration) {
if ret := cmd.Run(); ret != nil { if ret := cmd.Run(); ret != nil {
log.Printf("ERROR %s.%s.%s: run %s, code %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand, ret) log.Printf("ERROR %s.%s.%s: run %s, code %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand, ret)
} }
}
} }
func (f *Filter) cleanOldMatches(match string) { func (f *Filter) cleanOldMatches(match string) {

View File

@ -56,6 +56,8 @@ type Action struct {
After string `yaml:"after"` After string `yaml:"after"`
afterDuration time.Duration `yaml:"-"` afterDuration time.Duration `yaml:"-"`
OnExit bool `yaml:"onexit"`
} }
type LogEntry struct { type LogEntry struct {
@ -144,6 +146,8 @@ func (c *Conf) setup() {
log.Fatalln("FATAL Bad configuration: Failed to parse after time in ", stream.name, ".", filter.name, ".", action.name, ":", err) log.Fatalln("FATAL Bad configuration: Failed to parse after time in ", stream.name, ".", filter.name, ".", action.name, ":", err)
} }
action.afterDuration = afterDuration action.afterDuration = afterDuration
} else if action.OnExit {
log.Fatalln("FATAL Bad configuration: Cannot have `onexit:true` without an `after` directive in", stream.name, ".", filter.name, ".", action.name)
} }
if filter.longuestActionDuration == nil || filter.longuestActionDuration.Milliseconds() < action.afterDuration.Milliseconds() { if filter.longuestActionDuration == nil || filter.longuestActionDuration.Milliseconds() < action.afterDuration.Milliseconds() {
filter.longuestActionDuration = &action.afterDuration filter.longuestActionDuration = &action.afterDuration

View File

@ -17,3 +17,4 @@ streams:
sleepdamn: sleepdamn:
cmd: [ "echo", "sleep", "<ip>" ] cmd: [ "echo", "sleep", "<ip>" ]
after: 8m after: 8m
onexit: true

View File

@ -1,5 +1,4 @@
--- ---
# TODO heavily comment this file
# definitions are just a place to put chunks of conf you want to reuse in another place # definitions are just a place to put chunks of conf you want to reuse in another place
# they're not readed by reaction # they're not readed by reaction
definitions: definitions:
@ -42,3 +41,8 @@ streams:
# if after is defined, the action will not take place immediately, but after a specified duration. # if after is defined, the action will not take place immediately, but after a specified duration.
# same format as retry-period # same format as retry-period
after: 48h after: 48h
# let's say reaction is quitting. does it run all those pending commands which had an `after` duration set?
# if you want reaction to run those pending commands before exiting, you can set this:
# onexit: true
# (defaults to false)
# here it is not useful because we will flush the chain containing the bans anyway (see ./reaction.service)

2
go.mod
View File

@ -3,5 +3,5 @@ module framagit.org/ppom/reaction
go 1.19 go 1.19
require ( require (
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1
) )