Skip to content

maansaake/locksmith

Repository files navigation

Locksmith

Main branch protection Code scanning License Go Report Card tag

Locksmith provides a simple way to obtain shared locks between applications.

This project provides:

  • server implementation (binary + docker image)
  • a command line utility locksmithctl
  • a sample client
  • client library packages (see /pkg)

Documentation provided inline.

Install

The locksmith server can be installed in two different ways. To get the server container image, run:

docker pull ghcr.io/maansaake/locksmith:latest

You can browse available versions here: https://github.com/maansaake/locksmith/pkgs/container/locksmith

Run go install to instead get the server binary, make sure you have set either GOPATH or GOBIN.

go install github.com/maansaake/locksmith@latest

How to run

The locksmith server

Either...

docker run ghcr.io/maansaake/locksmith:latest

Or...

locksmith

Both the binary and the docker container have configuration options that are consumed via environment variables. All variables are namespaced and prefixed with LOCKSMITH_ to avoid collisions.

Locksmith server environment variables

  • LOCKSMITH_LOG_VERBOSITY: Sets the verbosity level for logging. Higher values produce more verbose output (default: 0)
  • LOCKSMITH_LOG_OUTPUT: Sets the log format. Must be either json or console (default: console)
  • LOCKSMITH_PORT: The port where the locksmith server is reachable (default: 9000)
  • LOCKSMITH_TLS: If set to true, TLS is enabled for the locksmith server (default: false). When enabled, both LOCKSMITH_TLS_CERT_PATH and LOCKSMITH_TLS_KEY_PATH must be provided
  • LOCKSMITH_TLS_CERT_PATH: Absolute path to the server's certificate (default: /etc/cert/locksmith.pem)
  • LOCKSMITH_TLS_KEY_PATH: Absolute path to the server's private key (default: /etc/cert/locksmith.key)
  • LOCKSMITH_TLS_REQUIRE_CLIENT_CERT: When set to true (default: false), client connections will have their certificates validated against the client CA certificate. You must provide LOCKSMITH_TLS_CLIENT_CA_CERT_PATH when this variable is set
  • LOCKSMITH_TLS_CLIENT_CA_CERT_PATH: Absolute path to the client CA certificate (default: /etc/cert/client_ca.cert)
  • LOCKSMITH_OBSERVABILITY: Set to true to enable OpenTelemetry instrumentation (default: false)
  • LOCKSMITH_RUNTIME_METRICS: Set to false to disable Go runtime metrics. Only applicable when LOCKSMITH_OBSERVABILITY is true (default: true)

Advanced configuration options

These options are available to enable optimizations for systems where locksmith is expected to handle very high loads. These parameters are not recommended to be changed at all for most use cases as the defaults are meant to be good enough for 99% of cases. Ensure that any changes to these values are preceded by rigorous load testing in the intended environment.

  • LOCKSMITH_Q_TYPE: Testing utility, there are only two options: single and multi (default: multi). The single option completely removes concurrency, making locksmith inefficient at handling higher throughput since it congests lock access to one go-routine, but making it easier to test in some situations
  • LOCKSMITH_Q_CONCURRENCY: Only applicable for multi type queueing, sets the number of go-routines serving incoming requests (default: 10)
  • LOCKSMITH_Q_CAPACITY: Only applicable for multi type queueing, sets the size of each serving go-routines work queue (default: 100)

locksmithctl

The command line utility must be installed via go install.

go install github.com/maansaake/locksmith/cmd/locksmithctl@latest

User guidance is provided as part of the CLI's UX:

╭──────────────────────────────────────╮
│  🔑 locksmithctl                     │
│  Interactive Locksmith Lock Manager  │
│  Connecting to localhost:9000        │
╰──────────────────────────────────────╯
✓ Connected to localhost:9000

Commands
  acquire [lock]          Acquire a lock (interactive prompt if omitted)
  release [lock]          Release a lock (picker if omitted)
  list                    Show all acquired locks
  reconnect               Reconnect to the server
  help                    Show this help
  exit / quit             Exit locksmithctl

locksmith> acquire locktag
→ Acquire request sent for locktag  (waiting for server acknowledgement…)
✓ Acquired: locktag
locksmith> list
╭──────────────────╮
│ Active Locks (1) │
│    1.  locktag   │
╰──────────────────╯

How to use the locksmith code as a library

Import and use the client in your own Go-code:

package main

import (
  "fmt"

  "github.com/maansaake/locksmith/pkg/client"
)

func main() {
  acquiredFunc := func(lockTag string) {
    fmt.Println("acquired lock tag: " + lockTag)
  }

  locksmithClient := client.New(&client.Opts{
    Host:       "localhost",
    Port:       9000,
    OnAcquired: acquiredFunc,
  })

  if err := locksmithClient.Connect(); err != nil {
    panic("uh oh, client failed to connect :-(")
  }

  if err := locksmithClient.Acquire("some-lock-tag"); err != nil {
    panic("failed to acquire")
  }

  // await call to acquiredFunc
}

Or use the protocol package directly to write your own client. See the ClientMessage and ServerMessage types and the interface functions used for encoding/decoding.

Metrics

Locksmith uses OpenTelemetry for instrumentation. When LOCKSMITH_OBSERVABILITY is set to true, the OTEL SDK is initialized and the autoexport package is used to select the metrics exporter based on standard OTEL environment variables. By default the OTLP exporter is used; set OTEL_METRICS_EXPORTER to change this (e.g. prometheus, console, or none). See the OTEL SDK environment variable specification and the OTLP exporter configuration reference for the full list of supported variables.

Locksmith registers the following OTEL instruments:

Instrument Type Description
locksmith.locks UpDownCounter Number of currently held locks
locksmith.acquires Counter Total successful lock acquires since start
locksmith.releases Counter Total successful lock releases since start
locksmith.rejections Counter Rejections due to client misbehavior; carries a reason attribute (bad_manners, unnecessary_acquire, or unnecessary_release)

When LOCKSMITH_RUNTIME_METRICS is true (the default), the following Go runtime instruments from the OTEL Go runtime semconv are also recorded:

Instrument Unit Description
go.memory.used By Memory used by the Go runtime
go.memory.limit By Go runtime memory limit, if configured
go.memory.allocated By Memory allocated to the heap
go.memory.allocations {allocation} Count of heap allocations
go.memory.gc.goal By Heap size target at end of GC cycle
go.goroutine.count {goroutine} Number of live goroutines
go.processor.limit {thread} OS threads available for user-level Go code
go.config.gogc % Heap size target percentage (GOGC)

Note: the instrument names above are the OTEL API names. The exact metric names seen in your monitoring system depend on the exporter. For example, the Prometheus exporter converts dots to underscores and appends _total to counters (locksmith.acquireslocksmith_acquires_total), while the OTLP exporter preserves the dot notation.

About

Locksmith is a lightning fast mutex server.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors