-
Notifications
You must be signed in to change notification settings - Fork 0
/
lock.go
64 lines (51 loc) · 1.43 KB
/
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
59
60
61
62
63
64
package dlock
import (
"time"
"github.com/jinzhu/gorm"
)
type LockKey struct {
Key string `gorm:"primary_key"`
LockTime time.Time
ExpireTime time.Time
}
type DLock struct {
db *gorm.DB
}
func NewDLock(db *gorm.DB) *DLock {
db.AutoMigrate(&LockKey{})
return &DLock{db}
}
func (lock *DLock) Lock(key string, duration time.Duration) bool {
if insertLockKey(lock.db, key, duration) {
return true
}
return updateLockKey(lock.db, key, duration)
}
func (lock *DLock) UnLock(key string) bool {
return deleteLockKey(lock.db, key)
}
func insertLockKey(db *gorm.DB, key string, duration time.Duration) bool {
now := time.Now()
return db.Create(&LockKey{Key: key, ExpireTime: now.Add(duration), LockTime: now}).Error == nil
}
func getLockKey(db *gorm.DB, key string) *LockKey {
lockKey := &LockKey{}
if db.Where("key = ?", key).First(lockKey).RecordNotFound() {
return nil
}
return lockKey
}
func updateLockKey(db *gorm.DB, key string, duration time.Duration) bool {
oldKey := getLockKey(db, key)
if oldKey == nil {
return false
}
if time.Now().Before(oldKey.ExpireTime) {
return false
}
now := time.Now()
return db.Model(&LockKey{}).Where("key = ? AND lock_time = ?", key, oldKey.LockTime).UpdateColumns(map[string]interface{}{"lock_time": now, "expire_time": now.Add(duration)}).RowsAffected == 1
}
func deleteLockKey(db *gorm.DB, key string) bool {
return db.Where("key = ?", key).Delete(&LockKey{}).RowsAffected == 1
}