better data structures for matches & actions maps
This commit is contained in:
parent
b6d7e5a946
commit
d26c7f24f2
@ -111,12 +111,7 @@ func ActionsManager() {
|
|||||||
go action.exec(match)
|
go action.exec(match)
|
||||||
} else {
|
} else {
|
||||||
actionsLock.Lock()
|
actionsLock.Lock()
|
||||||
// make sure map exists
|
actions[PAT{match, action, then}] = struct{}{}
|
||||||
if actions[action] == nil {
|
|
||||||
actions[action] = make(PatternTimes)
|
|
||||||
}
|
|
||||||
// append() to nil is valid go
|
|
||||||
actions[action][match] = append(actions[action][match], then)
|
|
||||||
actionsLock.Unlock()
|
actionsLock.Unlock()
|
||||||
go func(pat PAT, now time.Time) {
|
go func(pat PAT, now time.Time) {
|
||||||
time.Sleep(pat.t.Sub(now))
|
time.Sleep(pat.t.Sub(now))
|
||||||
@ -124,23 +119,20 @@ func ActionsManager() {
|
|||||||
}(pat, now)
|
}(pat, now)
|
||||||
}
|
}
|
||||||
case pat = <-pendingActionsC:
|
case pat = <-pendingActionsC:
|
||||||
match = pat.p
|
match, action, then = pat.p, pat.a, pat.t
|
||||||
action = pat.a
|
|
||||||
actionsLock.Lock()
|
actionsLock.Lock()
|
||||||
actions[action][match] = actions[action][match][1:]
|
delete(actions, PAT{match, action, then})
|
||||||
actionsLock.Unlock()
|
actionsLock.Unlock()
|
||||||
wgActions.Add(1)
|
wgActions.Add(1)
|
||||||
go action.exec(match)
|
go action.exec(match)
|
||||||
case _, _ = <-stopActions:
|
case _, _ = <-stopActions:
|
||||||
actionsLock.Lock()
|
actionsLock.Lock()
|
||||||
for action := range actions {
|
for pat := range actions {
|
||||||
if action.OnExit {
|
if pat.a.OnExit {
|
||||||
for match := range actions[action] {
|
|
||||||
wgActions.Add(1)
|
wgActions.Add(1)
|
||||||
go action.exec(match)
|
go action.exec(match)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
actionsLock.Unlock()
|
actionsLock.Unlock()
|
||||||
wgActions.Done()
|
wgActions.Done()
|
||||||
return
|
return
|
||||||
@ -156,7 +148,7 @@ func MatchesManager() {
|
|||||||
for !end {
|
for !end {
|
||||||
select {
|
select {
|
||||||
case pf = <-cleanMatchesC:
|
case pf = <-cleanMatchesC:
|
||||||
delete(matches[pf.f], pf.p)
|
delete(matches, pf)
|
||||||
case pft, ok := <-startupMatchesC:
|
case pft, ok := <-startupMatchesC:
|
||||||
if !ok {
|
if !ok {
|
||||||
end = true
|
end = true
|
||||||
@ -170,7 +162,7 @@ func MatchesManager() {
|
|||||||
select {
|
select {
|
||||||
case pf = <-cleanMatchesC:
|
case pf = <-cleanMatchesC:
|
||||||
matchesLock.Lock()
|
matchesLock.Lock()
|
||||||
delete(matches[pf.f], pf.p)
|
delete(matches, pf)
|
||||||
matchesLock.Unlock()
|
matchesLock.Unlock()
|
||||||
case pft = <-matchesC:
|
case pft = <-matchesC:
|
||||||
|
|
||||||
@ -187,26 +179,25 @@ func MatchesManager() {
|
|||||||
|
|
||||||
func matchesManagerHandleMatch(pft PFT) bool {
|
func matchesManagerHandleMatch(pft PFT) bool {
|
||||||
filter, match, then := pft.f, pft.p, pft.t
|
filter, match, then := pft.f, pft.p, pft.t
|
||||||
|
pf := PF{pft.p, pft.f}
|
||||||
|
|
||||||
if filter.Retry > 1 {
|
if filter.Retry > 1 {
|
||||||
// make sure map exists
|
// make sure map exists
|
||||||
if matches[filter] == nil {
|
if matches[pf] == nil {
|
||||||
matches[filter] = make(PatternTimes)
|
matches[pf] = make(map[time.Time]struct{})
|
||||||
}
|
}
|
||||||
// clean old matches
|
// clean old matches
|
||||||
newMatches := make([]time.Time, 0, len(matches[filter][match]))
|
for old := range matches[pf] {
|
||||||
for _, old := range matches[filter][match] {
|
if !old.Add(filter.retryDuration).After(then) {
|
||||||
if old.Add(filter.retryDuration).After(then) {
|
delete(matches[pf], old)
|
||||||
newMatches = append(newMatches, old)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add new match
|
// add new match
|
||||||
newMatches = append(newMatches, then)
|
matches[pf][then] = struct{}{}
|
||||||
matches[filter][match] = newMatches
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if filter.Retry <= 1 || len(matches[filter][match]) >= filter.Retry {
|
if filter.Retry <= 1 || len(matches[pf]) >= filter.Retry {
|
||||||
delete(matches[filter], match)
|
delete(matches, pf)
|
||||||
filter.sendActions(match, then)
|
filter.sendActions(match, then)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
26
app/pipe.go
26
app/pipe.go
@ -14,45 +14,37 @@ func genClientStatus() ClientStatus {
|
|||||||
matchesLock.Lock()
|
matchesLock.Lock()
|
||||||
|
|
||||||
// Painful data manipulation
|
// Painful data manipulation
|
||||||
for filter, filterMatches := range matches {
|
for pf, times := range matches {
|
||||||
|
pattern, filter := pf.p, pf.f
|
||||||
if cs[filter.stream.name] == nil {
|
if cs[filter.stream.name] == nil {
|
||||||
cs[filter.stream.name] = make(map[string]MapPatternStatus)
|
cs[filter.stream.name] = make(map[string]MapPatternStatus)
|
||||||
}
|
}
|
||||||
if cs[filter.stream.name][filter.name] == nil {
|
if cs[filter.stream.name][filter.name] == nil {
|
||||||
cs[filter.stream.name][filter.name] = make(MapPatternStatus)
|
cs[filter.stream.name][filter.name] = make(MapPatternStatus)
|
||||||
}
|
}
|
||||||
for pattern, patternMatches := range filterMatches {
|
cs[filter.stream.name][filter.name][pattern] = &PatternStatus{len(times), nil}
|
||||||
var ps PatternStatus
|
|
||||||
cs[filter.stream.name][filter.name][pattern] = &ps
|
|
||||||
|
|
||||||
ps.Matches = len(patternMatches)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
matchesLock.Unlock()
|
matchesLock.Unlock()
|
||||||
actionsLock.Lock()
|
actionsLock.Lock()
|
||||||
|
|
||||||
// Painful data manipulation
|
// Painful data manipulation
|
||||||
for action, pendingActions := range actions {
|
for pat := range actions {
|
||||||
|
pattern, action, then := pat.p, pat.a, pat.t
|
||||||
if cs[action.filter.stream.name] == nil {
|
if cs[action.filter.stream.name] == nil {
|
||||||
cs[action.filter.stream.name] = make(map[string]MapPatternStatus)
|
cs[action.filter.stream.name] = make(map[string]MapPatternStatus)
|
||||||
}
|
}
|
||||||
if cs[action.filter.stream.name][action.filter.name] == nil {
|
if cs[action.filter.stream.name][action.filter.name] == nil {
|
||||||
cs[action.filter.stream.name][action.filter.name] = make(MapPatternStatus)
|
cs[action.filter.stream.name][action.filter.name] = make(MapPatternStatus)
|
||||||
}
|
}
|
||||||
for pattern, patternPendingActions := range pendingActions {
|
|
||||||
if cs[action.filter.stream.name][action.filter.name][pattern] == nil {
|
if cs[action.filter.stream.name][action.filter.name][pattern] == nil {
|
||||||
var ps PatternStatus
|
cs[action.filter.stream.name][action.filter.name][pattern] = new(PatternStatus)
|
||||||
cs[action.filter.stream.name][action.filter.name][pattern] = &ps
|
|
||||||
}
|
}
|
||||||
var ps *PatternStatus
|
ps := cs[action.filter.stream.name][action.filter.name][pattern]
|
||||||
ps = cs[action.filter.stream.name][action.filter.name][pattern]
|
if ps.Actions == nil {
|
||||||
ps.Actions = make(map[string][]string)
|
ps.Actions = make(map[string][]string)
|
||||||
|
|
||||||
for _, t := range patternPendingActions {
|
|
||||||
ps.Actions[action.name] = append(ps.Actions[action.name], t.Format(time.DateTime))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ps.Actions[action.name] = append(ps.Actions[action.name], then.Format(time.DateTime))
|
||||||
}
|
}
|
||||||
actionsLock.Unlock()
|
actionsLock.Unlock()
|
||||||
return cs
|
return cs
|
||||||
|
@ -75,13 +75,10 @@ type WriteDB struct {
|
|||||||
enc *gob.Encoder
|
enc *gob.Encoder
|
||||||
}
|
}
|
||||||
|
|
||||||
type PatternTimes map[string][]time.Time
|
type MatchesMap map[PF]map[time.Time]struct{}
|
||||||
|
type ActionsMap map[PAT]struct{}
|
||||||
|
|
||||||
type MatchesMap map[*Filter]PatternTimes
|
// Helper structs made to carry information
|
||||||
|
|
||||||
type ActionsMap map[*Action]PatternTimes
|
|
||||||
|
|
||||||
// Helper structs made to carry information across channels
|
|
||||||
type SF struct{ s, f string }
|
type SF struct{ s, f string }
|
||||||
type PSF struct{ p, s, f string }
|
type PSF struct{ p, s, f string }
|
||||||
type PF struct {
|
type PF struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user