package client import ( "fmt" "time" "golang.conradwood.net/go-easyops/utils" ) type TimeoutLock interface { Unlock() Lock() LockWithTimeout(time.Duration) bool // true if lock was acquired } type timeoutlock struct { ch chan bool name string lockedat string } func NewTimeoutLock(name string) TimeoutLock { tl := &timeoutlock{ name: name, ch: make(chan bool, 1), } return tl } func (tl *timeoutlock) Lock() { tl.ch <- true tl.lockedat = utils.GetStack("lock %s", tl.name) } func (tl *timeoutlock) LockWithTimeout(t time.Duration) bool { select { case tl.ch <- true: tl.lockedat = utils.GetStack("lock %s", tl.name) return true case <-time.After(t): utils.PrintStack("[go-easyops] lock \"%s\" timeout", tl.name) fmt.Printf("lock \"%s\" was locked at: %s\n", tl.name, tl.lockedat) return false } } func (tl *timeoutlock) Unlock() { select { case <-tl.ch: // default: // nothing to unlock fmt.Printf("[go-easyops] timeoutlock \"%s\" unlocked but was not locked previously\n", tl.name) utils.PrintStack("[go-easyops]") } }