Simple Task Scheduler With PHP

During a more or less large project, a situation may arise when the number of scheduled tasks (cron jobs) becomes so large that their support becomes a DevOps nightmare. To solve this problem, I came up with the idea of creating a PHP scheduler implementation, thereby making it a part of the project, allowing the tasks themselves to be part of its configuration. In this case, the necessary and sufficient number of cron jobs will be equal to one.

Some time ago, I was able to develop a module for event planning. It was just a simplified version of Google/Apple Calendar for users of the application. For storing the dates and rules regarding the repetition of events, it was decided to use the iCalendar format (RFC 5545), which allows one line to describe a schedule for repeating an event, while taking into account the days of the week, months, the number of repetitions, and much more. A few examples:

FREQ = WEEKLY; BYDAY = SU, WE – Weekly on Saturday and Wednesday

FREQ = MONTHLY; COUNT = 5 – Every month, five times

FREQ = YEARLY; INTERVAL = 2; BYMONTH = 1; BYDAY = SU – Every second year on every Saturday of January

As you can see, this standard allows us to describe the rules for repeating the event in a much more flexible way than cron.

To work with the iCalendar format, I was lucky enough to find a wonderful library (don’t fret its stars).

Having a tool for working with RRULE (Recurrence Rule), the application becomes much simpler. Write several classes that allow you to schedule and run tasks (which are any manifestation of the PHP callable type).

Installing the Library:

composer require hutnikau / job-scheduler

Scheduling and Launching Tasks:

The class representing the task is: SchedulerJobJob

To create its instance, you need a rule for its repetition (RRULE) and an instance of type callable:

$startTime = new DateTime('2017-12-12 20:00:00');
$rule = new SchedulerJobRRule('FREQ=MONTHLY;COUNT=5', $startTime); //run monthly, at 20:00:00 starting from the 12th of December 2017, 5 times
$job = new SchedulerJobJob($rule, function () {
    //do something
});

Alternatively, use SchedulerJob Job:: createFromString () :

$job = SchedulerJobJob::createFromString(
    'FREQ=MONTHLY;COUNT=5', //Recurrence rule 
    '2017-12-28T21:00:00',  //Start date
    function() {},          //Callback
    'Europe/Minsk'          //Timezone. If $timezone is omitted, the current timezone will be used
);

Do not forget about time zones. I strongly advise you to always specify them explicitly (not only when working with this library, but with DateTime as a whole) in order to avoid unpleasant surprises.

Add the task to the schedule:

$scheduler = new SchedulerScheduler()
$scheduler->addJob($job);

You can also transfer an array of tasks to the constructor:

$scheduler = new SchedulerScheduler([
    $job,
    //more jobs here
])

Now, launch the scheduled tasks:

$jobRunner = new SchedulerJobRunnerJobRunner();
$from      = new DateTime('2017-12-12 20:00:00');
$to        = new DateTime('2017-12-12 20:10:00');
$reports   = $jobRunner->run($scheduler, $from, $to, true);

In this example, all tasks scheduled for the specified time period (10 minutes) will be performed.

So you only need one cron job, which runs JobRunner .

  • You can omit the $ from the parameter so that all tasks will be performed, starting from $ up to the current time.

The last parameter determines whether the tasks are completed, the execution time of which falls exactly on the boundary values (‘2017-12-12 20:00:00’ and ‘2017-12-12 20:10:00’ from the example above).

When starting the scheduler with cron, I advise you to save the time of the last run, and the next time you run it, pass it to $ from the parameter by adding one second, because the cron’s accuracy is not perfect, and it is possible to skip any tasks or execute them twice.

$ jobRunner-> run (...) returns an array of results of completed tasks (array of objects of type SchedulerActionReport ).

SchedulerActionReport {
    /* Methods */
    public mixed getReport ( void )
    public Action getAction ( void )
    public string getType ( void )
}

By calling SchedulerActionReport:: getReport () , you can get the result of executing a callable (the value returned by it).

In the event that an exception was thrown during the execution of the task, SchedulerActionReport:: getReport () returns the same exception.

The method SchedulerActionReport:: getAction () will return an instance of the type SchedulerActionActionInterface , which describes the action taken. By using it you can find out the time of the action or get the action itself.

It’s also worth noting that if a scheduled task had to be executed more than once (for example, if the MINUTELY interval was used in RRULE, and the difference between $ from and $ to, transferred in JobRunner 10 minutes), then the action will be performed several times. In other words, they will not be grouped.

The library is really small, but I hope someone will be useful.

PHP Zone稿源:PHP Zone (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » Simple Task Scheduler With PHP

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录