95 lines
1.7 KiB
Go
95 lines
1.7 KiB
Go
package lease
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
|
|
"github.com/tblyler/sheepmq/shepard"
|
|
)
|
|
|
|
var (
|
|
// ErrLeased denotes the item is already leased
|
|
ErrLeased = errors.New("Item is already leased")
|
|
|
|
// ErrNoLeaser denotes no leaser was provided to add a lease
|
|
ErrNoLeaser = errors.New("No leaser provided")
|
|
)
|
|
|
|
// Manager contains many leases and their validity
|
|
type Manager struct {
|
|
leases map[uint64]Leaser
|
|
locker sync.RWMutex
|
|
}
|
|
|
|
// NewManager creates a new Manager instance
|
|
func NewManager() *Manager {
|
|
return &Manager{
|
|
leases: make(map[uint64]Leaser),
|
|
}
|
|
}
|
|
|
|
// AddLease to the manager for the given item
|
|
func (m *Manager) AddLease(id uint64, info *shepard.GetInfo) error {
|
|
if m.CheckLease(id) {
|
|
return ErrLeased
|
|
}
|
|
|
|
var leaser Leaser
|
|
if info.TimeoutLease != nil {
|
|
leaser = NewTimeout(info.TimeoutLease.Ttl)
|
|
} else if info.PidLease != nil {
|
|
leaser = NewPID(int(info.PidLease.Pid))
|
|
} else if info.HeartLease != nil {
|
|
leaser = NewHeart(info.HeartLease.Ttl)
|
|
} else {
|
|
return ErrNoLeaser
|
|
}
|
|
|
|
m.locker.Lock()
|
|
m.leases[id] = leaser
|
|
m.locker.Unlock()
|
|
|
|
return nil
|
|
}
|
|
|
|
// CheckLease for validity
|
|
func (m *Manager) CheckLease(id uint64) bool {
|
|
m.locker.RLock()
|
|
lease, exists := m.leases[id]
|
|
if !exists {
|
|
m.locker.RUnlock()
|
|
return false
|
|
}
|
|
|
|
ret := lease.Valid()
|
|
m.locker.RUnlock()
|
|
if !ret {
|
|
// delete the lease since it is no longer valid
|
|
m.locker.Lock()
|
|
delete(m.leases, id)
|
|
m.locker.Unlock()
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
// PruneLeases that fail their checks
|
|
func (m *Manager) PruneLeases() {
|
|
deleteKeys := []uint64{}
|
|
m.locker.RLock()
|
|
|
|
for key, lease := range m.leases {
|
|
if !lease.Check() {
|
|
deleteKeys = append(deleteKeys, key)
|
|
}
|
|
}
|
|
|
|
m.locker.RUnlock()
|
|
m.locker.Lock()
|
|
for _, key := range deleteKeys {
|
|
delete(m.leases, key)
|
|
}
|
|
|
|
m.locker.Unlock()
|
|
}
|