Skip to main content

A lightweight distributed lock server using a simple line-based TCP protocol with FIFO ordering, automatic lease expiry, and background renewal.

This project has been archived.

The maintainers of this project have marked this project as archived. No new releases are expected.

Project description

dflockd

A lightweight distributed lock server using a simple line-based TCP protocol with FIFO ordering, automatic lease expiry, and background renewal.

Read the docs here

Quick start

# Install
uv sync

# Run the server
uv run dflockd

The server listens on 0.0.0.0:6388 by default.

Server configuration

All tuning is via environment variables:

Variable Default Description
DFLOCKD_HOST 0.0.0.0 Bind address
DFLOCKD_PORT 6388 Bind port
DFLOCKD_DEFAULT_LEASE_TTL_S 33 Default lock lease duration (seconds)
DFLOCKD_LEASE_SWEEP_INTERVAL_S 1 How often to check for expired leases
DFLOCKD_GC_LOOP_SLEEP 5 How often to prune idle lock state
DFLOCKD_GC_MAX_UNUSED_TIME 60 Seconds before idle lock state is pruned
DFLOCKD_MAX_LOCKS 1024 Maximum number of unique lock keys
DFLOCKD_READ_TIMEOUT_S 23 Client read timeout (seconds)
DFLOCKD_AUTO_RELEASE_ON_DISCONNECT 1 Release locks when a client disconnects (1, yes, true to enable)

CLI arguments

Settings can also be passed as command-line flags. Environment variables take precedence over CLI arguments.

uv run dflockd --port 7000 --max-locks 512
Flag Default Env var override
--host 0.0.0.0 DFLOCKD_HOST
--port 6388 DFLOCKD_PORT
--default-lease-ttl 33 DFLOCKD_DEFAULT_LEASE_TTL_S
--lease-sweep-interval 1 DFLOCKD_LEASE_SWEEP_INTERVAL_S
--gc-interval 5 DFLOCKD_GC_LOOP_SLEEP
--gc-max-idle 60 DFLOCKD_GC_MAX_UNUSED_TIME
--max-locks 1024 DFLOCKD_MAX_LOCKS
--read-timeout 23 DFLOCKD_READ_TIMEOUT_S
--auto-release-on-disconnect / --no-auto-release-on-disconnect true DFLOCKD_AUTO_RELEASE_ON_DISCONNECT

Protocol

The wire protocol is line-based UTF-8 over TCP. Each request is exactly 3 lines: command\nkey\narg\n.

Commands

Lock (acquire)

l
<key>
<timeout_s> [<lease_ttl_s>]

Response: ok <token> <lease_ttl>\n or timeout\n

Renew

n
<key>
<token> [<lease_ttl_s>]

Response: ok <seconds_remaining>\n or error\n

Release

r
<key>
<token>

Response: ok\n or error\n

Behavior

  • Locks are granted in strict FIFO order per key.
  • Leases expire automatically if not renewed. On expiry, the lock passes to the next waiter.
  • Connections that disconnect have their held locks released automatically.

Client usage

Async client

import asyncio
from dflockd.client import DistributedLock

async def main():
    async with DistributedLock("my-key", acquire_timeout_s=10) as lock:
        print(lock.token, lock.lease)
        # critical section — lease auto-renews in background

asyncio.run(main())

Sync client

from dflockd.sync_client import DistributedLock

with DistributedLock("my-key", acquire_timeout_s=10) as lock:
    print(lock.token, lock.lease)
    # critical section — lease auto-renews in background thread

Manual acquire/release

Both clients support explicit acquire() / release() outside of a context manager:

from dflockd.sync_client import DistributedLock

lock = DistributedLock("my-key")
if lock.acquire():
    try:
        pass  # critical section
    finally:
        lock.release()

Parameters

Parameter Default Description
key (required) Lock name
acquire_timeout_s 10 Seconds to wait for lock acquisition
lease_ttl_s None (server default) Lease duration in seconds
servers [("127.0.0.1", 6388)] List of (host, port) tuples
sharding_strategy stable_hash_shard Callable[[str, int], int] — maps (key, num_servers) to server index
renew_ratio 0.5 Renew at lease * ratio seconds

Multi-server sharding

When running multiple dflockd instances, the client can distribute keys across servers using consistent hashing. Each key always routes to the same server.

from dflockd.sync_client import DistributedLock

servers = [("server1", 6388), ("server2", 6388), ("server3", 6388)]

with DistributedLock("my-key", servers=servers) as lock:
    print(lock.token, lock.lease)

The default strategy uses zlib.crc32 for stable, deterministic hashing. You can provide a custom strategy:

from dflockd.sync_client import DistributedLock

def my_strategy(key: str, num_servers: int) -> int:
    """Route all keys to the first server."""
    return 0

with DistributedLock("my-key", servers=servers, sharding_strategy=my_strategy) as lock:
    pass

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dflockd-0.4.1.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dflockd-0.4.1-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file dflockd-0.4.1.tar.gz.

File metadata

  • Download URL: dflockd-0.4.1.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dflockd-0.4.1.tar.gz
Algorithm Hash digest
SHA256 b3763b4225d85cb3a277ff0cd21de613608baf704b1154ba4b87b701dcd2c55c
MD5 83d30be9c980bdfd6b682d19809b8a3b
BLAKE2b-256 d7c0f1e74751fc7917d44a4418f689327940ac8885e13ce47846b5f911166e3c

See more details on using hashes here.

File details

Details for the file dflockd-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: dflockd-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dflockd-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a30a1df4d13594fd7c55972a5f378d45a368b753f536c14d9f832cd831a9bc17
MD5 162c8ef84c4b0054eba48e0993178b84
BLAKE2b-256 e41bd4962ca8715a6e568a143a071f6f536433160ef0917eca37fcd2079d1e68

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page