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

Scheduler Queues Laravel Package

liberusoftware/scheduler-queues

Run Laravel scheduled tasks through queues instead of executing them inline. This package integrates the scheduler with your queue system for better reliability, control, and performance.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat liberusoftware/scheduler-queues as a convention layer for making queued jobs safe to retry, safe to overlap-check, and safer to deploy. It is not a replacement for Horizon, Redis, or Laravel’s native queue primitives; use it to standardize how your team applies those primitives.

Minimal adoption path:

  1. Install and pin the package:

    composer require liberusoftware/scheduler-queues
    

    Pin a specific tag or commit in composer.json. With zero stars/dependents, avoid floating constraints in production.

  2. Check service-provider discovery. If the package is not auto-discovered, register its provider in bootstrap/providers.php or config/app.php.

  3. Publish only what you need:

    php artisan vendor:publish --provider="Liberu\\SchedulerQueues\\SchedulerQueuesServiceProvider"
    

    Confirm the actual provider namespace and publish tags from the README or src/.

  4. If the package ships migrations for locks, failures, or monitoring, run them:

    php artisan migrate
    
  5. Look first at:

    • README.md for the intended job contract/trait and config keys
    • config/scheduler-queues.php
    • src/Contracts, src/Concerns, src/Middleware, src/Console
    • tests/ for the package’s expected usage

First use case: pick one high-risk queued job — a webhook handler, invoice charge, export, or notification — and make it idempotent with a stable business key. Then add a unique/overlap lock and verify behavior with two workers locally. Once that works, standardize the pattern across other jobs and schedules.

Given the low adoption signals, keep a fallback path using Laravel’s native ShouldBeUnique, WithoutOverlapping, onOneServer, and middleware. The package should reduce convention drift, not become an unexamined critical dependency.

Implementation Patterns

Use the package as a policy layer around jobs that must not run twice for the same logical operation.

Idempotent job policy

  • Mark only jobs that genuinely need uniqueness. A blanket policy on every job creates lock contention and confusing skipped executions.
  • Derive the unique/idempotency key from business data, not uniqid() or the job instance. Good keys: invoice:{id}:charge, webhook:{provider}:{event_id}, export:{tenant_id}:{report_id}:{date}.
  • Pass the key into the job explicitly. Do not rely on reconstructing it from mutable model state inside the handler.
  • Make the handler idempotent even if the lock is bypassed: check current state, use database constraints, or record processed event IDs.

Dispatch workflow

  • Dispatch after commit for jobs that depend on freshly written rows:
    DB::afterCommit(fn () => MyJob::dispatch($id, $idempotencyKey));
    
    Otherwise a worker can run before the transaction is visible, causing retries or false uniqueness conflicts.
  • Keep the unique window long enough to cover dispatch delays, retries, and deploys. If the package exposes uniqueFor, set it from the job’s realistic maximum lifespan.
  • Prefer a shared cache store — Redis or database — for locks. File cache is fine for a single-machine demo and wrong for multi-worker production.

Scheduler workflow

  • Keep schedule definitions close to the module that owns the work.
  • Use onOneServer() where the schedule must not run on every node, and withoutOverlapping() where the task must not overlap itself.
  • Be explicit about timezone. Laravel schedule timezone behavior is easy to misread in multi-region deployments.
  • Run php artisan schedule:list after changes and test with schedule:run in staging.

Retries and failures

  • Configure retries per job: $tries, $backoff, $maxExceptions, and retryUntil() where appropriate.
  • Do not rely on retries alone for correctness. A retry after partial side effects must be safe.
  • Route failures to your normal alerting path. If the package provides monitoring events or reporters, connect them to Slack, Sentry, or your existing queue dashboard.
  • Prune monitoring/failure records on a schedule if the package persists them.

Graceful deployment

  • Run php artisan queue:restart after deploying worker code.
  • Configure Supervisor with stopwaitsecs greater than the longest reasonable job duration.
  • During risky migrations, pause schedulers or deploy in expand/contract phases so old workers and new code can coexist.
  • Treat in-flight jobs as part of the deployment: they may retry against new code after restart.

Testing

  • Use Queue::fake() to assert dispatch and uniqueness-key construction.
  • Add an integration test with a real cache store that dispatches the same logical job twice and asserts only one execution.
  • Simulate lock contention and retry scenarios, not just the happy path.

Gotchas and Tips

  • Package contract required. The uniqueness/overlap behavior likely only applies to jobs that opt in via the package’s interface, trait, or middleware. If the job is not marked, expect no protection.
  • Do not double-lock. If you use Laravel’s ShouldBeUnique or WithoutOverlapping, confirm whether the package adds another lock. Two lock systems with different TTLs produce surprising skipped jobs and stuck locks.
  • Cache store is the usual failure point. Locks on the file cache break across servers and sometimes across workers. Use Redis or database-backed cache and verify the same store is used by web and queue processes.
  • Lock TTL must exceed runtime. A job that runs longer than the lock TTL can overlap with itself. Set TTLs from observed runtime, not guesses.
  • Uniqueness can block legitimate re-dispatch. A key based only on a model ID will prevent a second legitimate action after the first completes. Include action/version/date in the key.
  • afterCommit matters. Dispatching inside a transaction can create unique-lock ghosts or jobs that retry before the data exists.
  • Deploy restarts trigger retries. Idempotency must survive a worker being killed mid-job. Test this by restarting workers while a job is running in staging.
  • Schedule locks are not business locks. withoutOverlapping() protects the schedule from overlapping runs; it does not make the underlying job idempotent.
  • Monitor lock contention and skipped runs. A queue that looks empty may be silently skipping work because of stale locks or uniqueness keys. Log both dispatch and skip decisions.
  • Watch package maturity. Zero dependents and immature release metadata mean you should pin versions, read the source, and keep the integration behind a small adapter or base job class so you can replace it later.
  • Extension points to inspect: custom job policy/contract, middleware, schedule definitions, failure/monitoring reporter, and config for lock store/TTL/retry defaults. Prefer extending these over copying package internals into your app.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager