Skip to content

Commit

Permalink
Extend time package (#51)
Browse files Browse the repository at this point in the history
* add CronTask

* add TimerServicePeriodicTasksRegisterTask
  • Loading branch information
Mararok authored Jan 8, 2020
1 parent dffd309 commit d3b5778
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 2 deletions.
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"guzzlehttp/guzzle": "~6.0",
"nannehuiges/jsend": "2.1.*",
"monolog/monolog": "1.*",
"php-di/php-di": "^6.0"
"php-di/php-di": "^6.0",
"dragonmantank/cron-expression": "^2.3"
},
"require": {
"php": "^7.1"
Expand All @@ -25,7 +26,8 @@
"guzzlehttp/guzzle": "~6.0 Used for rest api and other http communication",
"nannehuiges/jsend": "2.1.* Used for rest api",
"php-di/php-di": "^6.* Used for DI integration",
"ext-zmq": "when using ZMQ subpackage"
"ext-zmq": "when using ZMQ subpackage",
"dragonmantank/cron-expression": "^2.3 when using cron staff"
},
"autoload": {
"psr-4": {
Expand Down
78 changes: 78 additions & 0 deletions src/SAREhub/Commons/Time/CronTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php


namespace SAREhub\Commons\Time;


use Cron\CronExpression;
use DateTimeInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use SAREhub\Commons\Misc\TimeProvider;
use SAREhub\Commons\Task\Task;

class CronTask implements LoggerAwareInterface
{
/**
* @var CronExpression
*/
private $cron;

/**
* @var TimeProvider
*/
private $timeProvider;

/**
* @var Task
*/
private $taskToRun;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @var DateTimeInterface
*/
private $nextRunDate;

public function __construct(CronExpression $cron, TimeProvider $timeProvider, Task $taskToRun)
{
$this->cron = $cron;
$this->timeProvider = $timeProvider;
$this->taskToRun = $taskToRun;
$this->logger = new NullLogger();
$this->updateNextRunDate();
}

public function __invoke()
{
$now = $this->timeProvider->now();
$this->logger->debug("Invoked, current nextRunDate: {nextRunDate}", [
"nextRunDate" => $this->nextRunDate->format(\DateTime::ATOM)
]);
if ($now >= $this->nextRunDate->getTimestamp()) {
$this->logger->notice("Run task, current nextRunDate: {nextRunDate}", [
"nextRunDate" => $this->nextRunDate->format(\DateTime::ATOM)
]);
$this->taskToRun->run();
$this->updateNextRunDate();
$this->logger->notice("Task ended, current nextRunDate: {nextRunDate}", [
"nextRunDate" => $this->nextRunDate->format(\DateTime::ATOM)
]);
}
}

private function updateNextRunDate(): void
{
$this->nextRunDate = $this->cron->getNextRunDate("@" . $this->timeProvider->now());
}

public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
45 changes: 45 additions & 0 deletions src/SAREhub/Commons/Time/PeriodicTaskDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php


namespace SAREhub\Commons\Time;


class PeriodicTaskDefinition
{
/**
* @var string
*/
private $id;

/**
* @var int
*/
private $interval;

/**
* @var callable
*/
private $callback;

public function __construct(string $id, int $interval, callable $callback)
{
$this->id = $id;
$this->interval = $interval;
$this->callback = $callback;
}

public function getId(): string
{
return $this->id;
}

public function getInterval(): int
{
return $this->interval;
}

public function getCallback(): callable
{
return $this->callback;
}
}
38 changes: 38 additions & 0 deletions src/SAREhub/Commons/Time/TimerServicePeriodicTasksRegisterTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php


namespace SAREhub\Commons\Time;


use SAREhub\Commons\Task\Task;
use SAREhub\Commons\Time\TimerService;

class TimerServicePeriodicTasksRegisterTask implements Task
{
/**
* @var TimerService
*/
private $service;

/**
* @var PeriodicTaskDefinition[]
*/
private $taskDefs;

public function __construct(TimerService $service, array $taskDefs)
{
$this->service = $service;
$this->taskDefs = $taskDefs;
}

public function run()
{
foreach ($this->taskDefs as $taskDef) {
$this->service->addPeriodicTask(
$taskDef->getId(),
$taskDef->getInterval(),
$taskDef->getCallback()
);
}
}
}
79 changes: 79 additions & 0 deletions tests/SAREhub/Commons/Time/CronTaskTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace SAREhub\Commons\Time;

use Cron\CronExpression;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use PHPUnit\Framework\TestCase;
use SAREhub\Commons\Misc\TimeProvider;
use SAREhub\Commons\Task\Task;

class CronTaskTest extends TestCase
{

use MockeryPHPUnitIntegration;

/**
* @var CronExpression
*/
private $cron;

/**
* @var TimeProvider
*/
private $timeProvider;

/**
* @var Task
*/
private $taskToRun;

/**
* @var CronTask
*/
private $task;

protected function setUp()
{
$this->cron = CronExpression::factory("@hourly");
$this->timeProvider = new TimeProvider();
$this->timeProvider->freezeTime();
$this->taskToRun = Mockery::mock(Task::class);
$this->task = new CronTask($this->cron, $this->timeProvider, $this->taskToRun);
}

public function testRunWhenNowIsNextRunDate()
{
$currentNextRunDate = $this->cron->getNextRunDate("@" . $this->timeProvider->now());
$this->timeProvider->freezeTime($currentNextRunDate->getTimestamp());

$this->taskToRun->expects("run")->with();

($this->task)();
}

public function testRunWhenNowIsNotNextRunDate()
{
$currentNextRunDate = $this->cron->getNextRunDate("@" . $this->timeProvider->now());
$this->timeProvider->freezeTime($currentNextRunDate->getTimestamp() - 1);

$this->taskToRun->expects("run")->never();

($this->task)();
}

public function testRunWhenAfterRunDate()
{
$currentNextRunDate = $this->cron->getNextRunDate("@" . $this->timeProvider->now());
$this->timeProvider->freezeTime($currentNextRunDate->getTimestamp() + 1);
$this->taskToRun->expects("run")->once();
($this->task)();

$currentNextRunDate = $this->cron->getNextRunDate("@" . $this->timeProvider->now());
$this->timeProvider->freezeTime($currentNextRunDate->getTimestamp() - 1);
$this->taskToRun->expects("run")->never();

($this->task)();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Commons\Time;

use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use SAREhub\Commons\Time\PeriodicTaskDefinition;
use SAREhub\Commons\Time\TimerService;
use PHPUnit\Framework\TestCase;
use SAREhub\Commons\Time\TimerServicePeriodicTasksRegisterTask;

class TimerServicePeriodicTasksRegisterTaskTest extends TestCase
{

use MockeryPHPUnitIntegration;

public function testRun()
{
$timerService = \Mockery::mock(TimerService::class);
$id = "test";
$interval = 60;
$callback = function () {
};
$def = new PeriodicTaskDefinition($id, $interval, $callback);
$task = new TimerServicePeriodicTasksRegisterTask($timerService, [$def]);

$timerService->expects("addPeriodicTask")->with($id, $interval, $callback);

$task->run();
}
}

0 comments on commit d3b5778

Please sign in to comment.