Urgent.News

What's breaking now, across thousands of outlets.

Tech

The wait queue is just a channel: building a small distributed lock server in Go

Sooner or later you hit the same small problem: two services, on two machines, want to touch the same thing at the same moment — append to a shared file, update a row nobody is fencing, call an API that tolerates one caller at a time. One of them has to wait. The usual answers feel heavier than the problem. Put a service in front and serialize everything through it — now you are building a queue,…

In the realm of distributed systems, a common hurdle arises when two services operating on separate machines attempt to modify the same resource simultaneously. To resolve this, a lock must be placed on the resource, allowing only one service to access it at a time. However, traditional solutions like queueing services or caching systems often complicate matters unnecessarily.

Enter Locking-Center, a compact and efficient lock server written in Go, designed to provide a simple and reliable locking mechanism with minimal overhead.

At the heart of Locking-Center lies an ingenious approach that leverages Go channels to implement a lock-free locking mechanism. Each key in the system is paired with a buffered channel of capacity 1. When a client wishes to acquire the lock, it sends a value into the corresponding channel. If the channel is empty, the send operation succeeds, and the client holds the lock.

If the channel is already occupied by another client, the send operation blocks, causing the client to wait until the lock is released. Once the lock is released, the next client in the queue is woken up and granted the lock. This elegant design, facilitated by Go's built-in channel mechanism, ensures that locks are acquired and released in a first-in, first-out (FIFO) order, eliminating the need for explicit synchronization or priority mechanisms.

However, one potential issue arises when a goroutine is blocked on a send operation, rendering it inaccessible to the rest of the program. In such cases, the goroutine cannot be cancelled, timed out, or signaled to release the lock. To address this concern, Locking-Center introduces a second structure—a map that associates each request with its corresponding context.

By maintaining this registry of request contexts, the system gains the ability to cancel or timeout requests that have been blocked for an extended period. This approach ensures that clients are promptly released from locks even in situations where they become unresponsive or are disconnected prematurely.

Furthermore, Locking-Center incorporates a log-based persistence mechanism to safeguard against data loss during system restarts or deployments. By default, the lock state resides solely in memory, which poses a risk of losing critical lock information upon process termination. To mitigate this risk, Locking-Center supports the optional use of a write-ahead log file.

When enabled, lock acquisitions and releases are recorded in the log before acknowledging the lock to the client. This ordering guarantee ensures that clients only perceive the lock as acquired once it has been safely persisted to disk, thereby preventing potential conflicts or inconsistencies in distributed environments.

In summary, Locking-Center offers a minimalist yet powerful solution for distributed locking in Go applications. By harnessing the power of Go channels, the system achieves a lightweight, FIFO-based locking mechanism that aligns with the requirements of many distributed systems. The inclusion of a request context map enables graceful cancellation and timeout handling, ensuring that clients are promptly released from locks even in the face of unresponsive or disconnected clients.

Lastly, the optional log-based persistence mechanism provides a reliable means of maintaining lock state across process restarts or deployments, minimizing the risk of data loss and ensuring the integrity of distributed locks.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Badger: An E-Ink Badge I Use For Conferences

I attend conferences regularly, and for years I’ve wanted a badge that makes it easy for people to find me online. In 2019, I attended defcon and built defpi , a goofy raspberry pi powered badge.

  • Sean Boult developed Badgeware Badger for easy conference identification.
  • Badger features WiFi module, battery, USB-C interface, and MicroPython.
  • Simulator allows testing and deployment of Badger code.

How I tested Row Level Security before shipping a SaaS starter kit (so one user can't see another's data)

When you're building a multi-tenant app, there's one bug category that's worse than any other: a user seeing someone else's data. Not a crash, not a broken button — a genuine privacy failure.

  • Tested Row Level Security with Supabase to prevent users from viewing other users' data.
  • Created a policy pattern for owner-scoped tables to filter rows based on authenticated user's ID.
  • Conducted impersonation tests to verify RLS policy effectiveness in both read and write operations.

More from Monday 31 August →