Skip to content
Open
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"psr/log": "^1",
"ramsey/uuid": "^4.2.3",
"react/event-loop": "^1.4",
"react/promise": "^2.10",
"react/promise": "^3.3",
"simshaun/recurr": "^5",
"ipl/stdlib": ">=0.12.0"
},
Expand Down
12 changes: 6 additions & 6 deletions src/Common/Promises.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ trait Promises
*/
protected function addPromise(UuidInterface $uuid, PromiseInterface $promise): self
{
if (! $this->promises->contains($uuid)) {
$this->promises->attach($uuid, new ArrayObject());
if (! $this->promises->offsetExists($uuid)) {
$this->promises->offsetSet($uuid, new ArrayObject());
}

$this->promises[$uuid][] = $promise;
Expand All @@ -45,7 +45,7 @@ protected function addPromise(UuidInterface $uuid, PromiseInterface $promise): s
* **Example Usage:**
*
* ```php
* $promise->always(function () use ($uuid, $promise) {
* $promise->finally(function () use ($uuid, $promise) {
* $promises->removePromise($uuid, $promise);
* })
* ```
Expand All @@ -60,7 +60,7 @@ protected function addPromise(UuidInterface $uuid, PromiseInterface $promise): s
*/
protected function removePromise(UuidInterface $uuid, PromiseInterface $promise): self
{
if (! $this->promises->contains($uuid)) {
if (! $this->promises->offsetExists($uuid)) {
throw new InvalidArgumentException(
sprintf('There are no registered promises for UUID %s', $uuid->toString())
);
Expand Down Expand Up @@ -96,12 +96,12 @@ protected function removePromise(UuidInterface $uuid, PromiseInterface $promise)
*/
protected function detachPromises(UuidInterface $uuid): array
{
if (! $this->promises->contains($uuid)) {
if (! $this->promises->offsetExists($uuid)) {
return [];
}

$promises = $this->promises[$uuid];
$this->promises->detach($uuid);
$this->promises->offsetUnset($uuid);

return $promises->getArrayCopy();
}
Expand Down
6 changes: 3 additions & 3 deletions src/Common/Timers.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ trait Timers
*/
protected function attachTimer(UuidInterface $uuid, TimerInterface $timer): self
{
$this->timers->attach($uuid, $timer);
$this->timers->offsetSet($uuid, $timer);

return $this;
}
Expand All @@ -47,13 +47,13 @@ protected function attachTimer(UuidInterface $uuid, TimerInterface $timer): self
*/
protected function detachTimer(UuidInterface $uuid): ?TimerInterface
{
if (! $this->timers->contains($uuid)) {
if (! $this->timers->offsetExists($uuid)) {
return null;
}

$timer = $this->timers->offsetGet($uuid);

$this->timers->detach($uuid);
$this->timers->offsetUnset($uuid);

return $timer;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Contract/Task.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace ipl\Scheduler\Contract;

use Ramsey\Uuid\UuidInterface;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;

interface Task
{
Expand Down Expand Up @@ -33,7 +33,7 @@
*
* This commits the actions in a non-blocking fashion to the event loop and yields a deferred promise
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
public function run(): ExtendedPromiseInterface;
public function run(): PromiseInterface;

Check failure on line 38 in src/Contract/Task.php

View workflow job for this annotation

GitHub Actions / PHP / Static analysis (8.5) / PHPStan 8.5

Method ipl\Scheduler\Contract\Task::run() return type with generic interface React\Promise\PromiseInterface does not specify its types: T

Check failure on line 38 in src/Contract/Task.php

View workflow job for this annotation

GitHub Actions / PHP / Static analysis (8.3) / PHPStan 8.3

Method ipl\Scheduler\Contract\Task::run() return type with generic interface React\Promise\PromiseInterface does not specify its types: T

Check failure on line 38 in src/Contract/Task.php

View workflow job for this annotation

GitHub Actions / PHP / Static analysis (8.2) / PHPStan 8.2

Method ipl\Scheduler\Contract\Task::run() return type with generic interface React\Promise\PromiseInterface does not specify its types: T

Check failure on line 38 in src/Contract/Task.php

View workflow job for this annotation

GitHub Actions / PHP / Static analysis (8.4) / PHPStan 8.4

Method ipl\Scheduler\Contract\Task::run() return type with generic interface React\Promise\PromiseInterface does not specify its types: T
}
27 changes: 13 additions & 14 deletions src/Scheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use ipl\Stdlib\Events;
use React\EventLoop\Loop;
use React\Promise;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;
use SplObjectStorage;
use Throwable;

Expand All @@ -24,7 +24,7 @@ class Scheduler
/**
* Event raised when a {@link Task task} is canceled
*
* The task and its pending operations as an array of canceled {@link ExtendedPromiseInterface promise}s
* The task and its pending operations as an array of canceled {@link PromiseInterface promise}s
* are passed as parameters to the event callbacks.
*
* **Example usage:**
Expand Down Expand Up @@ -94,13 +94,13 @@ class Scheduler
/**
* Event raised upon operation of a {@link Task task}
*
* The task and the possibly not yet completed result of the operation as a {@link ExtendedPromiseInterface promise}
* The task and the possibly not yet completed result of the operation as a {@link PromiseInterface promise}
* are passed as parameters to the event callbacks.
*
* **Example usage:**
*
* ```php
* $scheduler->on($scheduler::ON_TASK_OPERATION, function (Task $task, ExtendedPromiseInterface $_) use ($logger) {
* $scheduler->on($scheduler::ON_TASK_OPERATION, function (Task $task, PromiseInterface $_) use ($logger) {
* $logger->info(sprintf('Task %s operating', $task->getName()));
* });
* ```
Expand Down Expand Up @@ -161,7 +161,7 @@ public function remove(Task $task): self

$this->cancelTask($task);

$this->tasks->detach($task);
$this->tasks->offsetUnset($task);

return $this;
}
Expand Down Expand Up @@ -191,7 +191,7 @@ public function removeTasks(): self
*/
public function hasTask(Task $task): bool
{
return $this->tasks->contains($task);
return $this->tasks->offsetExists($task);
}

/**
Expand Down Expand Up @@ -233,9 +233,9 @@ public function schedule(Task $task, Frequency $frequency): self
$this->emit(static::ON_TASK_EXPIRED, [$task, $nextDue]);
};

if ($this->promises->contains($task->getUuid())) {
if ($this->promises->offsetExists($task->getUuid())) {
$pendingPromises = (array) $this->promises->offsetGet($task->getUuid());
Promise\all($pendingPromises)->always($removeTask);
Promise\all($pendingPromises)->finally($removeTask);
} else {
$removeTask();
}
Expand All @@ -257,7 +257,7 @@ public function schedule(Task $task, Frequency $frequency): self
);
$this->emit(static::ON_TASK_SCHEDULED, [$task, $nextDue]);

$this->tasks->attach($task);
$this->tasks->offsetSet($task);

return $this;
}
Expand Down Expand Up @@ -285,10 +285,9 @@ protected function cancelTask(Task $task): void
{
Loop::cancelTimer($this->detachTimer($task->getUuid()));

/** @var ExtendedPromiseInterface[] $promises */
/** @var PromiseInterface[] $promises */
$promises = $this->detachPromises($task->getUuid());
if (! empty($promises)) {
/** @var Promise\CancellablePromiseInterface $promise */
foreach ($promises as $promise) {
$promise->cancel();
}
Expand All @@ -301,9 +300,9 @@ protected function cancelTask(Task $task): void
*
* @param Task $task
*
* @return ExtendedPromiseInterface
* @return PromiseInterface
*/
protected function runTask(Task $task): ExtendedPromiseInterface
protected function runTask(Task $task): PromiseInterface
{
$promise = $task->run();
$this->addPromise($task->getUuid(), $promise);
Expand All @@ -315,7 +314,7 @@ function ($result) use ($task): void {
function (Throwable $reason) use ($task): void {
$this->emit(self::ON_TASK_FAILED, [$task, $reason]);
}
)->always(function () use ($task, $promise): void {
)->finally(function () use ($task, $promise): void {
// Unregister the promise without canceling it as it's already resolved
$this->removePromise($task->getUuid(), $promise);
});
Expand Down
2 changes: 1 addition & 1 deletion tests/Lib/CountableScheduler.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function count(): int

public function countPromises(UuidInterface $uuid): int
{
if (! $this->promises->contains($uuid)) {
if (! $this->promises->offsetExists($uuid)) {
return 0;
}

Expand Down
8 changes: 4 additions & 4 deletions tests/Lib/PromiseBoundTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
use ipl\Scheduler\Common\TaskProperties;
use ipl\Scheduler\Contract\Task;
use Ramsey\Uuid\Uuid;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;

class PromiseBoundTask implements Task
{
use TaskProperties;

/** @var ExtendedPromiseInterface */
/** @var PromiseInterface */
protected $promise;

/** @var int */
protected $startedPromises = 0;

public function __construct(ExtendedPromiseInterface $promise)
public function __construct(PromiseInterface $promise)
{
$this->promise = $promise;

Expand All @@ -31,7 +31,7 @@ public function getStartedPromises(): int
return $this->startedPromises;
}

public function run(): ExtendedPromiseInterface
public function run(): PromiseInterface

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should document the changed return types like this one somewhere.

{
$this->startedPromises++;

Expand Down
28 changes: 14 additions & 14 deletions tests/SchedulerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use PHPUnit\Framework\TestCase;
use React\EventLoop\Loop;
use React\Promise;
use React\Promise\ExtendedPromiseInterface;
use React\Promise\PromiseInterface;
use Throwable;

class SchedulerTest extends TestCase
Expand All @@ -38,7 +38,7 @@ protected function runAndStopEventLoop()

public function testSchedulingTasksNotYetDue()
{
$task = new PromiseBoundTask(Promise\resolve());
$task = new PromiseBoundTask(Promise\resolve(null));
$nextDue = new DateTime('+1 week');

$scheduledAt = null;
Expand All @@ -60,12 +60,12 @@ public function testSchedulingTasksNotYetDue()
public function testDoesNotScheduleNeverDueTasks()
{
$neverRun = true;
$task = new PromiseBoundTask(Promise\resolve());
$task = new PromiseBoundTask(Promise\resolve(null));
$this->scheduler
->schedule($task, new NeverDueFrequency())
->on(
CountableScheduler::ON_TASK_RUN,
function (Task $_, ExtendedPromiseInterface $p) use (&$neverRun): void {
function (Task $_, PromiseInterface $p) use (&$neverRun): void {
$neverRun = false;
}
);
Expand All @@ -82,12 +82,12 @@ function (Task $_, ExtendedPromiseInterface $p) use (&$neverRun): void {
public function testDueTasksRunImmediately()
{
$hasRun = false;
$task = new PromiseBoundTask(Promise\resolve());
$task = new PromiseBoundTask(Promise\resolve(null));
$this->scheduler
->schedule($task, new ImmediateDueFrequency())
->on(
CountableScheduler::ON_TASK_RUN,
function (Task $t, ExtendedPromiseInterface $_) use (&$hasRun): void {
function (Task $t, PromiseInterface $_) use (&$hasRun): void {
$hasRun = true;
}
);
Expand Down Expand Up @@ -174,7 +174,7 @@ public function testFailedTasksPropagateReason()
->schedule($task, new ImmediateDueFrequency())
->on(
CountableScheduler::ON_TASK_RUN,
function (Task $_, ExtendedPromiseInterface $p) use ($deferred): void {
function (Task $_, PromiseInterface $p) use ($deferred): void {
$deferred->reject(new TaskRejectedException('rejected'));
}
)
Expand Down Expand Up @@ -208,7 +208,7 @@ public function testDoneTasksPropagateReturn()
->schedule($task, new ImmediateDueFrequency())
->on(
CountableScheduler::ON_TASK_RUN,
function (Task $_, ExtendedPromiseInterface $p) use ($deferred): void {
function (Task $_, PromiseInterface $p) use ($deferred): void {
$deferred->resolve(10);
}
)
Expand All @@ -232,8 +232,8 @@ function (Task $_, $result) use (&$taskFulFilled, &$returnResult): void {

public function testCountsWithMultipleScheduledTasks()
{
$task1 = new PromiseBoundTask(Promise\resolve());
$task2 = new PromiseBoundTask(Promise\resolve());
$task1 = new PromiseBoundTask(Promise\resolve(null));
$task2 = new PromiseBoundTask(Promise\resolve(null));
$task3 = new PromiseBoundTask((new Promise\Deferred())->promise());

$this->scheduler
Expand All @@ -255,7 +255,7 @@ public function testCountsWithMultipleScheduledTasks()

public function testDoesNotScheduleExpiredTasks()
{
$task = new PromiseBoundTask(Promise\resolve());
$task = new PromiseBoundTask(Promise\resolve(null));
$frequency = new ExpiringFrequency();
$frequency->setExpired();

Expand Down Expand Up @@ -284,7 +284,7 @@ public function testTaskIsDetachedAfterExpiring()
})
->on(
CountableScheduler::ON_TASK_RUN,
function (Task $t, ExtendedPromiseInterface $_) use ($deferred, $frequency): void {
function (Task $t, PromiseInterface $_) use ($deferred, $frequency): void {
$frequency->setExpired();

Loop::addTimer(0, function ($timer) use ($deferred): void {
Expand Down Expand Up @@ -314,10 +314,10 @@ public function testOneOffTasksRunOnlyOnce()
->schedule($task, new OneOff(new DateTime('+1 milliseconds')))
->on(
CountableScheduler::ON_TASK_RUN,
function (Task $t, ExtendedPromiseInterface $_) use (&$countRuns, $deferred): void {
function (Task $t, PromiseInterface $_) use (&$countRuns, $deferred): void {
$countRuns += 1;

$deferred->resolve();
$deferred->resolve(null);
}
);

Expand Down
Loading