vmware-go-kcl-v2/src/leases/impl/lease.go
Tao Jiang a323d2fd51 KCL: Implement Worker
This is the core part of KCL by implementing worker.
It has exactly the same interface as Amazon's KCL. Internally,
it uses code from GoKini in order to get the library
functionaly quickly.

This is a working version. The test code worker_test.go
shows how to use this library.

Dynamic resharding feature is out of the scope of M4.

Test:

1. A Kinesis stream named "kcl-test" has been created under photon-infra
account.
2. Download your AWS Credential from IAM user page.
3. Modify the worker_test.go to fill in your aws credential.
4. hmake test

Jira CNA-637

Change-Id: I886d255bab9adaf7a13bca11bfda51bedaacaaed
2021-12-20 21:13:20 -06:00

116 lines
3.8 KiB
Go

package impl
import (
cc "clientlibrary/common"
"time"
)
const (
// We will consider leases to be expired if they are more than 90 days.
MAX_ABS_AGE_NANOS = int64(90 * 24 * time.Hour)
)
// Lease structure contains data pertaining to a Lease. Distributed systems may use leases to partition work across a
// fleet of workers. Each unit of work (identified by a leaseKey) has a corresponding Lease. Every worker will contend
// for all leases - only one worker will successfully take each one. The worker should hold the lease until it is ready to stop
// processing the corresponding unit of work, or until it fails. When the worker stops holding the lease, another worker will
// take and hold the lease.
type Lease struct {
// shard-id
leaseKey string
// worker#
leaseOwner string
// ccounter incremented periodically
leaseCounter int64
// This field is used to prevent updates to leases that we have lost and re-acquired. It is deliberately not
// persisted in DynamoDB and excluded from hashCode and equals.
concurrencyToken string
// This field is used by LeaseRenewer and LeaseTaker to track the last time a lease counter was incremented. It is
// deliberately not persisted in DynamoDB and excluded from hashCode and equals.
lastCounterIncrementNanos int64
}
// CloneLease to clone a lease object
func CopyLease(lease *Lease) *Lease {
return &Lease{
leaseKey: lease.leaseKey,
leaseOwner: lease.leaseOwner,
leaseCounter: lease.leaseCounter,
concurrencyToken: lease.concurrencyToken,
lastCounterIncrementNanos: lease.lastCounterIncrementNanos,
}
}
// GetLeaseKey retrieves leaseKey - identifies the unit of work associated with this lease.
func (l *Lease) GetLeaseKey() string {
return l.leaseKey
}
// GetLeaseOwner gets current owner of the lease, may be "".
func (l *Lease) GetLeaseOwner() string {
return l.leaseOwner
}
// GetLeaseCounter retrieves leaseCounter which is incremented periodically by the holder of the lease. Used for optimistic locking.
func (l *Lease) GetLeaseCounter() int64 {
return l.leaseCounter
}
// GetConcurrencyToken returns concurrency token
func (l *Lease) GetConcurrencyToken() string {
return l.concurrencyToken
}
// GetLastCounterIncrementNanos returns concurrency token
func (l *Lease) GetLastCounterIncrementNanos() int64 {
return l.lastCounterIncrementNanos
}
// SetLeaseKey sets leaseKey - LeaseKey is immutable once set.
func (l *Lease) SetLeaseKey(leaseKey string) error {
if len(l.leaseKey) > 0 {
return cc.IllegalArgumentError.MakeErr().WithDetail("LeaseKey is immutable once set")
}
l.leaseKey = leaseKey
return nil
}
// SetLeaseOwner set current owner of the lease, may be "".
func (l *Lease) SetLeaseOwner(leaseOwner string) {
l.leaseOwner = leaseOwner
}
// SetLeaseCounter sets leaseCounter which is incremented periodically by the holder of the lease. Used for optimistic locking.
func (l *Lease) SetLeaseCounter(leaseCounter int64) {
l.leaseCounter = leaseCounter
}
// SetConcurrencyToken
func (l *Lease) SetConcurrencyToken(concurrencyToken string) {
l.concurrencyToken = concurrencyToken
}
// SetLastCounterIncrementNanos returns concurrency token
func (l *Lease) SetLastCounterIncrementNanos(lastCounterIncrementNanos int64) {
l.lastCounterIncrementNanos = lastCounterIncrementNanos
}
// IsExpired to check whether lease expired using
// @param leaseDurationNanos duration of lease in nanoseconds
// @param asOfNanos time in nanoseconds to check expiration as-of
// @return true if lease is expired as-of given time, false otherwise
func (l *Lease) IsExpired(leaseDurationNanos, asOfNanos int64) bool {
if l.lastCounterIncrementNanos == 0 {
return true
}
age := asOfNanos - l.lastCounterIncrementNanos
if age > MAX_ABS_AGE_NANOS {
return true
} else {
return age > leaseDurationNanos
}
}