mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
113 lines
3.0 KiB
Go
113 lines
3.0 KiB
Go
// Copyright 2022 The etcd Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package lease
|
|
|
|
import (
|
|
"math"
|
|
"sync"
|
|
"time"
|
|
|
|
"go.etcd.io/etcd/server/v3/lease/leasepb"
|
|
"go.etcd.io/etcd/server/v3/storage/backend"
|
|
"go.etcd.io/etcd/server/v3/storage/schema"
|
|
)
|
|
|
|
type Lease struct {
|
|
ID LeaseID
|
|
ttl int64 // time to live of the lease in seconds
|
|
remainingTTL int64 // remaining time to live in seconds, if zero valued it is considered unset and the full ttl should be used
|
|
// expiryMu protects concurrent accesses to expiry
|
|
expiryMu sync.RWMutex
|
|
// expiry is time when lease should expire. no expiration when expiry.IsZero() is true
|
|
expiry time.Time
|
|
|
|
// mu protects concurrent accesses to itemSet
|
|
mu sync.RWMutex
|
|
itemSet map[LeaseItem]struct{}
|
|
revokec chan struct{}
|
|
}
|
|
|
|
func (l *Lease) expired() bool {
|
|
return l.Remaining() <= 0
|
|
}
|
|
|
|
func (l *Lease) persistTo(b backend.Backend) {
|
|
lpb := leasepb.Lease{ID: int64(l.ID), TTL: l.ttl, RemainingTTL: l.remainingTTL}
|
|
tx := b.BatchTx()
|
|
tx.LockInsideApply()
|
|
defer tx.Unlock()
|
|
schema.MustUnsafePutLease(tx, &lpb)
|
|
}
|
|
|
|
// TTL returns the TTL of the Lease.
|
|
func (l *Lease) TTL() int64 {
|
|
return l.ttl
|
|
}
|
|
|
|
// RemainingTTL returns the last checkpointed remaining TTL of the lease.
|
|
func (l *Lease) getRemainingTTL() int64 {
|
|
if l.remainingTTL > 0 {
|
|
return l.remainingTTL
|
|
}
|
|
return l.ttl
|
|
}
|
|
|
|
// refresh refreshes the expiry of the lease.
|
|
func (l *Lease) refresh(extend time.Duration) {
|
|
newExpiry := time.Now().Add(extend + time.Duration(l.getRemainingTTL())*time.Second)
|
|
l.expiryMu.Lock()
|
|
defer l.expiryMu.Unlock()
|
|
l.expiry = newExpiry
|
|
}
|
|
|
|
// forever sets the expiry of lease to be forever.
|
|
func (l *Lease) forever() {
|
|
l.expiryMu.Lock()
|
|
defer l.expiryMu.Unlock()
|
|
l.expiry = forever
|
|
}
|
|
|
|
// Keys returns all the keys attached to the lease.
|
|
func (l *Lease) Keys() []string {
|
|
l.mu.RLock()
|
|
keys := make([]string, 0, len(l.itemSet))
|
|
for k := range l.itemSet {
|
|
keys = append(keys, k.Key)
|
|
}
|
|
l.mu.RUnlock()
|
|
return keys
|
|
}
|
|
|
|
// Remaining returns the remaining time of the lease.
|
|
func (l *Lease) Remaining() time.Duration {
|
|
l.expiryMu.RLock()
|
|
defer l.expiryMu.RUnlock()
|
|
if l.expiry.IsZero() {
|
|
return time.Duration(math.MaxInt64)
|
|
}
|
|
return time.Until(l.expiry)
|
|
}
|
|
|
|
type LeaseItem struct {
|
|
Key string
|
|
}
|
|
|
|
// leasesByExpiry implements the sort.Interface.
|
|
type leasesByExpiry []*Lease
|
|
|
|
func (le leasesByExpiry) Len() int { return len(le) }
|
|
func (le leasesByExpiry) Less(i, j int) bool { return le[i].Remaining() < le[j].Remaining() }
|
|
func (le leasesByExpiry) Swap(i, j int) { le[i], le[j] = le[j], le[i] }
|