Release of RC1 #7
|
@ -56,7 +56,7 @@ use FuzeWorks\Logger;
|
|||
class DependencyConstraint implements Constraint
|
||||
{
|
||||
|
||||
public $dependencies = [];
|
||||
protected $dependencies = [];
|
||||
|
||||
protected $delayTimes = 3;
|
||||
|
||||
|
@ -100,7 +100,6 @@ class DependencyConstraint implements Constraint
|
|||
// Get dependency
|
||||
$dependencyTask = $taskStorage->getTaskById($dependency);
|
||||
|
||||
|
||||
// If the dependency task is completed, ignore it and continue to next dependency
|
||||
if ($dependencyTask->getStatus() === Task::COMPLETED)
|
||||
continue;
|
||||
|
@ -146,6 +145,16 @@ class DependencyConstraint implements Constraint
|
|||
return time() + $this->delayTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of dependencies
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the tasks library, so that dependencies can get scanned later
|
||||
*
|
||||
|
|
|
@ -38,6 +38,15 @@ namespace FuzeWorks\Async;
|
|||
interface Handler
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets invoked upon being added to the Task
|
||||
*
|
||||
* @param Task $task
|
||||
* @return mixed
|
||||
* @throws TasksException
|
||||
*/
|
||||
public function init(Task $task);
|
||||
|
||||
/**
|
||||
* Retrieve the parent handler that will first handle this task, before this child Handler
|
||||
*
|
||||
|
@ -55,9 +64,9 @@ interface Handler
|
|||
/**
|
||||
* Import the parent output into the child
|
||||
*
|
||||
* @param mixed $input
|
||||
* @param string $input
|
||||
*/
|
||||
public function setParentInput($input): void;
|
||||
public function setParentInput(string $input): void;
|
||||
|
||||
/**
|
||||
* The handler method used to handle this task.
|
||||
|
@ -73,9 +82,9 @@ interface Handler
|
|||
/**
|
||||
* Any output generated by primaryHandler should be returned here.
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function getOutput();
|
||||
public function getOutput(): string;
|
||||
|
||||
/**
|
||||
* The handler method used after the primaryHandler if so requested
|
||||
|
@ -90,8 +99,8 @@ interface Handler
|
|||
/**
|
||||
* Any output generated by postHandler should be returned here
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function getPostOutput();
|
||||
public function getPostOutput(): string;
|
||||
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks Async Library
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 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 - 2020, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 1.0.0
|
||||
*
|
||||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Constraint;
|
||||
use FuzeWorks\Async\Constraint\DependencyConstraint;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Task;
|
||||
use FuzeWorks\Async\Tasks;
|
||||
use FuzeWorks\Async\TasksException;
|
||||
use FuzeWorks\Exception\FactoryException;
|
||||
use FuzeWorks\Exception\LibraryException;
|
||||
use FuzeWorks\Factory;
|
||||
use FuzeWorks\Libraries;
|
||||
|
||||
class DependentTaskHandler implements Handler
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Handler
|
||||
*/
|
||||
protected $parentHandler;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $dependencyList;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $delayTimes;
|
||||
|
||||
/**
|
||||
* DependentTaskHandler constructor.
|
||||
*
|
||||
* To add dependencies, the following array should be supplied:
|
||||
* $dependencyList: array(string 'taskId', string 'taskId', string 'taskId')
|
||||
*
|
||||
* @param array $dependencyList
|
||||
* @param int $delayTimes Time that a task should be delayed before retrying
|
||||
*/
|
||||
public function __construct(array $dependencyList = [], int $delayTimes = 3)
|
||||
{
|
||||
$this->dependencyList = $dependencyList;
|
||||
$this->delayTimes = $delayTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function init(Task $task)
|
||||
{
|
||||
if (!empty($this->dependencyList))
|
||||
$task->addConstraint(new DependencyConstraint($this->dependencyList, $this->delayTimes));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function primaryHandler(Task $task): bool
|
||||
{
|
||||
// First find all the dependencies
|
||||
try {
|
||||
$dependencies = $this->fetchDependencies($task);
|
||||
$this->output = json_encode($dependencies);
|
||||
return true;
|
||||
} catch (TasksException $e) {
|
||||
$this->output = 'Failed to fetch dependencies. TasksException: ' . $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput(): string
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function postHandler(Task $task)
|
||||
{
|
||||
// First find all the dependencies
|
||||
try {
|
||||
$dependencies = $this->fetchDependencies($task);
|
||||
$this->output = json_encode($dependencies);
|
||||
return true;
|
||||
} catch (TasksException $e) {
|
||||
$this->output = 'Failed to fetch dependencies. TasksException: ' . $e->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput(): string
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getParentHandler(): ?Handler
|
||||
{
|
||||
return $this->parentHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setParentHandler(Handler $parentHandler): void
|
||||
{
|
||||
$this->parentHandler = $parentHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setParentInput(string $input): void
|
||||
{
|
||||
// Parent output gets set at this handler's output.
|
||||
// Only if this class has something to intervene it will override the parent output
|
||||
// Which should be always... but alas.
|
||||
$this->output = $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Task $task
|
||||
* @return array
|
||||
* @throws TasksException
|
||||
*/
|
||||
protected function fetchDependencies(Task $task): array
|
||||
{
|
||||
// When it receives the task, all dependencies should already be handled
|
||||
// the primary handler will therefore connect with the DependencyConstraint and fetch dependencies
|
||||
$constraints = $task->getConstraints();
|
||||
|
||||
// First prepare a list of dependencies
|
||||
$dependencies = [];
|
||||
$dependencyConstraints = [];
|
||||
foreach ($constraints as $constraint) {
|
||||
if ($constraint instanceof Constraint)
|
||||
$dependencyConstraints[] = $constraint;
|
||||
}
|
||||
|
||||
// If no dependencies found, throw exception
|
||||
if (empty($dependencyConstraints))
|
||||
return $dependencies;
|
||||
|
||||
// Afterwards build a list of dependencies
|
||||
/** @var DependencyConstraint $constraint */
|
||||
foreach ($dependencyConstraints as $constraint) {
|
||||
foreach ($constraint->getDependencies() as $dependency) {
|
||||
if (!isset($dependencies[$dependency]))
|
||||
$dependencies[$dependency] = [];
|
||||
}
|
||||
}
|
||||
|
||||
// Now that all dependencies are determined, fetch all the output
|
||||
$tasks = $this->loadTasksLib();
|
||||
$taskStorage = $tasks->getTaskStorage();
|
||||
foreach ($dependencies as $dependency => $data)
|
||||
{
|
||||
// Fetch the task
|
||||
try {
|
||||
$dependencyTask = $taskStorage->getTaskById($dependency);
|
||||
|
||||
// Then fetch all output
|
||||
$dependencies[$dependency]['status'] = $dependencyTask->getStatus();
|
||||
$dependencies[$dependency]['output'] = $dependencyTask->getOutput();
|
||||
$dependencies[$dependency]['errors'] = $dependencyTask->getErrors();
|
||||
$dependencies[$dependency]['post'] = $dependencyTask->getPostOutput();
|
||||
$dependencies[$dependency]['postErrors'] = $dependencyTask->getPostErrors();
|
||||
} catch (TasksException $e) {
|
||||
$dependencies[$dependency]['status'] = Task::FAILED;
|
||||
$dependencies[$dependency]['output'] = null;
|
||||
$dependencies[$dependency]['errors'] = 'Task not found.';
|
||||
$dependencies[$dependency]['post'] = null;
|
||||
$dependencies[$dependency]['postErrors'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the tasks library, so that dependencies can get scanned later
|
||||
*
|
||||
* @return Tasks
|
||||
* @throws TasksException
|
||||
*/
|
||||
private function loadTasksLib(): Tasks
|
||||
{
|
||||
try {
|
||||
/** @var Libraries $libraries */
|
||||
$libraries = Factory::getInstance('libraries');
|
||||
|
||||
/** @var Tasks $tasks */
|
||||
$tasks = $libraries->get('async');
|
||||
|
||||
return $tasks;
|
||||
} catch (FactoryException | LibraryException $e) {
|
||||
throw new TasksException("Could not constrain task. Async library could not be loaded.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,9 +117,8 @@ class ParallelSuperVisor implements SuperVisor
|
|||
// RUNNING: check if task is still running. If not, set result based on output
|
||||
elseif ($task->getStatus() === Task::RUNNING)
|
||||
{
|
||||
// @todo Find a way to use the latest output
|
||||
$isRunning = $this->executor->getTaskRunning($task);
|
||||
$output = $this->taskStorage->readTaskOutput($task, 1);
|
||||
$output = $this->taskStorage->readTaskOutput($task);
|
||||
$hasOutput = !is_null($output);
|
||||
|
||||
// If nothing is found, the process has crashed and status PFAILED should be set
|
||||
|
@ -204,9 +203,8 @@ class ParallelSuperVisor implements SuperVisor
|
|||
// POST: when a task is currently running in it's postHandler
|
||||
elseif ($task->getStatus() === Task::POST)
|
||||
{
|
||||
// @todo Find a way to use the latest output
|
||||
$isRunning = $this->executor->getTaskRunning($task);
|
||||
$output = $this->taskStorage->readPostOutput($task, 1);
|
||||
$output = $this->taskStorage->readPostOutput($task);
|
||||
$hasOutput = !is_null($output);
|
||||
|
||||
// If a task is not running and has no output, an error has occurred
|
||||
|
|
|
@ -209,6 +209,9 @@ class Task
|
|||
throw new TasksException("Could not create Task. Provided arguments are not serializable.");
|
||||
|
||||
$this->arguments = $args;
|
||||
|
||||
// Init the handler
|
||||
$this->handler->init($this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -237,16 +237,19 @@ class DummyTaskStorage implements TaskStorage
|
|||
*/
|
||||
public function readTaskOutput(Task $task, int $attempt = 0): ?array
|
||||
{
|
||||
if ($attempt !== 0)
|
||||
if (!isset($this->taskOutput[$task->getId()]['task']))
|
||||
return null;
|
||||
|
||||
if ($attempt === 0)
|
||||
$attempt = count($this->taskOutput[$task->getId()]['task']);
|
||||
|
||||
if ($attempt === -1)
|
||||
return $this->taskOutput[$task->getId()]['task'];
|
||||
else
|
||||
{
|
||||
if (isset($this->taskOutput[$task->getId()]['task'][$attempt]))
|
||||
return $this->taskOutput[$task->getId()]['task'][$attempt];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->taskOutput[$task->getId()]['task']))
|
||||
return $this->taskOutput[$task->getId()]['task'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -256,16 +259,19 @@ class DummyTaskStorage implements TaskStorage
|
|||
*/
|
||||
public function readPostOutput(Task $task, int $attempt = 0): ?array
|
||||
{
|
||||
if ($attempt !== 0)
|
||||
if (!isset($this->taskOutput[$task->getId()]['post']))
|
||||
return null;
|
||||
|
||||
if ($attempt === 0)
|
||||
$attempt = count($this->taskOutput[$task->getId()]['post']);
|
||||
|
||||
if ($attempt === -1)
|
||||
return $this->taskOutput[$task->getId()]['post'];
|
||||
else
|
||||
{
|
||||
if (isset($this->taskOutput[$task->getId()]['post'][$attempt]))
|
||||
return $this->taskOutput[$task->getId()]['post'][$attempt];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->taskOutput[$task->getId()]['post']))
|
||||
return $this->taskOutput[$task->getId()]['post'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -271,19 +271,12 @@ class RedisTaskStorage implements TaskStorage
|
|||
// First get the task ID
|
||||
$taskId = $task->getId();
|
||||
|
||||
if ($attempt !== 0)
|
||||
{
|
||||
// Check if this output exists
|
||||
if (!$this->conn->hExists($this->key_prefix . $taskId, 'output' . $attempt))
|
||||
return null;
|
||||
// If a nothing in particular is requested, fetch the latest and select that as the attempt
|
||||
if ($attempt === 0)
|
||||
$attempt = $this->conn->hGet($this->key_prefix . $taskId, 'taskOutputAttempts');
|
||||
|
||||
// Load and convert the data
|
||||
$data = $this->conn->hGet($this->key_prefix . $taskId, 'output' . $attempt);
|
||||
$data = unserialize($data);
|
||||
|
||||
return ['output' => $data['output'], 'errors' => $data['errors'], 'statusCode' => $data['statusCode']];
|
||||
}
|
||||
else
|
||||
// If -1 is requested, fetch all
|
||||
if ($attempt === -1)
|
||||
{
|
||||
// Get amount of attempts
|
||||
$totalAttempts = $this->conn->hGet($this->key_prefix . $taskId, 'taskOutputAttempts');
|
||||
|
@ -303,9 +296,22 @@ class RedisTaskStorage implements TaskStorage
|
|||
|
||||
if (!empty($output))
|
||||
return $output;
|
||||
|
||||
return null;
|
||||
}
|
||||
// If a specific one is requested, fetch that one
|
||||
else
|
||||
{
|
||||
// Check if this output exists
|
||||
if (!$this->conn->hExists($this->key_prefix . $taskId, 'output' . $attempt))
|
||||
return null;
|
||||
|
||||
// Load and convert the data
|
||||
$data = $this->conn->hGet($this->key_prefix . $taskId, 'output' . $attempt);
|
||||
$data = unserialize($data);
|
||||
|
||||
return ['output' => $data['output'], 'errors' => $data['errors'], 'statusCode' => $data['statusCode']];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -316,19 +322,12 @@ class RedisTaskStorage implements TaskStorage
|
|||
// First get the task ID
|
||||
$taskId = $task->getId();
|
||||
|
||||
if ($attempt !== 0)
|
||||
{
|
||||
// Check if this output exists
|
||||
if (!$this->conn->hExists($this->key_prefix . $taskId, 'postOutput' . $attempt))
|
||||
return null;
|
||||
// If a nothing in particular is requested, fetch the latest and select that as the attempt
|
||||
if ($attempt === 0)
|
||||
$attempt = $this->conn->hGet($this->key_prefix . $taskId, 'taskPostAttempts');
|
||||
|
||||
// Load and convert the data
|
||||
$data = $this->conn->hGet($this->key_prefix . $taskId, 'postOutput' . $attempt);
|
||||
$data = unserialize($data);
|
||||
|
||||
return ['output' => $data['output'], 'errors' => $data['errors'], 'statusCode' => $data['statusCode']];
|
||||
}
|
||||
else
|
||||
// If -1 is requested, fetch all
|
||||
if ($attempt === -1)
|
||||
{
|
||||
// Get amount of attempts
|
||||
$totalAttempts = $this->conn->hGet($this->key_prefix . $taskId, 'taskPostAttempts');
|
||||
|
@ -348,9 +347,22 @@ class RedisTaskStorage implements TaskStorage
|
|||
|
||||
if (!empty($output))
|
||||
return $output;
|
||||
|
||||
return null;
|
||||
}
|
||||
// If a specific one is requested, fetch that one
|
||||
else
|
||||
{
|
||||
// Check if this output exists
|
||||
if (!$this->conn->hExists($this->key_prefix . $taskId, 'postOutput' . $attempt))
|
||||
return null;
|
||||
|
||||
// Load and convert the data
|
||||
$data = $this->conn->hGet($this->key_prefix . $taskId, 'postOutput' . $attempt);
|
||||
$data = unserialize($data);
|
||||
|
||||
return ['output' => $data['output'], 'errors' => $data['errors'], 'statusCode' => $data['statusCode']];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -94,11 +94,10 @@ class Tasks implements iLibrary
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $bootstrapFile
|
||||
* @return SuperVisor
|
||||
* @throws TasksException
|
||||
*/
|
||||
public function getSuperVisor(string $bootstrapFile): SuperVisor
|
||||
public function getSuperVisor(): SuperVisor
|
||||
{
|
||||
if (isset($this->supervisor))
|
||||
return $this->supervisor;
|
||||
|
@ -116,7 +115,7 @@ class Tasks implements iLibrary
|
|||
$parameters = isset($cfg[$type]['parameters']) && is_array($cfg[$type]['parameters']) ? $cfg[$type]['parameters'] : [];
|
||||
|
||||
// Then add the TaskStorage and Executor to the parameters
|
||||
array_unshift($parameters, $this->getTaskStorage(), $this->getExecutor($bootstrapFile));
|
||||
array_unshift($parameters, $this->getTaskStorage(), $this->getExecutor());
|
||||
|
||||
// If the type does not exist, throw an exception
|
||||
if (!class_exists($class, true))
|
||||
|
@ -183,11 +182,10 @@ class Tasks implements iLibrary
|
|||
/**
|
||||
* Fetch the Executor based on the configured type
|
||||
*
|
||||
* @param string $bootstrapFile
|
||||
* @return Executor
|
||||
* @throws TasksException
|
||||
*/
|
||||
protected function getExecutor(string $bootstrapFile): Executor
|
||||
protected function getExecutor(): Executor
|
||||
{
|
||||
if (isset($this->executor))
|
||||
return $this->executor;
|
||||
|
@ -209,7 +207,7 @@ class Tasks implements iLibrary
|
|||
throw new TasksException("Could not get Executor. Type of '$class' not found.");
|
||||
|
||||
// And load the Executor and test if everything is in order
|
||||
$object = new $class($bootstrapFile, $parameters);
|
||||
$object = new $class($parameters);
|
||||
if (!$object instanceof Executor)
|
||||
throw new TasksException("Could not get Executor. Type '$class' is not instanceof Executor.");
|
||||
|
||||
|
|
|
@ -0,0 +1,453 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks Async Library
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 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 - 2020, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 1.0.0
|
||||
*
|
||||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
use FuzeWorks\Async\Constraint\DependencyConstraint;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Handler\DependentTaskHandler;
|
||||
use FuzeWorks\Async\SuperVisor;
|
||||
use FuzeWorks\Async\Task;
|
||||
use FuzeWorks\Async\Tasks;
|
||||
use FuzeWorks\Async\TaskStorage;
|
||||
use FuzeWorks\Events;
|
||||
use FuzeWorks\Factory;
|
||||
use Mock\Handlers\ArgumentedHandler;
|
||||
use Mock\Handlers\EmptyHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DependenciesTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Tasks
|
||||
*/
|
||||
private $tasks;
|
||||
|
||||
/**
|
||||
* @var TaskStorage
|
||||
*/
|
||||
private $taskStorage;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
// Add TaskStorage
|
||||
/** @var Tasks $tasks */
|
||||
$this->tasks = Factory::getInstance('libraries')->get('async');
|
||||
$this->taskStorage = $this->tasks->getTaskStorage();
|
||||
$this->taskStorage->reset();
|
||||
|
||||
// Reset events
|
||||
Events::$listeners = [];
|
||||
}
|
||||
|
||||
/* ---------------------------------- Test the dependency constraint ------------------ */
|
||||
|
||||
public function testHasConstrainedDeps()
|
||||
{
|
||||
// Create the dependent tasks
|
||||
$depTask1 = new Task('depTask1', new EmptyHandler());
|
||||
$depTask2 = new Task('depTask2', new EmptyHandler());
|
||||
|
||||
// Write those dependencies to TaskStorage
|
||||
$this->taskStorage->addTask($depTask1);
|
||||
$this->taskStorage->addTask($depTask2);
|
||||
|
||||
// Create the constraint
|
||||
$constraint = new DependencyConstraint(['depTask1', 'depTask2']);
|
||||
|
||||
// And a dummyTask to accompany
|
||||
$dummyTask = new Task('dependentTask', new EmptyHandler());
|
||||
$dummyTask->addConstraint($constraint);
|
||||
|
||||
// Test that the constraint is the same
|
||||
$this->assertSame([$constraint], $dummyTask->getConstraints());
|
||||
|
||||
// And test the intervention
|
||||
$this->assertTrue($constraint->intervene($dummyTask));
|
||||
$this->assertEquals(Task::DELAYED, $constraint->blockCode());
|
||||
$this->assertEquals(time() + 3, $constraint->delayTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testHasConstrainedDeps
|
||||
*/
|
||||
public function testDelayTimes()
|
||||
{
|
||||
// Create the dependent tasks
|
||||
$depTask1 = new Task('depTask1', new EmptyHandler());
|
||||
$depTask2 = new Task('depTask2', new EmptyHandler());
|
||||
|
||||
// Write those dependencies to TaskStorage
|
||||
$this->taskStorage->addTask($depTask1);
|
||||
$this->taskStorage->addTask($depTask2);
|
||||
|
||||
// Create some useless dummy task
|
||||
$dummyTask = new Task('dependentTask', new EmptyHandler());
|
||||
|
||||
// Create the constraints
|
||||
// Default time
|
||||
$constraintDef = new DependencyConstraint(['depTask1', 'depTask2']);
|
||||
|
||||
// Modified time (30)
|
||||
$constraintMod1 = new DependencyConstraint(['depTask1', 'depTask2'], 30);
|
||||
|
||||
// And another (60)
|
||||
$constraintMod2 = new DependencyConstraint(['depTask1', 'depTask2'], 60);
|
||||
|
||||
// And intervene all of them
|
||||
$this->assertTrue($constraintDef->intervene($dummyTask));
|
||||
$this->assertTrue($constraintMod1->intervene($dummyTask));
|
||||
$this->assertTrue($constraintMod2->intervene($dummyTask));
|
||||
|
||||
// And check the results
|
||||
$this->assertEquals(Task::DELAYED, $constraintDef->blockCode());
|
||||
$this->assertEquals(Task::DELAYED, $constraintMod1->blockCode());
|
||||
$this->assertEquals(Task::DELAYED, $constraintMod2->blockCode());
|
||||
$this->assertEquals(time() + 3, $constraintDef->delayTime());
|
||||
$this->assertEquals(time() + 30, $constraintMod1->delayTime());
|
||||
$this->assertEquals(time() + 60, $constraintMod2->delayTime());
|
||||
}
|
||||
|
||||
public function testHasFailedDeps()
|
||||
{
|
||||
// Create the dependent tasks
|
||||
$depTask1 = new Task('depTask1', new EmptyHandler());
|
||||
$depTask2 = new Task('depTask2', new EmptyHandler());
|
||||
|
||||
// And set the first as completed, and second as failed
|
||||
$depTask1->setStatus(Task::COMPLETED);
|
||||
$depTask2->setStatus(Task::CANCELLED);
|
||||
|
||||
// Write those dependencies to TaskStorage
|
||||
$this->taskStorage->addTask($depTask1);
|
||||
$this->taskStorage->addTask($depTask2);
|
||||
|
||||
// Create the constraint
|
||||
$constraint = new DependencyConstraint(['depTask1', 'depTask2']);
|
||||
|
||||
// And a dummyTask to accompany
|
||||
$dummyTask = new Task('dependentTask', new EmptyHandler());
|
||||
$dummyTask->addConstraint($constraint);
|
||||
|
||||
// Test that the constraint is the same
|
||||
$this->assertSame([$constraint], $dummyTask->getConstraints());
|
||||
|
||||
// And test the intervention
|
||||
$this->assertTrue($constraint->intervene($dummyTask));
|
||||
$this->assertEquals(Task::CANCELLED, $constraint->blockCode());
|
||||
$this->assertEquals('Task cancelled due to failed dependency.', $dummyTask->getErrors());
|
||||
}
|
||||
|
||||
public function testHasCompletedDeps()
|
||||
{
|
||||
// Create the dependent tasks
|
||||
$depTask1 = new Task('depTask1', new EmptyHandler());
|
||||
$depTask2 = new Task('depTask2', new EmptyHandler());
|
||||
|
||||
// And set the first as completed, and second as failed
|
||||
$depTask1->setStatus(Task::COMPLETED);
|
||||
$depTask2->setStatus(Task::COMPLETED);
|
||||
|
||||
// Write those dependencies to TaskStorage
|
||||
$this->taskStorage->addTask($depTask1);
|
||||
$this->taskStorage->addTask($depTask2);
|
||||
|
||||
// Create the constraint
|
||||
$constraint = new DependencyConstraint(['depTask1', 'depTask2']);
|
||||
|
||||
// And a dummyTask to accompany
|
||||
$dummyTask = new Task('dependentTask', new EmptyHandler());
|
||||
$dummyTask->addConstraint($constraint);
|
||||
|
||||
// Test that the constraint is the same
|
||||
$this->assertSame([$constraint], $dummyTask->getConstraints());
|
||||
|
||||
// And test the intervention
|
||||
$this->assertFalse($constraint->intervene($dummyTask));
|
||||
}
|
||||
|
||||
public function testGetDependencies()
|
||||
{
|
||||
$constraint = new DependencyConstraint(['someTask1', 'someTask2']);
|
||||
$this->assertEquals(['someTask1', 'someTask2'], $constraint->getDependencies());
|
||||
}
|
||||
|
||||
/* ---------------------------------- Test the dependent task handler ----------------- */
|
||||
|
||||
public function testAddedDependencies()
|
||||
{
|
||||
$handler = new DependentTaskHandler(['someTask1', 'someTask2']);
|
||||
$dummyTask = new Task('someTask', $handler);
|
||||
|
||||
// Check that the constraints match expectations
|
||||
/** @var DependencyConstraint[] $constraints */
|
||||
$constraints = $dummyTask->getConstraints();
|
||||
$this->assertInstanceOf(DependencyConstraint::class, $constraints[0]);
|
||||
|
||||
// And that the dependencies match
|
||||
$this->assertEquals(['someTask1', 'someTask2'], $constraints[0]->getDependencies());
|
||||
}
|
||||
|
||||
public function testPassingOutput()
|
||||
{
|
||||
// Create the dependent tasks
|
||||
$depTask1 = new Task('someTask', new EmptyHandler());
|
||||
$depTask2 = new Task('someTask2', new EmptyHandler());
|
||||
|
||||
// Give the dependencies some output
|
||||
$depTask1->setOutput('First Output', '');
|
||||
$depTask2->setOutput('Second Output', '');
|
||||
|
||||
// Write those to TaskStorage
|
||||
$this->taskStorage->addTask($depTask1);
|
||||
$this->taskStorage->addTask($depTask2);
|
||||
|
||||
// Create the task
|
||||
$handler = new DependentTaskHandler(['someTask', 'someTask2']);
|
||||
|
||||
// Create a dummy Task
|
||||
$dummyTask = new Task('someTask3', $handler);
|
||||
|
||||
// Assert that all is well
|
||||
$this->assertTrue($handler->primaryHandler($dummyTask));
|
||||
|
||||
// And test the handler's output
|
||||
$this->assertEquals(json_encode([
|
||||
'someTask' => [
|
||||
'status' => Task::PENDING,
|
||||
'output' => 'First Output',
|
||||
'errors' => '',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
],
|
||||
'someTask2' => [
|
||||
'status' => Task::PENDING,
|
||||
'output' => 'Second Output',
|
||||
'errors' => '',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
]
|
||||
]), $handler->getOutput());
|
||||
|
||||
// And test the post handler
|
||||
$this->assertTrue($handler->postHandler($dummyTask));
|
||||
$this->assertEquals(json_encode([
|
||||
'someTask' => [
|
||||
'status' => Task::PENDING,
|
||||
'output' => 'First Output',
|
||||
'errors' => '',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
],
|
||||
'someTask2' => [
|
||||
'status' => Task::PENDING,
|
||||
'output' => 'Second Output',
|
||||
'errors' => '',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
]
|
||||
]), $handler->getPostOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPassingOutput
|
||||
*/
|
||||
public function testMissingDependency()
|
||||
{
|
||||
// Create the task
|
||||
$handler = new DependentTaskHandler(['someTask']);
|
||||
|
||||
// Create a dummy Task
|
||||
$dummyTask = new Task('someTask2', $handler);
|
||||
|
||||
// Assert that all is well
|
||||
$this->assertTrue($handler->primaryHandler($dummyTask));
|
||||
|
||||
// And test the handler's output
|
||||
$this->assertEquals(json_encode([
|
||||
'someTask' => [
|
||||
'status' => Task::FAILED,
|
||||
'output' => null,
|
||||
'errors' => 'Task not found.',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
],
|
||||
]), $handler->getOutput());
|
||||
|
||||
// And test the post handler
|
||||
$this->assertTrue($handler->postHandler($dummyTask));
|
||||
$this->assertEquals(json_encode([
|
||||
'someTask' => [
|
||||
'status' => Task::FAILED,
|
||||
'output' => null,
|
||||
'errors' => 'Task not found.',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
],
|
||||
]), $handler->getPostOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testPassingOutput
|
||||
*/
|
||||
public function testNoDepedencies()
|
||||
{
|
||||
// Create the task
|
||||
$handler = new DependentTaskHandler([]);
|
||||
|
||||
// Create a dummy Task
|
||||
$dummyTask = new Task('someTask', $handler);
|
||||
|
||||
// Assert that all is well
|
||||
$this->assertTrue($handler->primaryHandler($dummyTask));
|
||||
$this->assertEquals(json_encode([]), $handler->getOutput());
|
||||
|
||||
// And test the post handler
|
||||
$this->assertTrue($handler->postHandler($dummyTask));
|
||||
$this->assertEquals(json_encode([]), $handler->getPostOutput());
|
||||
}
|
||||
|
||||
public function testParentHandler()
|
||||
{
|
||||
// Test pass output
|
||||
$handler = new DependentTaskHandler([]);
|
||||
$handler->setParentInput('Passed Input');
|
||||
$this->assertEquals('Passed Input', $handler->getOutput());
|
||||
|
||||
// Test passing a handler
|
||||
$handler = new DependentTaskHandler([]);
|
||||
$parentHandler = $this->createMock(Handler::class);
|
||||
$handler->setParentHandler($parentHandler);
|
||||
$this->assertSame($parentHandler, $handler->getParentHandler());
|
||||
}
|
||||
|
||||
public function testPassDependencyOutput()
|
||||
{
|
||||
// Build all systems for this test
|
||||
$superVisor = $this->tasks->getSuperVisor();
|
||||
|
||||
// Create the dependency
|
||||
$dependency = new Task('dependency', new ArgumentedHandler(0, 'Prepared Output'));
|
||||
|
||||
// Write the task to TaskStorage
|
||||
$this->taskStorage->addTask($dependency);
|
||||
|
||||
// Now create the dependent task
|
||||
$dependent = new Task('dependent', new DependentTaskHandler(['dependency'], 2));
|
||||
|
||||
// And write that task to TaskStorage
|
||||
$this->taskStorage->addTask($dependent);
|
||||
|
||||
// Now we make the SuperVisor cycle, to start the dependency and set the dependent to WAIT
|
||||
$this->assertEquals(SuperVisor::RUNNING, $superVisor->cycle());
|
||||
|
||||
// Assert that everything is running
|
||||
$this->assertEquals(Task::RUNNING,
|
||||
$this->taskStorage->getTaskById($dependency->getId())->getStatus()
|
||||
);
|
||||
$this->assertEquals(Task::DELAYED,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
|
||||
// Give the task some time to finish
|
||||
usleep(500000);
|
||||
|
||||
// And re-run the SuperVisor
|
||||
$this->assertEquals(SuperVisor::RUNNING, $superVisor->cycle());
|
||||
|
||||
// Now check the tasks again. Dependency should be finished and have output,
|
||||
// whereas dependent should still be delayed
|
||||
$this->assertEquals(Task::SUCCESS,
|
||||
$this->taskStorage->getTaskById($dependency->getId())->getStatus()
|
||||
);
|
||||
$this->assertEquals(Task::DELAYED,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
|
||||
// Cycle again and see the dependency be completed, and dependent still delayed
|
||||
$this->assertEquals(SuperVisor::RUNNING, $superVisor->cycle());
|
||||
$this->assertEquals(Task::COMPLETED,
|
||||
$this->taskStorage->getTaskById($dependency->getId())->getStatus()
|
||||
);
|
||||
$this->assertEquals(Task::DELAYED,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
|
||||
// Also check that output is correct
|
||||
$this->assertEquals('Prepared Output',
|
||||
$this->taskStorage->getTaskById($dependency->getId())->getOutput()
|
||||
);
|
||||
|
||||
// Now wait long enough for the delay to be finished
|
||||
usleep(2500000);
|
||||
|
||||
// Now cycle again, and expect the task to be pending
|
||||
$this->assertEquals(SuperVisor::RUNNING, $superVisor->cycle());
|
||||
$this->assertEquals(Task::PENDING,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
|
||||
// Cycle again and expect it to be running
|
||||
$this->assertEquals(SuperVisor::RUNNING, $superVisor->cycle());
|
||||
$this->assertEquals(Task::RUNNING,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
|
||||
// Give the task some time to finish
|
||||
usleep(500000);
|
||||
|
||||
// And cycle again and expect the task to have succeeded
|
||||
$this->assertEquals(SuperVisor::RUNNING, $superVisor->cycle());
|
||||
$this->assertEquals(Task::SUCCESS,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
|
||||
// Cycle again and expect the task to have completed, and test its output
|
||||
$this->assertEquals(SuperVisor::FINISHED, $superVisor->cycle());
|
||||
$this->assertEquals(Task::COMPLETED,
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getStatus()
|
||||
);
|
||||
$this->assertEquals(
|
||||
json_encode(['dependency' => [
|
||||
'status' => Task::COMPLETED,
|
||||
'output' => 'Prepared Output',
|
||||
'errors' => '',
|
||||
'post' => null,
|
||||
'postErrors' => null
|
||||
]]),
|
||||
$this->taskStorage->getTaskById($dependent->getId())->getOutput()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -338,11 +338,14 @@ class TaskStorageTest extends TestCase
|
|||
$this->assertTrue($this->taskStorage->writeTaskOutput($dummyTask, 'output2', 'errors2', 0));
|
||||
|
||||
// Then try to read all the output
|
||||
$output = $this->taskStorage->readTaskOutput($dummyTask);
|
||||
$output = $this->taskStorage->readTaskOutput($dummyTask, -1);
|
||||
$this->assertEquals([
|
||||
['output' => 'output1', 'errors' => 'errors1', 'statusCode' => 0],
|
||||
['output' => 'output2', 'errors' => 'errors2', 'statusCode' => 0]
|
||||
], $output);
|
||||
|
||||
// Then try and read the latest
|
||||
$this->assertEquals(['output' => 'output2', 'errors' => 'errors2', 'statusCode' => 0], $this->taskStorage->readTaskOutput($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -392,11 +395,16 @@ class TaskStorageTest extends TestCase
|
|||
|
||||
// Attempt to load the default output
|
||||
$output = $this->taskStorage->readTaskOutput($dummyTask);
|
||||
$this->assertEquals('output2', $output['output']);
|
||||
$this->assertEquals('errors2', $output['errors']);
|
||||
$this->assertEquals(102, $output['statusCode']);
|
||||
|
||||
// And to load all
|
||||
$this->assertEquals([
|
||||
['output' => 'output0', 'errors' => 'errors0', 'statusCode' => 100],
|
||||
['output' => 'output1', 'errors' => 'errors1', 'statusCode' => 101],
|
||||
['output' => 'output2', 'errors' => 'errors2', 'statusCode' => 102]
|
||||
], $output);
|
||||
], $this->taskStorage->readTaskOutput($dummyTask, -1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -446,11 +454,13 @@ class TaskStorageTest extends TestCase
|
|||
$this->assertTrue($this->taskStorage->writePostOutput($dummyTask, 'output2', 'errors2', 0));
|
||||
|
||||
// Then try to read all the output
|
||||
$output = $this->taskStorage->readPostOutput($dummyTask);
|
||||
$output = $this->taskStorage->readPostOutput($dummyTask, -1);
|
||||
$this->assertEquals([
|
||||
['output' => 'output1', 'errors' => 'errors1', 'statusCode' => 0],
|
||||
['output' => 'output2', 'errors' => 'errors2', 'statusCode' => 0]
|
||||
], $output);
|
||||
|
||||
$this->assertEquals(['output' => 'output2', 'errors' => 'errors2', 'statusCode' => 0], $this->taskStorage->readPostOutput($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -488,11 +498,16 @@ class TaskStorageTest extends TestCase
|
|||
|
||||
// Attempt to load the default output
|
||||
$output = $this->taskStorage->readPostOutput($dummyTask);
|
||||
$this->assertEquals('output2', $output['output']);
|
||||
$this->assertEquals('errors2', $output['errors']);
|
||||
$this->assertEquals(102, $output['statusCode']);
|
||||
|
||||
// And to load all
|
||||
$this->assertEquals([
|
||||
['output' => 'output0', 'errors' => 'errors0', 'statusCode' => 100],
|
||||
['output' => 'output1', 'errors' => 'errors1', 'statusCode' => 101],
|
||||
['output' => 'output2', 'errors' => 'errors2', 'statusCode' => 102]
|
||||
], $output);
|
||||
], $this->taskStorage->readPostOutput($dummyTask, -1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
use FuzeWorks\Async\Constraint;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Task;
|
||||
use FuzeWorks\Async\TasksException;
|
||||
use Mock\Handlers\EmptyHandler;
|
||||
|
@ -111,6 +112,19 @@ class TaskTest extends TestCase
|
|||
$this->assertEquals([$stub], $dummyTask->getConstraints());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testBaseVariables
|
||||
*/
|
||||
public function testInitHandler()
|
||||
{
|
||||
$mockHandler = $this->createMock(Handler::class);
|
||||
$mockHandler->expects($this->once())->method('init')
|
||||
->with($this->callback(function($subject){return $subject instanceof Task;}));
|
||||
|
||||
// Then create a class
|
||||
new Task('testInitHandler', $mockHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testBaseVariables
|
||||
*/
|
||||
|
|
|
@ -83,8 +83,9 @@ return array(
|
|||
'ShellExecutor' => [
|
||||
'parameters' => [
|
||||
'workerFile' => Core::getEnv('EXECUTOR_SHELL_WORKER',
|
||||
dirname(__FILE__) . DS . 'bin' . DS . 'worker'),
|
||||
'bootstrapFile' => Core::getEnv('EXECUTOR_SHELL_BOOTSTRAP', 'unknown')
|
||||
dirname(__FILE__, 2) . DS . 'bin' . DS . 'worker'),
|
||||
'bootstrapFile' => Core::getEnv('EXECUTOR_SHELL_BOOTSTRAP',
|
||||
dirname(__FILE__) . DS . 'bootstrap.php')
|
||||
]
|
||||
]
|
||||
]
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
namespace Mock\Handlers;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Task;
|
||||
use FuzeWorks\Async\TasksException;
|
||||
|
||||
class ArgumentedHandler implements Handler
|
||||
{
|
||||
|
@ -50,6 +51,13 @@ class ArgumentedHandler implements Handler
|
|||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function init(Task $task)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -62,7 +70,7 @@ class ArgumentedHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput()
|
||||
public function getOutput(): string
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
@ -79,7 +87,7 @@ class ArgumentedHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
public function getPostOutput(): string
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
@ -95,7 +103,7 @@ class ArgumentedHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setParentInput($input): void
|
||||
public function setParentInput(string $input): void
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,13 @@ use FuzeWorks\Async\Task;
|
|||
class EmptyHandler implements Handler
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function init(Task $task)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -52,7 +59,7 @@ class EmptyHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput()
|
||||
public function getOutput(): string
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,7 +73,7 @@ class EmptyHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
public function getPostOutput(): string
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -81,7 +88,7 @@ class EmptyHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setParentInput($input): void
|
||||
public function setParentInput(string $input): void
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,13 @@ use FuzeWorks\Async\Task;
|
|||
class TestStartAndReadTasksHandler implements Handler
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function init(Task $task)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -53,7 +60,7 @@ class TestStartAndReadTasksHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput()
|
||||
public function getOutput(): string
|
||||
{
|
||||
return "Valid Output";
|
||||
}
|
||||
|
@ -69,7 +76,7 @@ class TestStartAndReadTasksHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
public function getPostOutput(): string
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -85,7 +92,7 @@ class TestStartAndReadTasksHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setParentInput($input): void
|
||||
public function setParentInput(string $input): void
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,13 @@ use FuzeWorks\Async\Task;
|
|||
class TestStopTaskHandler implements Handler
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function init(Task $task)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -53,7 +60,7 @@ class TestStopTaskHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput()
|
||||
public function getOutput(): string
|
||||
{
|
||||
return "Valid Output";
|
||||
}
|
||||
|
@ -68,7 +75,7 @@ class TestStopTaskHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
public function getPostOutput(): string
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -83,7 +90,7 @@ class TestStopTaskHandler implements Handler
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setParentInput($input): void
|
||||
public function setParentInput(string $input): void
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,11 @@ use FuzeWorks\Events;
|
|||
use Mock\Handlers\ArgumentedHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class ParallelSuperVisorTest
|
||||
*
|
||||
* @todo Add test that latest output is added to Task, and not just 'any' output
|
||||
*/
|
||||
class ParallelSuperVisorTest extends TestCase
|
||||
{
|
||||
|
||||
|
|
Loading…
Reference in New Issue