Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.6] Multi server scheduling cron support #22216

Merged
merged 6 commits into from
Nov 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Illuminate\Contracts\Cache\Repository as Cache;

class CacheMutex implements Mutex
class CacheEventMutex implements EventMutex
{
/**
* The cache repository implementation.
Expand All @@ -25,7 +25,7 @@ public function __construct(Cache $cache)
}

/**
* Attempt to obtain a mutex for the given event.
* Attempt to obtain an event mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return bool
Expand All @@ -38,7 +38,7 @@ public function create(Event $event)
}

/**
* Determine if a mutex exists for the given event.
* Determine if an event mutex exists for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return bool
Expand All @@ -49,7 +49,7 @@ public function exists(Event $event)
}

/**
* Clear the mutex for the given event.
* Clear the event mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return void
Expand Down
53 changes: 53 additions & 0 deletions src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Illuminate\Console\Scheduling;

use Illuminate\Support\Carbon;
use Illuminate\Contracts\Cache\Repository as Cache;

class CacheSchedulingMutex implements SchedulingMutex
{
/**
* The cache repository implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
public $cache;

/**
* Create a new overlapping strategy.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}

/**
* Attempt to obtain a scheduling mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @param \Illuminate\Support\Carbon $time
* @return bool
*/
public function create(Event $event, Carbon $time)
{
return $this->cache->add(
$event->mutexName().$time->format('Hi'), true, 60
);
}

/**
* Determine if a scheduling mutex exists for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @param \Illuminate\Support\Carbon $time
* @return bool
*/
public function exists(Event $event, Carbon $time)
{
return $this->cache->has($event->mutexName().$time->format('Hi'));
}
}
26 changes: 24 additions & 2 deletions src/Illuminate/Console/Scheduling/CallbackEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ class CallbackEvent extends Event
/**
* Create a new event instance.
*
* @param \Illuminate\Console\Scheduling\Mutex $mutex
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
* @param string $callback
* @param array $parameters
* @return void
*
* @throws \InvalidArgumentException
*/
public function __construct(Mutex $mutex, $callback, array $parameters = [])
public function __construct(EventMutex $mutex, $callback, array $parameters = [])
{
if (! is_string($callback) && ! is_callable($callback)) {
throw new InvalidArgumentException(
Expand Down Expand Up @@ -94,6 +94,8 @@ protected function removeMutex()
*
* @param int $expiresAt
* @return $this
*
* @throws \LogicException
*/
public function withoutOverlapping($expiresAt = 1440)
{
Expand All @@ -112,6 +114,26 @@ public function withoutOverlapping($expiresAt = 1440)
});
}

/**
* Allow the event to only run on one server for each cron expression.
*
* @return $this
*
* @throws \LogicException
*/
public function onOneServer()
{
if (! isset($this->description)) {
throw new LogicException(
"A scheduled event name is required to only run on one server. Use the 'name' method before 'onOneServer'."
);
}

$this->onOneServer = true;

return $this;
}

/**
* Get the mutex name for the scheduled command.
*
Expand Down
31 changes: 25 additions & 6 deletions src/Illuminate/Console/Scheduling/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ class Event
*/
public $withoutOverlapping = false;

/**
* Indicates if the command should only be allowed to run on one server each cron expression.
*
* @var bool
*/
public $onOneServer = false;

/**
* The amount of time the mutex should be valid.
*
Expand Down Expand Up @@ -128,9 +135,9 @@ class Event
public $description;

/**
* The mutex implementation.
* The event mutex implementation.
*
* @var \Illuminate\Console\Scheduling\Mutex
* @var \Illuminate\Console\Scheduling\EventMutex
*/
public $mutex;

Expand All @@ -141,7 +148,7 @@ class Event
* @param string $command
* @return void
*/
public function __construct(Mutex $mutex, $command)
public function __construct(EventMutex $mutex, $command)
{
$this->mutex = $mutex;
$this->command = $command;
Expand Down Expand Up @@ -532,6 +539,18 @@ public function withoutOverlapping($expiresAt = 1440)
});
}

/**
* Allow the event to only run on one server for each cron expression.
*
* @return $this
*/
public function onOneServer()
{
$this->onOneServer = true;

return $this;
}

/**
* Register a callback to further filter the schedule.
*
Expand Down Expand Up @@ -663,12 +682,12 @@ public function getExpression()
}

/**
* Set the mutex implementation to be used.
* Set the event mutex implementation to be used.
*
* @param \Illuminate\Console\Scheduling\Mutex $mutex
* @param \Illuminate\Console\Scheduling\EventMutex $mutex
* @return $this
*/
public function preventOverlapsUsing(Mutex $mutex)
public function preventOverlapsUsing(EventMutex $mutex)
{
$this->mutex = $mutex;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@

namespace Illuminate\Console\Scheduling;

interface Mutex
interface EventMutex
{
/**
* Attempt to obtain a mutex for the given event.
* Attempt to obtain an event mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return bool
*/
public function create(Event $event);

/**
* Determine if a mutex exists for the given event.
* Determine if an event mutex exists for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return bool
*/
public function exists(Event $event);

/**
* Clear the mutex for the given event.
* Clear the event mutex for the given event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @return void
Expand Down
40 changes: 32 additions & 8 deletions src/Illuminate/Console/Scheduling/Schedule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Illuminate\Console\Scheduling;

use Illuminate\Support\Carbon;
use Illuminate\Console\Application;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\ShouldQueue;
Expand All @@ -17,11 +18,18 @@ class Schedule
protected $events = [];

/**
* The mutex implementation.
* The event mutex implementation.
*
* @var \Illuminate\Console\Scheduling\Mutex
* @var \Illuminate\Console\Scheduling\EventMutex
*/
protected $mutex;
protected $eventMutex;

/**
* The scheduling mutex implementation.
*
* @var \Illuminate\Console\Scheduling\SchedulingMutex
*/
protected $schedulingMutex;

/**
* Create a new schedule instance.
Expand All @@ -32,9 +40,13 @@ public function __construct()
{
$container = Container::getInstance();

$this->mutex = $container->bound(Mutex::class)
? $container->make(Mutex::class)
: $container->make(CacheMutex::class);
$this->eventMutex = $container->bound(EventMutex::class)
? $container->make(EventMutex::class)
: $container->make(CacheEventMutex::class);

$this->schedulingMutex = $container->bound(SchedulingMutex::class)
? $container->make(SchedulingMutex::class)
: $container->make(CacheSchedulingMutex::class);
}

/**
Expand All @@ -47,7 +59,7 @@ public function __construct()
public function call($callback, array $parameters = [])
{
$this->events[] = $event = new CallbackEvent(
$this->mutex, $callback, $parameters
$this->eventMutex, $callback, $parameters
);

return $event;
Expand Down Expand Up @@ -104,11 +116,23 @@ public function exec($command, array $parameters = [])
$command .= ' '.$this->compileParameters($parameters);
}

$this->events[] = $event = new Event($this->mutex, $command);
$this->events[] = $event = new Event($this->eventMutex, $command);

return $event;
}

/**
* Determine if the server is allowed to run this event.
*
* @param \Illuminate\Console\Scheduling\Event $event
* @param \Illuminate\Support\Carbon $time
* @return bool
*/
public function allowServerToRun(Event $event, Carbon $time)
{
return $this->schedulingMutex->create($event, $time);
}

/**
* Compile parameters for a command.
*
Expand Down
Loading