gcslock

package module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: May 9, 2023 License: Apache-2.0 Imports: 10 Imported by: 1

README

GoDoc

go-gcslock

GCS Lock creates a forward-looking lock using Google Cloud Storage. The lock is forward-looking because it is not actually "held" like a mutex. This is useful in situations where you want something to occur at most once over a duration, but multiple independent processes could trigger the event.

"Identity" is tied to the object itself; different locks should use different object names.

Usage

lock, err := gcslock.New(ctx, "my-bucket", "my-object")
if err != nil {
  panic(err) // TODO: handle error
}
defer lock.Close(ctx)

// Acquire the lock for 30 minutes. Upon successful return from this method,
// the lock is held.
if err := lock.Acquire(ctx, 30*time.Minute); err != nil {
  var lockErr *ErrLockHeld
  if errors.As(err, &lockErr) {
    // Lock is already held
    log.Printf("lock is held until %s", lockErr.NotBefore())
  }

  panic(err) // TODO: handle error
}

Documentation

Overview

Package gcslock acquires a forward-looking lock leveraging a file in a Google Cloud Storage bucket. Unlike a mutex, the lock is TTL-based instead of "held" like a traditional mutex.

Compared to other mutexes, this is intended to be a long-lived lock. The minimum granularity is "seconds" and most consumers will acquire a lock for "minutes" or "hours". Because of clock skew and network latency, granularity below 1s is not a supported use case.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Lock added in v0.1.2

type Lock struct {
	// contains filtered or unexported fields
}

Lock represents a remote forward-looking lock in Google Cloud Storage.

func New

func New(ctx context.Context, bucket, object string, opts ...option.ClientOption) (*Lock, error)

New creates a new distributed locking handler on the specific object in Google Cloud. It does create the lock until Acquire is called.

func (*Lock) Acquire added in v0.1.2

func (l *Lock) Acquire(ctx context.Context, ttl time.Duration) error

Acquire attempts to acquire the lock. It returns [ErrLockHeld] if the lock is already held. Callers can cast the error type to get more specific information like the TTL expiration time:

if err := lock.Acquire(ctx, 5*time.Minute); err != nil {
  var lockErr *ErrLockHeld
  if errors.As(err, &lockErr) {
    log.Printf("lock is held until %s", lockErr.NotBefore())
  }
}

It automatically retries transient upstream API errors, but returns immediately for errors that are irrecoverable.

func (*Lock) Close added in v0.1.2

func (l *Lock) Close(_ context.Context) error

Close terminates the client connection. It does not delete the lock.

type LockHeldError

type LockHeldError struct {
	// contains filtered or unexported fields
}

LockHeldError is a specific error returned when a lock is alread held.

func NewLockHeldError added in v0.1.3

func NewLockHeldError(nbf int64) *LockHeldError

NewLockHeldError creates an instance of a LockHeldError.

func (*LockHeldError) Error

func (e *LockHeldError) Error() string

Error implements the error interface.

func (*LockHeldError) Is

func (e *LockHeldError) Is(err error) bool

Is implements the error comparison interface.

func (*LockHeldError) NotBefore

func (e *LockHeldError) NotBefore() time.Time

NotBefore returns the UTC Unix timestamp of when the lock expires.

type Lockable added in v0.1.2

type Lockable interface {
	Acquire(ctx context.Context, ttl time.Duration) error
	Close(ctx context.Context) error
}

Lockable is the interface that defines how to manage a lock with Google Cloud Storage.

Jump to

Keyboard shortcuts

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