Skip to content

Commit

Permalink
Merge pull request #12 from Indatus/develop
Browse files Browse the repository at this point in the history
Improvements/fixes to scheduling
  • Loading branch information
bkuhl committed Mar 24, 2014
2 parents 31b5521 + 503392b commit 7c8486a
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 86 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Use `php artisan scheduled:make` to generate a new scheduled command, the same w
<a name="scheduling-commands" />
### Scheduling Existing Commands

Simply `extend \Indatus\Dispatcher\ScheduledCommand` and implement the `schedule()` method within your command. This method is injected with a `Schedulable` which provides a simple interface for scheduling your commands.
Simply `extend \Indatus\Dispatcher\ScheduledCommand` and implement the `schedule()` method within your command or `implement \Indatus\Dispatcher\ScheduledCommandInterface`. This method is injected with a `Schedulable` which provides a simple interface for scheduling your commands.

```php
public function schedule(Schedulable $scheduler)
Expand All @@ -110,6 +110,16 @@ Simply `extend \Indatus\Dispatcher\ScheduledCommand` and implement the `schedule
}
```

You may also schedule commands via raw cron expressions

```php
public function schedule(Schedulable $scheduler)
{
//every other day at 3:15am, 4:15am and 5:15am
return $scheduler->setSchedule(3, [3,4,5], '*/2', '*', '*');
}
```

<a name="commands-as-users" />
### Running Commands As Users

Expand Down
35 changes: 32 additions & 3 deletions src/Indatus/Dispatcher/Drivers/Cron/ScheduleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,48 @@

use App;
use Cron\CronExpression;
use Indatus\Dispatcher\ScheduledCommand;
use Indatus\Dispatcher\ScheduledCommandInterface;

class ScheduleService extends \Indatus\Dispatcher\Services\ScheduleService {

/**
* Determine if a command is due to be run
* @param ScheduledCommand $command
* @param ScheduledCommandInterface $command
* @return bool
*/
public function isDue(ScheduledCommand $command)
public function isDue(ScheduledCommandInterface $command)
{
$scheduler = App::make('Indatus\Dispatcher\Schedulable');
$cron = CronExpression::factory($command->schedule($scheduler)->getSchedule());
return $cron->isDue();
}

/**
* @inheritDoc
*/
public function printSummary()
{
$this->table->setHeaders(array('Environment(s)', 'Name', 'Minute', 'Hour', 'Day of Month', 'Month', 'Day of Week', 'Run as'));
/** @var $command \Indatus\Dispatcher\ScheduledCommandInterface */
foreach ($this->getScheduledCommands() as $command) {
/** @var $command \Indatus\Dispatcher\ScheduledCommandInterface */
$scheduler = $command->schedule(App::make('Indatus\Dispatcher\Schedulable'));

$this->table->addRow(array(
is_array($command->environment()) ? implode(',', $command->environment()) : $command->environment(),
$command->getName(),
$scheduler->getScheduleMinute(),
$scheduler->getScheduleHour(),
$scheduler->getScheduleDayOfMonth(),
$scheduler->getScheduleMonth(),
$scheduler->getScheduleDayOfWeek(),
$command->user()
));
}

//sort by first column
$this->table->sort(0);

$this->table->display();
}
}
5 changes: 4 additions & 1 deletion src/Indatus/Dispatcher/Drivers/Cron/Scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Scheduler implements Schedulable
{

/**
* @var string Any of the contextual timeframe
* @var string Any of the contextual time frame
*/
const ANY = '*';

Expand Down Expand Up @@ -71,6 +71,7 @@ public function getSchedule()
* @param mixed $dayOfMonth
* @param mixed $month
* @param mixed $dayOfWeek
* @return $this
*/
public function setSchedule($minute, $hour, $dayOfMonth, $month, $dayOfWeek)
{
Expand All @@ -85,6 +86,8 @@ public function setSchedule($minute, $hour, $dayOfMonth, $month, $dayOfWeek)
$this->setScheduleDayOfMonth($dayOfMonth);
$this->setScheduleMonth($month);
$this->setScheduleDayOfWeek($dayOfWeek);

return $this;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/Indatus/Dispatcher/Schedulable.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function daysOfTheMonth($hoursIntoTheDay);
* @param mixed $dayOfMonth
* @param mixed $month
* @param mixed $dayOfWeek
* @return $this
*/
public function setSchedule($minute, $hour, $dayOfMonth, $month, $dayOfWeek);

Expand Down
10 changes: 1 addition & 9 deletions src/Indatus/Dispatcher/ScheduledCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use App;
use Illuminate\Console\Command;

abstract class ScheduledCommand extends Command
abstract class ScheduledCommand extends Command implements ScheduledCommandInterface
{


Expand All @@ -24,14 +24,6 @@ abstract class ScheduledCommand extends Command
*/
protected $name = 'scheduledCommand';

/**
* When a command should run
*
* @param Schedulable $scheduler
* @return \Indatus\Dispatcher\Schedulable
*/
abstract public function schedule(Schedulable $scheduler);

/**
* User to run the command as
*
Expand Down
36 changes: 36 additions & 0 deletions src/Indatus/Dispatcher/ScheduledCommandInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* @author Ben Kuhl <[email protected]>
*/
namespace Indatus\Dispatcher;

interface ScheduledCommandInterface
{
/**
* User to run the command as
* @return string Defaults to false to run as default user
*/
public function user();

/**
* When a command should run
* @param Schedulable $scheduler
* @return \Indatus\Dispatcher\Schedulable
*/
public function schedule(Schedulable $scheduler);

/**
* Environment(s) under which the given command should run
* Defaults to '*' for all environments
* @return string
*/
public function environment();

/**
* Checks whether the command is enabled or not in the current environment
* Override this to check for x or y and return false if the command can not
* run properly under the current conditions.
* @return Boolean
*/
public function isEnabled();
}
39 changes: 5 additions & 34 deletions src/Indatus/Dispatcher/Services/ScheduleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use App;
use Artisan;
use Indatus\Dispatcher\ScheduledCommand;
use Indatus\Dispatcher\ScheduledCommandInterface;
use Indatus\Dispatcher\Table;

abstract class ScheduleService
Expand All @@ -28,10 +28,10 @@ public function __construct(Table $table)

/**
* Determine if a command is due to be run
* @param ScheduledCommand $command
* @param ScheduledCommandInterface $command
* @return bool
*/
abstract public function isDue(ScheduledCommand $command);
abstract public function isDue(ScheduledCommandInterface $command);

/**
* Get all commands that are scheduled
Expand All @@ -42,7 +42,7 @@ public function getScheduledCommands()
{
$scheduledCommands = array();
foreach (Artisan::all() as $command) {
if ($command instanceOf ScheduledCommand) {
if ($command instanceOf ScheduledCommandInterface) {
$scheduledCommands[] = $command;
}
}
Expand All @@ -68,37 +68,8 @@ public function getDueCommands()

/**
* Review scheduled commands schedule, active status, etc.
* @todo refactor this... it's ugly. The output goes directly to STDOUT
* @return void
*/
public function printSummary()
{
$this->table->setHeaders(array('Environment(s)', 'Name', 'Minute', 'Hour', 'Day of Month', 'Month', 'Day of Week', 'Run as'));
/** @var $command \Indatus\Dispatcher\ScheduledCommand */
$commands = 0;
$activeCommands = 0;
foreach ($this->getScheduledCommands() as $command) {
/** @var $command \Indatus\Dispatcher\ScheduledCommand */
$scheduler = $command->schedule(App::make('Indatus\Dispatcher\Schedulable'));

$this->table->addRow(array(
is_array($command->environment()) ? implode(',', $command->environment()) : $command->environment(),
$command->getName(),
$scheduler->getScheduleMinute(),
$scheduler->getScheduleHour(),
$scheduler->getScheduleDayOfMonth(),
$scheduler->getScheduleMonth(),
$scheduler->getScheduleDayOfWeek(),
$command->user()
));
$commands++;
$activeCommands++;
}

//sort by first column
$this->table->sort(0);

$this->table->display();
}
abstract public function printSummary();

}
55 changes: 55 additions & 0 deletions tests/Drivers/Cron/TestCronScheduleService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* @author Ben Kuhl <[email protected]>
*/

use Mockery as m;

class TestCronScheduleService extends TestCase
{
public function setUp()
{
parent::setUp();
}

public function tearDown()
{
parent::tearDown();
m::close();
}

/**
* Test that a summary is properly generated
* Dangit this is ugly... gotta find a new cli library
*/
public function testPrintSummary()
{
$table = m::mock('Indatus\Dispatcher\Table', function ($m) {
$m->shouldReceive('setHeaders')->once();
$m->shouldReceive('sort')->once();
$m->shouldReceive('display')->once();
});
$scheduledCommand = m::mock('Indatus\Dispatcher\ScheduledCommand', function ($m) use ($table) {
$table->shouldReceive('addRow')->once();

$m->shouldReceive('getName')->once();
$m->shouldReceive('user')->once();
$m->shouldReceive('environment')->twice();
$m->shouldReceive('schedule')->once()->andReturn(m::mock('Indatus\Dispatcher\Drivers\Cron\Scheduler', function ($m) {
$m->shouldReceive('getScheduleMinute');
$m->shouldReceive('getScheduleHour');
$m->shouldReceive('getScheduleDayOfMonth');
$m->shouldReceive('getScheduleMonth');
$m->shouldReceive('getScheduleDayOfWeek');
}));
});
$scheduleService = m::mock('Indatus\Dispatcher\Drivers\Cron\ScheduleService[getScheduledCommands]', array(
$table
), function ($m) use ($scheduledCommand) {
$m->shouldReceive('getScheduledCommands')->once()->andReturn(array(
$scheduledCommand
));
});
$scheduleService->printSummary();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use \Indatus\Dispatcher\Drivers\Cron\Scheduler;

class TestScheduler extends TestCase
class TestCronScheduler extends TestCase
{
/**
* @var Indatus\Dispatcher\Scheduler
Expand All @@ -16,6 +16,7 @@ class TestScheduler extends TestCase

public function setUp()
{
parent::setUp();
$this->scheduler = new Scheduler();
}

Expand All @@ -29,7 +30,7 @@ public function testBuildingSchedule()

public function testSetSchedule()
{
$this->scheduler->setSchedule(1, 2, 3, 4, 5);
$this->assertInstanceOf($this->schedularClass, $this->scheduler->setSchedule(1, 2, 3, 4, 5));
$this->assertEquals($this->scheduler->getSchedule(), '1 2 3 4 5');
}

Expand Down
37 changes: 1 addition & 36 deletions tests/Services/TestScheduleService.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

use Mockery as m;
use Indatus\Dispatcher\Drivers\Cron\ScheduleService;
use Indatus\Dispatcher\Table;
use Indatus\Dispatcher\Scheduler;
use Indatus\Dispatcher\Table;

class TestScheduleService extends TestCase
{
Expand Down Expand Up @@ -39,41 +39,6 @@ public function testGetScheduledCommands()
$this->assertSameSize($scheduledCommands, $this->scheduleService->getScheduledCommands());
}

/**
* Test that a summary is properly generated
* Dangit this is ugly... gotta find a new cli library
*/
public function testPrintSummary()
{
$table = m::mock('Indatus\Dispatcher\Table', function ($m) {
$m->shouldReceive('setHeaders')->once();
$m->shouldReceive('sort')->once();
$m->shouldReceive('display')->once();
});
$scheduledCommand = m::mock('Indatus\Dispatcher\ScheduledCommand', function ($m) use ($table) {
$table->shouldReceive('addRow')->once();

$m->shouldReceive('getName')->once();
$m->shouldReceive('user')->once();
$m->shouldReceive('environment')->twice();
$m->shouldReceive('schedule')->once()->andReturn(m::mock('Indatus\Dispatcher\Drivers\Cron\Scheduler', function ($m) {
$m->shouldReceive('getScheduleMinute');
$m->shouldReceive('getScheduleHour');
$m->shouldReceive('getScheduleDayOfMonth');
$m->shouldReceive('getScheduleMonth');
$m->shouldReceive('getScheduleDayOfWeek');
}));
});
$scheduleService = m::mock('Indatus\Dispatcher\Drivers\Cron\ScheduleService[getScheduledCommands]', array(
$table
), function ($m) use ($scheduledCommand) {
$m->shouldReceive('getScheduledCommands')->once()->andReturn(array(
$scheduledCommand
));
});
$scheduleService->printSummary();
}

public function testGetDueCommands()
{
$scheduleService = m::mock('Indatus\Dispatcher\Drivers\Cron\ScheduleService[getScheduledCommands,isDue]', array(
Expand Down

0 comments on commit 7c8486a

Please sign in to comment.