Skip to content

File-Based Semaphore ​

Cross-platform file-based semaphore for process coordination. Lock resources reliably across processes with zero dependencies.

Overview ​

File-Based Semaphore provides cross-platform process coordination using lock files. It handles stale lock detection, supports both blocking and non-blocking acquisition, and works across different programming languages. Built in Rust for performance and reliability.

Status: Production Ready (v0.1.0)

Language: Rust

Repository: tuulbelt/file-based-semaphore

Features ​

Atomic Locking ​

Acquire locks atomically using O_CREAT | O_EXCL. No race conditions in lock acquisition.

Stale Detection ​

Detect and recover from stale locks with configurable timeouts. Handle crashed processes gracefully.

RAII Guards ​

Use Rust's ownership system for automatic lock release. Guards ensure locks are released even on panic.

Cross-Platform ​

Works on Linux, macOS, and Windows. Uses portable file operations only.

CLI & Library ​

Use as a command-line tool for shell scripts or integrate as a Rust library in your applications.

Zero Runtime Dependencies ​

Uses only Rust standard library. No external crates required at runtime.

Quick Start ​

bash
# Clone the repository
git clone https://github.com/tuulbelt/file-based-semaphore.git
cd file-based-semaphore

# Build
cargo build --release

# CLI: Try to acquire a lock
./target/release/sema try /tmp/my.lock

# CLI: Check status
./target/release/sema status /tmp/my.lock

# CLI: Release
./target/release/sema release /tmp/my.lock
rust
// Library usage
use file_based_semaphore::{Semaphore, SemaphoreConfig};
use std::time::Duration;

let config = SemaphoreConfig {
    stale_timeout: Some(Duration::from_secs(60)),
    ..Default::default()
};

let sem = Semaphore::new("/tmp/my.lock", config)?;

{
    let _guard = sem.try_acquire()?;
    // Critical section - only one process here
    do_exclusive_work();
} // Lock auto-released

Use Cases ​

  • Build Coordination: Prevent concurrent builds from conflicting
  • Deployment Scripts: Ensure only one deployment runs at a time
  • Test Isolation: Coordinate access to shared test resources
  • Service Health Checks: Single instance for health monitoring
  • Batch Job Coordination: Prevent duplicate batch job runs

Why File-Based Semaphore? ​

Traditional locking approaches have limitations:

  1. Database Locks: Require running database server
  2. Advisory Locks (flock): Platform-specific behavior, don't survive crashes well
  3. In-Memory Locks: Don't work across processes
  4. Redis/ZooKeeper: Require external services

File-based semaphores solve these by using simple lock files that:

  • Work across any language that can create files
  • Survive process crashes with stale detection
  • Need no running daemons or services
  • Use atomic filesystem operations

Cross-Language Compatibility ​

TypeScript Implementation Available

A TypeScript implementation is available: File-Based Semaphore (TS) Both implementations use the same lock file format and can coordinate across languages.

Lock files use a simple text format compatible with any language:

pid=12345
timestamp=1735420800
tag=optional-description

Mixed-language coordination example:

bash
# Rust acquires the lock
sema try /tmp/shared.lock --tag "rust-service"

# TypeScript checks status (reads the same lock file)
semats status /tmp/shared.lock
# Output: Locked by PID 12345 (rust-service)

# TypeScript waits for lock
semats acquire /tmp/shared.lock --timeout 5000

This enables:

  • Rust backend services coordinating with Node.js workers
  • Shell scripts checking locks created by any language
  • Gradual migration between language implementations

Dogfooding ​

This tool demonstrates composability by being VALIDATED BY other Tuulbelt tools:

Test Flakiness Detector - Validate concurrent safety:

bash
./scripts/dogfood-flaky.sh 10
# ✅ NO FLAKINESS DETECTED
# 85 tests × 10 runs = 850 executions

Output Diffing Utility - Prove deterministic outputs:

bash
./scripts/dogfood-diff.sh
# Test outputs should be identical

Cross-language composition: Rust tools validated by TypeScript tools via CLI.

See DOGFOODING_STRATEGY.md in the repository for details.

Demo ​

File-Based Semaphore Demo

▶ View interactive recording on asciinema.org

Try it Locally ​

bash
# Clone and build
git clone https://github.com/tuulbelt/file-based-semaphore.git
cd file-based-semaphore
cargo build --release

# Run examples
cargo run --example basic
cargo run --example concurrent
cargo run --example stale_recovery

# Run full demo script
./scripts/demo.sh
Try it online:Open in StackBlitz

Demo recordings are automatically generated via GitHub Actions.

Next Steps ​

License ​

MIT License - see repository for details.

Released under the MIT License.