MadLab / MultiServerScheduling by nickashley

This package extends Laravel's native Command Event class to add functionality that prevents events from overlapping when ran in multi server environments. This is achieved using Laravel Cache
18,561
7
5
Package Data
Maintainer Username: nickashley
Maintainer Contact: nick@madlab.com (Nick Ashley)
Package Create Date: 2016-09-27
Package Last Update: 2017-06-23
Language: PHP
License: MIT
Last Refreshed: 2024-04-18 15:18:56
Package Statistics
Total Downloads: 18,561
Monthly Downloads: 0
Daily Downloads: 0
Total Stars: 7
Total Watchers: 5
Total Forks: 0
Total Open Issues: 0

Multi Server Scheduling

This package extends Laravel's native task scheduling to include the ability to lock events and block them from overlapping when in a multi webserver environment.

It works similarly to Laravel's withoutOverlapping feature, except the lockfile is written to Cache as opposed to the local filesystem, and each server generates a unique key to lock the command.

In order to prevent a condition where a short-running command's lock doesn't last long enough, we are implementing a minimum 10 second break between the completion of the command and its next execution time, so if a command runs every minute but takes between 50 and 59 seconds to complete, the next command will be delayed one more minute. We also automatically expire any locks after 1 hour.

You may also enable logging to Laravel's logfile, so that you can ensure things are working correctly.

Installation

$ composer require madlab/multi-server-scheduling

The new scheduler uses Laravel's cache to track which server is currently executing an event. You must make sure you have configured a cache driver that is distributed and accessible by all servers (like memcache or redis).

Now we want to change the default schedule IoC to use this alternate one. In app\Console\Kernel.php add the following function:


use Illuminate\Contracts\Cache\Repository as Cache;
use madlab\MultiServerScheduling\Schedule as MultiServerSchedule;

/**
 * Define the application's command schedule.
 *
 * @return void
 */
protected function defineConsoleSchedule()
{
	$this->app->instance(
		Schedule::class, $schedule = new MultiServerSchedule(
			$this->app[Cache::class],
			MultiServerSchedule::LOG_LEVEL_ABANDONED
		)
	);

    $this->schedule($schedule);
}

Usage

When composing your schedule, simply add "withoutOverlappingCache()" to the command, i.e.

$schedule->command('inspire')
    ->daily()
    ->withoutOverlappingCache();

This will prevent multiple servers from executing the same event at the same time.

Logging

When intitializing the Scheduler in app\Console\Kernal.php, you may pass in 3 different logging levels:

  • LOG_LEVEL_NONE: logging is disabled
  • LOG_LEVEL_ABANDONED: a log will be written anytime a server tries to execute a task that has already been running for 10+ minutes
  • LOG_LEVEL_VERBOSE: most detailed, will log anytime a lock is attempted, obtained, or released

Support

This was made by Nick Ashley at MadLab, LLC and if you need paid support you can contact us at MadLab.com.