/
triggers_lock.go
58 lines (52 loc) · 1.71 KB
/
triggers_lock.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
package redis
import (
"fmt"
"time"
"github.com/gomodule/redigo/redis"
)
// AcquireTriggerCheckLock sets trigger lock by given id. If lock does not take, try again and repeat it for given attempts
func (connector *DbConnector) AcquireTriggerCheckLock(triggerID string, timeout int) error {
acquired, err := connector.SetTriggerCheckLock(triggerID)
if err != nil {
return err
}
count := 0
for !acquired && count < timeout {
count++
<-time.After(time.Millisecond * 500)
acquired, err = connector.SetTriggerCheckLock(triggerID)
if err != nil {
return err
}
}
if !acquired {
return fmt.Errorf("can not acquire trigger lock in %v seconds", timeout)
}
return nil
}
// SetTriggerCheckLock create to database lock object with 30sec TTL and return true if object successfully created, or false if object already exists
func (connector *DbConnector) SetTriggerCheckLock(triggerID string) (bool, error) {
c := connector.pool.Get()
defer c.Close()
_, err := redis.String(c.Do("SET", metricCheckLockKey(triggerID), time.Now().Unix(), "EX", 30, "NX"))
if err != nil {
if err == redis.ErrNil {
return false, nil
}
return false, fmt.Errorf("failed to set check lock: %s error: %s", triggerID, err.Error())
}
return true, nil
}
// DeleteTriggerCheckLock deletes trigger check lock for given triggerID
func (connector *DbConnector) DeleteTriggerCheckLock(triggerID string) error {
c := connector.pool.Get()
defer c.Close()
_, err := c.Do("DEL", metricCheckLockKey(triggerID))
if err != nil {
return fmt.Errorf("failed to delete trigger check lock: %s error: %s", triggerID, err.Error())
}
return nil
}
func metricCheckLockKey(triggerID string) string {
return fmt.Sprintf("moira-metric-check-lock:%s", triggerID)
}