Cron Job Bundle

This bundle provides a central way to run cron jobs in your Symfony application.

Installation

First install the bundle

composer require becklyn/cron-job

(You need to optionally enable the bundle if you are not using Flex).

Also install the cronjob in your system:

* * * * * /path/to/your/project/vendor/bin/cron

Usage

Registering a Cron Job

Your service needs to implement the CronJobInterface:

use Becklyn\CronJobBundle\Console\BufferedSymfonyStyle;
use Becklyn\CronJobBundle\Cron\CronJobInterface;
use Becklyn\CronJobBundle\Data\CronStatus;


class MyCronJob implements CronJobInterface
{
    public function getCronTab () : string
    {
        // returns the cron date text
        return "*/5 * * * *";
    }

    public function getName () : string
    {
        // a clear text name for your task
        return "My Job";
    }

    public function execute (BufferedSymfonyStyle $io) : CronStatus
    {
        // do the actual task
    }
}

Your task needs a name, the time it will be run and the actual task it should perform.

Passing the CLI output to the cron status entry

New in version 2.0: The new BufferedSymfonyStyle was added.

You can pass the complete (except for sections) CLI output to the CronStatus, by fetching the buffer of the $io object:

public function execute (BufferedSymfonyStyle $io) : CronStatus
{
    // ...

    return new CronStatus(true, $io->getBufferedOutput());
}

Debug Tools via the CLI

Status of All Tasks

bin/console cron:log

This will display all the registered cron jobs, whether they have a valid cron tab, when the last run was and when the next run will be.

Log of a Single Task

bin/console cron:log --single

With this command you can take a look at the last 10 runs of a single task.

You can also preselect a single task, for that just use the key (it’s FQCN) as value for the --single attribute:

bin/console cron:log --single='App\Cron\ExampleCronJob'

You need to use single quotes or escape the backslashes.

Scheduling

The main entry point of the cron job is supposed to be called every minute (see the setup from above).

If a task takes longer than 1 minute (so it would overlap with the next run), the next run is aborted. The component is designed in a way, so that if a task can no be run at the specified time, it will be run at the next possible moment.

So for example: you have a task that should run every day at 00:00. Your system’s cron job failed however, so that this bundle was never called from 23:00 until 9:17. As the task hasn’t run the last time it was supposed to run (at 00:00) it will be scheduled immediately the next time the cron job bundle is run. That also means, that if a task has never run before, it will be run immediately.

This implementation is a best effort to try to make up for missed tasks. Because of these overly long tasks, it also implies however:

  • It isn’t assured that a task is run at the exact time it was scheduled for.
  • A task that should run every minute might not be able to run every minute (if a cron was dropped due to overly long tasks before).

If there is no task that takes longer than 1 minute (and if the system’s cron is set up properly) ever task is executed at the specified time.