Installation:
composer require zerkalica/semaphore
Add the service provider to config/app.php:
'providers' => [
// ...
Zerkalica\Semaphore\SemaphoreServiceProvider::class,
],
Basic Usage:
use Zerkalica\Semaphore\Facades\Semaphore;
// Acquire a semaphore (blocking)
Semaphore::acquire('my_resource');
// Release the semaphore
Semaphore::release('my_resource');
First Use Case: Limit concurrent database imports to 3:
Semaphore::acquire('import_lock', 3);
// Critical section (e.g., import logic)
Semaphore::release('import_lock');
Resource Guarding:
// In a controller/middleware
Semaphore::acquire('api_rate_limit', 10);
try {
// Process request
} finally {
Semaphore::release('api_rate_limit');
}
Non-Blocking Checks:
if (Semaphore::tryAcquire('exclusive_task', 1)) {
// Execute critical task
Semaphore::release('exclusive_task');
} else {
// Fallback or queue
}
Laravel Events:
// In an event listener
Semaphore::acquire('event_processor');
// Process event
Semaphore::release('event_processor');
Context Managers:
Semaphore::acquire('resource');
try {
// Business logic
} finally {
Semaphore::release('resource');
}
Rate Limiting Middleware:
public function handle($request, Closure $next) {
Semaphore::acquire('api_limit', 100);
$response = $next($request);
Semaphore::release('api_limit');
return $response;
}
Deadlocks:
finally blocks.A → B → A).Resource Leaks:
tryAcquire() for timeouts:
if (!Semaphore::tryAcquire('resource', 1, 5)) { // 5-second timeout
throw new \RuntimeException('Resource unavailable');
}
Cross-Process Safety:
storage/framework/semaphores/).chmod -R 775 storage/framework/semaphores).Check Lock Files:
ls -la storage/framework/semaphores/
Manually delete stale locks if needed (restart app afterward).
Logging:
Enable debug mode in config/semaphore.php:
'debug' => env('SEMAPHORE_DEBUG', false),
Custom Storage:
Override the default storage engine by binding a Zerkalica\Semaphore\Contracts\SemaphoreStorage implementation:
$this->app->bind('semaphore.storage', function() {
return new CustomRedisSemaphoreStorage();
});
Event Hooks:
Listen for semaphore events (e.g., semaphore.acquired, semaphore.released) via Laravel’s event system.
Configuration:
Adjust timeouts in config/semaphore.php:
'timeout' => 30, // Seconds
'retry_interval' => 100, // Milliseconds
How can I help you explore Laravel packages today?