Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Command Lock Bundle Laravel Package

ffreitas-br/command-lock-bundle

A Symfony bundle for locking console commands so scheduled jobs and long-running tasks don’t run concurrently. Prevent duplicate executions and race conditions by applying locks to individual commands with minimal configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — poor, effectively nil for Laravel as-published. This is a Symfony bundle (*Bundle naming, DI extension, Resources/config service wiring), not a Laravel package. Laravel has no bundle registration concept — it expects a ServiceProvider, optional Facade, and publishable config. The only shared substrate is that Laravel's Artisan console is built on symfony/console, so the idea (a lock guard around command execution) is portable, but the artifact is not. Any adoption requires a port, not an install.

Integration feasibility — low without a rewrite. The bundle targets the Symfony 2.2–2.5 era (last release 2014-06-02). At that time symfony/lock did not exist (it shipped in 2.6/3.0), so the lock primitive is almost certainly a custom flock-on-a-file or a cache-backed flag. Two consequences:

  • The lock semantics live in bundle-internal classes wired through Symfony's container — none of that resolves inside Laravel's container.
  • The underlying algorithm is what has value, and it is reimplementable in roughly a day against Laravel's Cache::lock() or the scheduler's withoutOverlapping().

Technical risk — high and asymmetric. Risks concentrate on the runtime, not the concept:

  • PHP compatibility: 2014 code was written for PHP 5.4/5.5. Expect no scalar type hints, no return types, no namespaces for newer interfaces, and possible use of removed functions. Running it on PHP 8.1+ is a coin flip and would need static analysis (phpstan/rector) before anything else.
  • Symfony API drift: Symfony\Component\Console\Command\Command and EventDispatcher signatures changed materially (e.g., Command::execute return type, configure() conventions). A shim layer is unlikely to be cheaper than a rewrite.
  • Zero ecosystem signal: 5 stars, 0 dependents, one release a decade ago. This is an abandoned single-author artifact with no issue tracker health, no CI, and no security response path.
  • Correctness unknown: no visibility into whether locks are TTL'd, whether they detect stale PIDs, or whether they're safe on NFS. A silently-wrong lock is worse than no lock — it creates false confidence in exactly the cron/double-execution scenario you were trying to prevent.

Key questions for the maintainer/vendor (or for the spike):

  1. What is the lock backend — flock, mkdir atomicity, Memcached add, Redis SETNX?
  2. Is there a TTL or stale-lock reaper, or does a SIGKILL leave the command permanently blocked?
  3. Is the lock released in a finally/shutdown handler, or only on graceful exit?
  4. Does it behave correctly across multiple hosts, and on NFS/EFS-mounted volumes?
  5. Is lock acquisition blocking, non-blocking, or blocking-with-timeout — and is that configurable per command?
  6. What PHP and Symfony versions were validated, and is there any test suite?

Integration Approach

Stack fit — the requirement is valid; this package is the wrong vehicle. Concurrent-invocation suppression is a real operational need for scheduled jobs, webhook-triggered Artisan commands, and queue workers. Laravel has shipped first-class answers to this since 5.x/6.x, which means the buy-vs-build calculus points at the framework, not at a 2014 Symfony bundle.

Recommended path (in order of preference):

  1. Native Laravel primitives — no dependency.

    • Scheduler: $schedule->command('foo')->withoutOverlapping(10) for per-task mutual exclusion.
    • Ad-hoc commands: Cache::lock("cmd:foo", 300)->get() with ->block(0) for fail-fast behavior; wrap in try/finally with $lock->release().
    • This gives TTL, distributed correctness (Redis/Memcached/DynamoDB stores), and zero new attack surface.
  2. symfony/lock standalone — if you need richer semantics. Current 6.x/7.x releases are actively maintained, support Redis/Postgres/Doctrine/flock stores, and offer LockFactory::createLock() with configurable TTL and auto-release. Installable via Composer into Laravel with no bundle plumbing. This is the closest legitimate successor to what this package attempted in 2014.

  3. Fork-and-port — only if 1 and 2 demonstrably fail. Extract the lock algorithm, reimplement as a Laravel package with a ServiceProvider, a config/command-lock.php, and a Command decorator or middleware. Budget 3–5 engineer-days plus test coverage; assume the original is a specification, not a codebase.

  4. Install as-is — not recommended under any scenario. Blocked by bundle/container mismatch and PHP version risk.

Migration path and sequencing:

  • Week 1 — Spike (1 day): Inventory every command and scheduled task that currently risks concurrent execution. Classify each as single-host or multi-host. This determines whether flock semantics suffice.
  • Week 1 — PoC (1–2 days): Implement the top three highest-risk commands with Cache::lock() on the production cache store. Include a forced-failure test (kill -9 mid-execution) to confirm TTL releases the lock.
  • Week 2 — Rollout: Apply withoutOverlapping() to the scheduler; add lock guards to any command invoked by HTTP or queue. Instrument with log lines on lock-acquired/lock-skipped.
  • Week 3 — Harden: Add alerting on "lock skipped" frequency so you can distinguish healthy suppression from a stuck lock. Document the TTL chosen per command relative to worst-case runtime.

Compatibility notes: withoutOverlapping() requires the cache store to be shared across all hosts running the scheduler — verify you are not on the array or file driver for the scheduler mutex if you run more than one scheduler node. Cache::lock() requires Laravel 6+ and a store implementing LockProvider (Redis, Memcached, DynamoDB, database).

Operational Impact

Maintenance — the package itself is a liability, not an asset. One release, June 2014, single author, no dependents. There is no realistic path to upstream fixes, and no security disclosure process. Even in a fork scenario you inherit the maintenance burden entirely. By contrast, symfony/lock and Laravel's cache locks receive ongoing security and PHP-version support.

Support — zero. No documentation beyond the README, no test suite evidence, no issue triage. Any incident investigation lands on your team. For a component that gates whether production jobs run at all, this is an unacceptable support posture.

Scaling — the likely weak point. File-based locking (the most probable 2014 implementation) degrades in three ways that matter at scale:

  • Multi-host: flock is host-local. Two app servers both acquire the lock and both run the job. This silently defeats the entire purpose in any horizontally scaled deployment.
  • Shared volumes: flock over NFS/EFS is historically unreliable and filesystem-dependent.
  • Lock contention: a blocking acquisition with no timeout can pile up PHP-FPM workers or scheduler processes.

A Redis-backed lock (Cache::lock) resolves all three and is the reason to prefer the native route.

Failure modes to design against:

Failure Consequence Mitigation
Process killed mid-run (no finally) Lock held until TTL or forever Mandatory TTL; verify store expiry
TTL shorter than job runtime Second instance starts while first still running Size TTL to p99 runtime × 2; log overruns
Lock store unavailable (Redis down) Either all jobs blocked or all run Decide fail-open vs fail-closed per command and document it
Clock skew across hosts TTL expiry miscalculated Use store-side TTL (SETEX), not app-side timestamps
Bundle not registered / silently no-op False confidence, duplicate execution Integration test asserting the second invocation is actually skipped

Ramp-up — low for the recommended path, moderate for a fork. Any Laravel engineer can adopt withoutOverlapping()/Cache::lock() in under a day; the concepts are documented and idiomatic. A fork-and-port requires someone comfortable reading Symfony 2.x container XML/YAML and reconstructing intent from undocumented 2014 code — call it 1–2 days of archaeology before any code is written, with meaningful risk of misreading the original's guarantees.

Bottom line for the roadmap: the capability is worth prioritising — unsuppressed concurrent command execution is a classic source of duplicated charges, double-sent emails, and corrupted batch state. But ffreitas-br/command-lock-bundle should be logged as a rejected candidate: wrong framework, abandoned, unverifiable correctness. Deliver the same outcome via Laravel's native locking, with symfony/lock as the escape hatch if distributed or cross-language requirements emerge.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin