Go Client

A Go LDLM client library from https://github.com/imoore76/ldlm/tree/main/client.

Installation

// your go application
include "github.com/imoore76/ldlm/client"

then

$ go mod tidy

Basic Example

import (
    "context"

    "github.com/imoore76/ldlm/client"
)

c, _ := client.New(context.Background(), client.Config{
    Address: "ldlm-server:3144",
})

lock, err := c.Lock("my-task", nil)

if err != nil {
    panic(err)
}

func() {
    defer lock.Unlock()
    doMyTask()
}()

See also

LDLM Concepts

For a basic understanding of how locks function and the different locking methods available.

LDLM Use Cases

For Python client examples of common use cases.

API Reference

For a complete view of Python client functionality.

Usage

Comprehensive Go module documentation is available at pkg.go.dev.

Create a Client

A client takes a context and a Config object. Cancelling the context aborts a client’s operations.

func New(ctx context.Context, conf Config, opts ...grpc.DialOption) (*Client, error)
Client creation example
import (
    "context"

    "github.com/imoore76/ldlm/client"
)

c, err := client.New(context.Background(), client.Config{
    Address: "localhost:3144",
})

if err != nil {
    panic(err)
}

New() takes an arbitrary number of gRPC dial options that are passed along to grpc.Dial().

Client Config

A Config{} object should be supplied to New().

type Config struct {
    Address     string // host:port address of ldlm server
    NoAutoRenew bool   // Don't automatically renew locks before they expire
    UseTls      bool   // use TLS to connect to the server
    SkipVerify  bool   // don't verify the server's certificate
    CAFile      string // path to file containing a CA certificate
    TlsCert     string // path to file containing a TLS certificate for this client
    TlsKey      string // path to file containing a TLS key for this client
    Password    string // password to send
    MaxRetries  int    // maximum number of retries on network error or server unreachable
}

Lock Object

Lock objects are returned from successful Lock() and TryLock() client methods.

type Lock struct {
    Name   string // The name of the lock
    Key    string // The name of the lock
    Locked bool   // Whether the lock was acquired or not
}
func (l *Lock) Unlock() error

Unlocks the lock.

Lock Options

Lock operations take a *LockOptions object that specifies relevant lock options.

type LockOptions struct {
    WaitTimeoutSeconds int32 // How long to wait for the lock to become available
    LockTimeoutSeconds int32 // How long to hold the lock before needing to renew
    Size               int32 // Size of the lock
}

Note

These options are described in more detail in LDLM Concepts.

Lock()

func (c *Client) Lock(name string, options *LockOptions) (*Lock, error)

Lock() attempts to acquire a lock in LDLM. It will block until the lock is acquired or until WaitTimeoutSeconds has elapsed (if specified). It accepts the following arguments:

Type

Description

string

Name of the lock to acquire

*LockOptions

Options for the lock

It returns a *Lock and an error.

Examples

Simple lock
lock, err = c.Lock("my-task", nil)
if err != nil {
    // handle err
}

func() {
    defer lock.Unlock()
    doWork("my-task")
}()
Wait timeout
lock, err = c.Lock("my-task", &client.LockOptions{WaitTimeoutSeconds: 5})
if err != nil {
    panic(err)
}

if !lock.Locked {
    fmt.Println("Couldn't obtain lock within 5 seconds")
    return
}

func() {
    defer lock.Unlock()
    doWork("my-task")
}()

TryLock()

func (c *Client) TryLock(name string, options *LockOptions) (*Lock, error)

TryLock() attempts to acquire a lock and immediately returns; whether the lock was acquired or not. You must inspect the returned lock’s Locked property to determine if it was acquired.

TryLock() accepts the following arguments.

Type

Description

string

Name of the lock to acquire

*LockOptions

Options for the lock

It returns a *Lock and an error.

Examples

Simple try lock
lock, err = c.TryLock("my-task", nil)
if err != nil {
    // handle err
}
if !lock.Locked {
    // Something else is holding the lock
    return
}

func() {
    defer lock.Unlock()
    doWork("my-task")
}()

Errors

The following errors may be returned from lock operations and correspond to LDLM API errors of the same name.

  • ErrLockDoesNotExist

  • ErrInvalidLockKey

  • ErrLockWaitTimeout

  • ErrLockNotLocked

  • ErrLockDoesNotExistOrInvalidKey

  • ErrInvalidLockSize

  • ErrLockSizeMismatch