Added TaskModifyEvent.
continuous-integration/drone/push Build is failing Details

Event gets fired when an Event is modified by sending it to TaskStorage::modifyEvent. This allows components to observe changes and report these to the user. Might also be useful to cancel unwanted changes.
This commit is contained in:
Abel Hoogeveen 2020-05-19 22:07:44 +02:00
parent 8bcebfc1c3
commit 5f369c784b
No known key found for this signature in database
GPG Key ID: 96C2234920BF4292
5 changed files with 164 additions and 1 deletions

View File

@ -0,0 +1,64 @@
<?php
/**
* FuzeWorks CLIComponent.
*
* The FuzeWorks PHP FrameWork
*
* Copyright (C) 2013-2019 TechFuze
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @author TechFuze
* @copyright Copyright (c) 2013 - 2019, TechFuze. (http://techfuze.net)
* @license https://opensource.org/licenses/MIT MIT License
*
* @link http://techfuze.net/fuzeworks
* @since Version 1.2.0
*
* @version Version 1.2.0
*/
namespace FuzeWorks\Async\Events;
use FuzeWorks\Async\Task;
use FuzeWorks\Event;
class TaskModifyEvent extends Event
{
/**
* @var Task
*/
protected $task;
public function init(Task $task)
{
$this->task = $task;
}
public function getTask(): Task
{
return $this->task;
}
public function updateTask(Task $task)
{
$this->task = $task;
}
}

View File

@ -79,6 +79,11 @@ interface TaskStorage
/**
* Modifies a task
*
* Should first check if the Task exists in TaskStorage. If not, it should throw a TasksException.
*
* Modifies a Task in TaskStorage. Should fire a TaskModifyEvent and cancel the edit if cancelled by the event.
* If cancelled, should return zero. Preferably be logged as well.
*
* @param Task $task
* @return bool
* @throws TasksException

View File

@ -37,9 +37,12 @@
namespace FuzeWorks\Async\TaskStorage;
use FuzeWorks\Async\Events\TaskModifyEvent;
use FuzeWorks\Async\Task;
use FuzeWorks\Async\TasksException;
use FuzeWorks\Async\TaskStorage;
use FuzeWorks\Events;
use FuzeWorks\Logger;
/**
* Class DummyTaskStorage
@ -126,6 +129,18 @@ class DummyTaskStorage implements TaskStorage
*/
public function modifyTask(Task $task): bool
{
// Fire the TaskModifyEvent
/** @var TaskModifyEvent $event */
$event = Events::fireEvent(new TaskModifyEvent(), $task);
if ($event->isCancelled())
{
Logger::log("Did not modify task. Cancelled by taskModifyEvent.");
return false;
}
// And finally replace Task with the event based one.
$task = $event->getTask();
$taskId = $task->getId();
for ($i=0;$i<count($this->tasks);$i++)
{

View File

@ -35,9 +35,12 @@
*/
namespace FuzeWorks\Async\TaskStorage;
use FuzeWorks\Async\Events\TaskModifyEvent;
use FuzeWorks\Async\Task;
use FuzeWorks\Async\TasksException;
use FuzeWorks\Async\TaskStorage;
use FuzeWorks\Events;
use FuzeWorks\Logger;
use Redis;
use RedisException;
@ -159,8 +162,17 @@ class RedisTaskStorage implements TaskStorage
if (!$isMember)
throw new TasksException("Could not modify task. Task '$taskId' already exists.");
// Fire the TaskModifyEvent
/** @var TaskModifyEvent $event */
$event = Events::fireEvent(new TaskModifyEvent(), $task);
if ($event->isCancelled())
{
Logger::log("Did not modify task. Cancelled by taskModifyEvent.");
return false;
}
// And write the data
$taskData = serialize($task);
$taskData = serialize($event->getTask());
return $this->conn->set($this->key_prefix . $taskId, $taskData);
}

View File

@ -34,11 +34,14 @@
* @version Version 1.0.0
*/
use FuzeWorks\Async\Events\TaskModifyEvent;
use FuzeWorks\Async\Task;
use FuzeWorks\Async\Tasks;
use FuzeWorks\Async\TasksException;
use FuzeWorks\Async\TaskStorage;
use FuzeWorks\Async\TaskStorage\DummyTaskStorage;
use FuzeWorks\Events;
use FuzeWorks\Priority;
use PHPUnit\Framework\TestCase;
/**
@ -54,9 +57,13 @@ class TaskStorageTest extends TestCase
public function setUp(): void
{
// Add TaskStorage
$tasks = new Tasks();
$this->taskStorage = $tasks->getTaskStorage();
$this->taskStorage->reset();
// Reset events
Events::$listeners = [];
}
public function testDummyTaskStorageClass()
@ -199,6 +206,66 @@ class TaskStorageTest extends TestCase
$this->taskStorage->modifyTask($dummyTask);
}
/**
* @depends testModifyTask
*/
public function testModifyTaskEvent()
{
// Prepare a dummy task
$dummyTask = new Task('testModifyTaskEvent', 'none');
$dummyTask->setStatus(Task::PENDING);
// Then add the Task
$this->taskStorage->addTask($dummyTask);
// Now prepare a listener to be fired
Events::addListener(function (TaskModifyEvent $event){
$task = $event->getTask();
$this->assertEquals(Task::PENDING, $task->getStatus());
$task->setStatus(Task::RUNNING);
$event->updateTask($task);
return $event;
}, 'TaskModifyEvent', Priority::NORMAL);
// Now update the task
$this->assertEquals(Task::PENDING, $dummyTask->getStatus());
$this->taskStorage->modifyTask($dummyTask);
// And check whether dummyTask got modified
$this->assertEquals(Task::RUNNING, $dummyTask->getStatus());
// And check whether the TaskStorage has this updated version as well
$modifiedTask = $this->taskStorage->getTaskById($dummyTask->getId());
$this->assertEquals(Task::RUNNING, $modifiedTask->getStatus());
}
/**
* @depends testModifyTaskEvent
*/
public function testModifyTaskCancel()
{
// Prepare a dummy task
$dummyTask = new Task('testModifyTaskCancel', 'none');
$dummyTask->setStatus(Task::PENDING);
// Then add the Task
$this->taskStorage->addTask($dummyTask);
// Now prepare a listener to be fired
Events::addListener(function (TaskModifyEvent $event){
$event->setCancelled(true);
return $event;
}, 'TaskModifyEvent', Priority::NORMAL);
// Modify the task
$dummyTask->setStatus(Task::SUCCESS);
$this->assertFalse($this->taskStorage->modifyTask($dummyTask));
// And check that the task actually hasn't updated
$modifiedTask = $this->taskStorage->getTaskById($dummyTask->getId());
$this->assertEquals(Task::PENDING, $modifiedTask->getStatus());
}
/**
* @depends testGetTaskById
*/