Skip to content

Commit

Permalink
Merge pull request #60 from TheShiftExchange/maintenancemode
Browse files Browse the repository at this point in the history
Commands no longer run in maintenance mode
  • Loading branch information
bkuhl committed Jul 27, 2014
2 parents 1bd6781 + a4ecbd8 commit 42f5c92
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 6 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class MyCommand extends ScheduledCommand {
* [Scheduling Existing Commands](#scheduling-commands)
* [Running Commands As Users](#commands-as-users)
* [Environment-Specific Commands](#environment-commands)
* [Running Commands In Maintenance Mode](#maintenance-mode)
* [Advanced Scheduling](#advanced-scheduling)
* [Drivers](#drivers)
* [Cron](#Cron)
Expand Down Expand Up @@ -158,6 +159,20 @@ You may override `environment()` to ensure your command is only scheduled in spe
}
```

<a name="maintenance-mode" />
### Maintenance Mode

By default, cron commands will *not* run when application is in Maintenance Mode. This will prevent all sorts of weird output that might occur if a cron command is run while you are migrating a database or doing a composer update.

You may override `runInMaintenanceMode()` to force your command to still be run while the application is in maintenance mode.

```php
public function runInMaintenanceMode()
{
return true;
}
```

<a name="advanced-scheduling" />
### Advanced scheduling

Expand Down
10 changes: 10 additions & 0 deletions src/Indatus/Dispatcher/Scheduling/ScheduledCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,14 @@ public function environment()
return '*';
}

/**
* Should this command be allowed to run when application is in maintenance mode
*
* @return boolean Defaults to false
*/
public function runInMaintenanceMode()
{
return false;
}

}
31 changes: 25 additions & 6 deletions src/Indatus/Dispatcher/Services/CommandService.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,16 @@ public function runDue(Debugger $debugger)

//determine if the command is enabled
if ($command->isEnabled()) {

if ($this->runnableInEnvironment($command)) {
$scheduler = $queueItem->getScheduler();

$backgroundProcessRunner->run($command, $scheduler->getArguments(), $scheduler->getOptions(), $debugger);
if ($this->runnableInCurrentMaintenanceSetting($command)) {
if ($this->runnableInEnvironment($command)) {
$scheduler = $queueItem->getScheduler();

$backgroundProcessRunner->run($command, $scheduler->getArguments(), $scheduler->getOptions(), $debugger);
} else {
$debugger->commandNotRun($command, 'Command is not configured to run in '.App::environment());
}
} else {
$debugger->commandNotRun($command, 'Command is not configured to run in '.App::environment());
$debugger->commandNotRun($command, 'Command is not configured to run while application is in maintenance mode');
}
} else {
$debugger->commandNotRun($command, 'Command is disabled');
Expand Down Expand Up @@ -87,6 +90,22 @@ public function runnableInEnvironment(ScheduledCommandInterface $command)
return false;
}

/**
* Determine if application is in maintenance mode and if scheduled command can run
*
* @param \Indatus\Dispatcher\Scheduling\ScheduledCommandInterface $command
*
* @return bool
*/
public function runnableInCurrentMaintenanceSetting(ScheduledCommandInterface $command)
{
if (App::isDownForMaintenance()) {
return $command->runInMaintenanceMode();
}

return true;
}

/**
* Prepare a command's arguments for command line usage
*
Expand Down
5 changes: 5 additions & 0 deletions tests/Scheduling/TestScheduledCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ public function testDefaultEnvironment()
$this->assertEquals('*', $this->scheduledCommand->environment());
}

public function testDefaultRunInMaintenanceMode()
{
$this->assertFalse($this->scheduledCommand->runInMaintenanceMode());
}

}
57 changes: 57 additions & 0 deletions tests/Services/TestCommandService.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,36 @@ function ($m) use ($scheduledCommand, $scheduler) {
$this->assertNull($commandService->runDue($debugger));
}

public function testLogNotRunnableInMaintenanceMode()
{
$scheduledCommand = $this->mockCommand();
$scheduledCommand->shouldReceive('isEnabled')->once()->andReturn(true);

$scheduler = m::mock('Indatus\Dispatcher\Scheduling\Schedulable');
$queue = m::mock('Indatus\Dispatcher\Queue',
function ($m) use ($scheduledCommand, $scheduler) {
$item = m::mock('Indatus\Dispatcher\QueueItem');
$item->shouldReceive('getCommand')->once()->andReturn($scheduledCommand);
$m->shouldReceive('flush')->once()->andReturn(array($item));
});
$scheduleService = m::mock('Indatus\Dispatcher\Drivers\Cron\ScheduleService');
$scheduleService->shouldReceive('getQueue')->once()->andReturn($queue);
$this->app->instance('Indatus\Dispatcher\Services\ScheduleService', $scheduleService);

$commandService = m::mock('Indatus\Dispatcher\Services\CommandService[runnableInCurrentMaintenanceSetting,run]',
array($scheduleService),
function ($m) use ($scheduledCommand, $scheduler) {
$m->shouldReceive('runnableInCurrentMaintenanceSetting')->andReturn(false);
});

$debugger = m::mock('Indatus\Dispatcher\Debugger');
$debugger->shouldReceive('commandNotRun')->once()->with($scheduledCommand, 'Command is not configured to run while application is in maintenance mode');
$debugger->shouldReceive('log');
$debugger->shouldReceive('commandRun');

$this->assertNull($commandService->runDue($debugger));
}

public function testLogNotRunnableInEnvironment()
{
$scheduledCommand = $this->mockCommand();
Expand Down Expand Up @@ -162,6 +192,33 @@ public function testNotRunnableInEnvironment()
$this->assertFalse($this->commandService->runnableInEnvironment($scheduledCommand));
}

public function testNotRunnableInCurrentMaintenanceSetting()
{
$scheduledCommand = $this->mockCommand();
$scheduledCommand->shouldReceive('runInMaintenanceMode')->once()->andReturn(false);

App::shouldReceive('isDownForMaintenance')->andReturn(true);
$this->assertFalse($this->commandService->runnableInCurrentMaintenanceSetting($scheduledCommand));
}

public function testRunnableInCurrentMaintenanceSetting()
{
$scheduledCommand = $this->mockCommand();
$scheduledCommand->shouldReceive('runInMaintenanceMode')->once()->andReturn(true);

App::shouldReceive('isDownForMaintenance')->andReturn(true);
$this->assertTrue($this->commandService->runnableInCurrentMaintenanceSetting($scheduledCommand));
}

public function testChecksForMaintenanceMode()
{
$scheduledCommand = $this->mockCommand();
$scheduledCommand->shouldReceive('runInMaintenanceMode')->never();

App::shouldReceive('isDownForMaintenance')->andReturn(false);
$this->assertTrue($this->commandService->runnableInCurrentMaintenanceSetting($scheduledCommand));
}

public function testPrepareArguments()
{
$arguments = array(
Expand Down

0 comments on commit 42f5c92

Please sign in to comment.