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

Taskschedulerbundle Laravel Package

rewieer/taskschedulerbundle

TaskSchedulerBundle makes it easy to schedule recurring PHP tasks with cron-style expressions. Register tasks as services, run them through a single console command, and manage background jobs cleanly in Symfony applications without extra infrastructure.

View on GitHub
Deep Wiki
Context7

Getting Started

TaskSchedulerBundle is a Symfony bundle that lets you declare scheduled tasks as services (each with a cron expression) and run them from a single long-lived runner command, instead of scattering cron entries across servers.

Caveat before you install: this is a Symfony bundle, not a Laravel package. If you are on Laravel, the same concepts live in Illuminate\Console\Scheduling\Schedule (->cron(), ->withoutOverlapping(), ->runInBackground()), and that is what you should use day-to-day. Read this package when you are maintaining a Symfony service alongside your Laravel apps, or when you want a reference model for the daemon-plus-locks pattern.

Minimal steps:

  1. composer require ancyrweb/task-scheduler-bundle and register the bundle in config/bundles.php (Symfony) — pin the version (0.13.*) since this is still pre-1.0 and minor bumps can carry behaviour changes.
  2. Look first at the README's task-definition example (the scheduled-task interface and/or the scheduling attribute) and at the runner command the bundle exposes. Those two things are 90% of the API surface.
  3. First use case: wrap a single existing service method (a cleanup job, a report generator) as one task with a */5 * * * * expression, then invoke the runner command manually with verbose output and confirm it fires once, logs, and exits cleanly.

Do not start by migrating all your existing cron entries. Get one task running under the runner and observed for a day first.

Implementation Patterns

One task per class, thin and idempotent. Keep the scheduled class a wrapper that resolves dependencies via constructor injection and delegates to a real service. That makes the task runnable by hand in a test or a console command without the scheduler in the loop.

Daemon + loop, not per-task cron. The intended production shape is a single supervisor/systemd-managed process that the bundle keeps alive, evaluating "what is due now" on each tick. This is the same trade-off as Laravel's schedule:work versus a crontab entry calling schedule:run every minute: the daemon is cheaper and gives you in-process locking, but it can silently die — always pair it with a supervisor restart policy and a heartbeat check.

Scheduling metadata in one place. Prefer defining frequencies next to the task (attribute or service tag) but keep environment-specific overrides (disable a noisy task in dev, stagger times in prod) in config rather than hard-coded expressions.

Bridge pattern for Laravel shops. If you need this bundle's semantics in a Laravel codebase, don't try to install it. Reimplement: a queued/daemonised loop that reads a task registry (a container tag or a config array), resolves each task from the container, checks a cache lock (Cache::lock()), and dispatches. The locking and "is it due" logic is the only part worth copying.

Testing. Call the task class directly with mocked collaborators — the scheduling layer adds nothing to the assertion. For the runner itself, test with a frozen clock and a single due task.

Gotchas and Tips

0.13.0 changed time semantics — this is the one to internalise. The current time is now captured before the first task runs and reused for the run. Previously each due-check could read a fresh clock. Consequences:

  • Any task that computes due-ness or "next run" from the current time will now see a timestamp that does not advance during a long run. Two tasks due 10 seconds apart inside one long tick are evaluated against the same instant.
  • Inside a task, do not rely on the scheduler's notion of now for user-facing timestamps or TTLs. Call the clock yourself at the start of the task body if you need real elapsed time.
  • A long-running task can now cause the next tick to be computed against an already-stale baseline, so very long tasks effectively shift the schedule. Keep individual tasks short and hand heavy work to a queue/worker rather than doing it inside the scheduled task.
  • Tests that asserted on relative times across a multi-task run may now pass or fail differently. Re-freeze and re-baseline time-sensitive tests after upgrading.

0.13.0 also tightened code style. This is contributor-facing (fixers/CI) and has no runtime effect — but if you vendor-patch or maintain a fork, expect your local changes to fail their style job, and rebase onto the new formatting rather than merging around it.

Pre-1.0 versioning. Treat every 0.x minor as potentially breaking. Read the changelog even for "style" releases, because 0.13.0 bundled a behavioural change under a second bullet.

Overlap protection is on you. The daemon model means a slow task and the next tick can collide. Always wrap non-reentrant tasks in a lock with an expiry longer than the worst-case runtime, and log lock contention rather than swallowing it — a silently skipped task looks identical to a task that did nothing.

Timezone and DST. Cron expressions are evaluated against whatever timezone the runner process has. Set it explicitly; ambiguous local times around DST transitions can skip or double-fire a task.

Debugging a task that "didn't run": check in this order — is the daemon alive, is the task registered in the container/tag, is the expression valid, is the lock held, and only then look at the task body. Verbose runner output on a manual invocation resolves the first four immediately.

Extension points. The task registry (container tag / attribute loading) and the runner loop are the seams to customise — a custom task loader if you store schedules in a database, or a decorated runner if you need metrics. Keep customisations outside the vendor tree; the API is not stable at 0.x.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels