dsync

package
v0.15.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2024 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package dsync Provides distributed synchronization support of microservices and provide common usage patterns around distributed lock, such as lock-based service leader election.

Index

Constants

View Source
const FxGroup = `dsync`

FxGroup is a group name for uber.fx

Variables

View Source
var (
	ErrLockUnavailable      = newError("lock is held by another session")
	ErrUnlockFailed         = newError("failed to release lock")
	ErrSessionUnavailable   = newError("session is not available")
	ErrSyncManagerStopped   = newError("sync manager stopped")
	ErrFailedInitialization = newError("sync manager failed to start")
)
View Source
var Module = &bootstrap.Module{
	Name:       "distributed",
	Precedence: bootstrap.DistributedLockPrecedence,
	Options: []fx.Option{
		appconfig.FxEmbeddedDefaults(defaultConfigFS),
		fx.Invoke(initialize),
	},
}

Functions

This section is empty.

Types

type Lock

type Lock interface {
	// Key the unique identifier of the lock
	Key() string

	// Lock attempts to acquire the lock and blocks until lock is acquired or context is cancelled/timed out.
	// Invoking Lock after lock is acquired (or re-acquired after some error) returns immediately.
	//
	// A cancellable context.Context can be used to abort the current attempt, but it won't stop the lock to keep
	// trying in the background.
	//
	// It is NOT safe to assume that the lock is guaranteed to be held until Release(). The lock might be lost
	// due to session invalidation, communication errors, operator intervention, etc.
	//
	// Lost() returns a channel that is closed if our lock is lost or an error occurred.
	// By default, dsync implementations prefer liveness over safety and an application must be able to handle
	// the lock being lost.
	//
	// Important: Regardless the result, the lock would keep trying to acquire the lock in the background.
	// So a pairing call of Release() is always required after the lock is no longer needed, even if the context is canceled
	Lock(ctx context.Context) error

	// TryLock differs from Lock in following ways:
	// - TryLock stop blocking when lock is held by other instance/session
	// - TryLock stop blocking when unrecoverable error happens during lock acquisition
	// Note: TryLock may temporarily block when connectivity to external infra service is not available
	//
	// Important: Regardless the result, the lock would keep trying to acquire the lock in the background.
	// So a pairing call of Release() is always required after the lock is no longer needed, even if the context is canceled
	TryLock(ctx context.Context) error

	// Release stops the attempt to acquire the lock and releases the lock if already held
	// Release must be used everytime after Lock or TryLock is called, unless the application is intended
	// to hold the lock indefinitely.
	//
	// Invoking Release multiple time takes no effect.
	//
	// Note: Lost channel would stop signalling after Release, until Lock or TryLock is called again.
	Release() error

	// Lost channel signals long-running goroutine when lock is lost (due to network error, operator intervention,
	// manual Release() call from other goroutine, etc).
	//
	// When Lost channel is signalled, there is no need to re-invoke Lock.Lock or Lock.TryLock for lock re-acquisition
	// unless it's caused by manual Release() call, but all relying-tasks should pause.
	Lost() <-chan struct{}
}

Lock distributed mutex lock backed by external infrastructure service such as consul or redis. Once lock acquisition is started (Lock.Lock or Lock.TryLock), regardless the result, the Lock would keep trying to acquire/re-acquire the lock until Lock.Release is manually invoked, because the lock might be revoked by operator or external infra service.

Long-running goroutine should monitor Lost channel after the lock is acquired. When Lost channel is signalled, there is no need to re-invoke Lock.Lock or Lock.TryLock, since internal loop would try to re-acquire lock. However, any existing tasks relying on this lock should be stopped because there is no guarantee that the lock will be re-acquired

func LeadershipLock

func LeadershipLock() Lock

LeadershipLock returns globally maintained lock for leadership election To check leadership, use Lock.TryLock and check error. Example:

if e := LeadershipLock().TryLock(ctx); e == nil {
	// do what a leader should do
}

This function panic if it's call too soon during startup Note: Lock.Lost() channel should be monitored for long-running goroutine, since leadership could be revoked any time by operators

func LockWithKey

func LockWithKey(key string, opts ...LockOptions) Lock

LockWithKey returns a distributed Lock with given key. If the Lock already exists with same key, the options are ignored and the same Lock is returned.

The returned Lock is goroutines-safe, but locking/releasing same lock from different goroutine may cause complicated scenarios. It's application's responsibility to coordinate such concurrent usage.

This function panic if internal SyncManager is not initialized yet or key is not provided.

type LockOption

type LockOption struct {
	Valuer LockValuer
}

type LockOptions

type LockOptions func(opt *LockOption)

type LockValuer

type LockValuer func() []byte

LockValuer is used to annotate the lock in external infra service. It's treated literally and serves as lock's metadata

func NewJsonLockValuer

func NewJsonLockValuer(v interface{}) LockValuer

NewJsonLockValuer is the default implementation of LockValuer.

type SyncManager

type SyncManager interface {
	// Lock returns a distributed lock with given key. If the Lock already exists with same key,
	// the options are ignored and the same Lock is returned.
	//
	// The returned Lock is goroutines-safe, but locking/releasing same lock from different goroutine may cause
	// complicated scenarios. It's application's responsibility to coordinate such concurrent usage.
	Lock(key string, opts ...LockOptions) (Lock, error)
}

SyncManager manage distributed locks across the application.

type SyncManagerLifecycle

type SyncManagerLifecycle interface {
	Start(ctx context.Context) error
	Stop(ctx context.Context) error
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL