Many changes.
This commit is contained in:
parent
dc02826079
commit
13ad2b0ef8
15 changed files with 148 additions and 178 deletions
3
.idea/scopes/TamerLib.xml
generated
Normal file
3
.idea/scopes/TamerLib.xml
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<scope name="TamerLib" pattern="file[tamer]:src/TamerLib//*" />
|
||||
</component>
|
3
.idea/scopes/Test_Directory.xml
generated
Normal file
3
.idea/scopes/Test_Directory.xml
generated
Normal file
|
@ -0,0 +1,3 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<scope name="Test Directory" pattern="file[tamer]:tests//*" />
|
||||
</component>
|
|
@ -1,17 +1,21 @@
|
|||
<?php
|
||||
<?php /** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace TamerLib\Classes;
|
||||
namespace TamerLib\Classes;
|
||||
|
||||
use Exception;
|
||||
use Opis\Closure\SerializableClosure;
|
||||
use Symfony\Component\Process\Process;
|
||||
use TamerLib\Enums\TamerMode;
|
||||
use TamerLib\Exceptions\NoAvailablePortException;
|
||||
use TamerLib\tm;
|
||||
use Throwable;
|
||||
use function serialize;
|
||||
use function unserialize;
|
||||
use const PHP_MAJOR_VERSION;
|
||||
|
||||
class Utilities
|
||||
{
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private static $pid;
|
||||
|
||||
/**
|
||||
* Attempts to find an available port in the given range. If no port is available,
|
||||
* a NoAvailablePortException is thrown.
|
||||
|
@ -87,32 +91,47 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Serialize
|
||||
* Returns the current name of the process for logging purposes.
|
||||
* If the current mode is worker, the process name will be
|
||||
* net.nosial.tamerlib:<pid>. Otherwise, the process name will be
|
||||
* net.nosial.tamerlib.
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return string
|
||||
*/
|
||||
public static function serialize($data)
|
||||
public static function getName(): string
|
||||
{
|
||||
SerializableClosure::enterContext();
|
||||
SerializableClosure::wrapClosures($data);
|
||||
$data = serialize($data);
|
||||
SerializableClosure::exitContext();
|
||||
return $data;
|
||||
if(tm::getMode() === TamerMode::WORKER)
|
||||
{
|
||||
if(self::$pid === null)
|
||||
{
|
||||
// Very unlikely that getmypid() will return 0.
|
||||
/** @noinspection ProperNullCoalescingOperatorUsageInspection */
|
||||
self::$pid = getmypid() ?? (string)null;
|
||||
}
|
||||
|
||||
return sprintf('net.nosial.tamerlib:%s', self::$pid);
|
||||
}
|
||||
|
||||
return 'net.nosial.tamerlib';
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserialize
|
||||
* Returns the latest output from the given process either from the output or error output.
|
||||
* If no output is available, an empty string is returned.
|
||||
*
|
||||
* @param string $data
|
||||
* @param array|null $options
|
||||
* @return mixed
|
||||
* @param Process $process
|
||||
* @return string
|
||||
*/
|
||||
public static function unserialize($data, array $options = null)
|
||||
public static function getLatestOutput(Process $process): string
|
||||
{
|
||||
SerializableClosure::enterContext();
|
||||
$data = $options === null || PHP_MAJOR_VERSION < 7 ? unserialize($data) : unserialize($data, $options);
|
||||
SerializableClosure::unwrapClosures($data);
|
||||
SerializableClosure::exitContext();
|
||||
return $data;
|
||||
$output = $process->getIncrementalOutput();
|
||||
$error_output = $process->getIncrementalErrorOutput();
|
||||
|
||||
if (!empty($error_output))
|
||||
{
|
||||
$output .= PHP_EOL . $error_output;
|
||||
}
|
||||
|
||||
return empty($output) ? (string)null : $output;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
use TamerLib\Objects\ServerConfiguration;
|
||||
use TamerLib\Objects\WorkerConfiguration;
|
||||
use TamerLib\Objects\WorkerInstance;
|
||||
use TamerLib\tm;
|
||||
|
||||
class WorkerSupervisor
|
||||
{
|
||||
|
|
|
@ -1,28 +1,9 @@
|
|||
<?PHP
|
||||
<?PHP /** @noinspection PhpFullyQualifiedNameUsageInspection */
|
||||
/** @noinspection PhpFullyQualifiedNameUsageInspection */
|
||||
/** @noinspection PhpFullyQualifiedNameUsageInspection */
|
||||
|
||||
require 'ncc';
|
||||
require 'ncc';
|
||||
import('net.nosial.tamerlib');
|
||||
|
||||
\TamerLib\tm::initalize(\TamerLib\Enums\TamerMode::WORKER);
|
||||
|
||||
$function = function($input)
|
||||
{
|
||||
var_dump($input);
|
||||
sleep($input);
|
||||
return 5 + $input;
|
||||
};
|
||||
|
||||
\TamerLib\tm::addFunction('test', $function);
|
||||
|
||||
while(true)
|
||||
{
|
||||
try
|
||||
{
|
||||
\TamerLib\tm::run();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
var_dump($e);
|
||||
//\LogLib\Log::error('net.nosial.tamerlib', $e->getMessage(), $e);
|
||||
}
|
||||
}
|
||||
\TamerLib\tm::initialize(\TamerLib\Enums\TamerMode::WORKER);
|
||||
\TamerLib\tm::run();
|
|
@ -4,20 +4,27 @@
|
|||
|
||||
final class JobStatus
|
||||
{
|
||||
/**
|
||||
* The Job is waiting to be picked up by a worker.
|
||||
* Processing Mode
|
||||
*/
|
||||
public const WAITING = 10;
|
||||
|
||||
/**
|
||||
* The Job is currently being processed by a worker.
|
||||
* Processing Mode
|
||||
*/
|
||||
public const PROCESSING = 20;
|
||||
|
||||
/**
|
||||
* The Job has been finished by a worker.
|
||||
* Finished Mode
|
||||
*/
|
||||
public const FINISHED = 30;
|
||||
|
||||
/**
|
||||
* The Job has failed to be processed by a worker.
|
||||
* Finished Mode
|
||||
*/
|
||||
public const FAILED = 40;
|
||||
public const REJECTED = 50;
|
||||
|
||||
public const PROCESSING_STATES = [
|
||||
self::WAITING,
|
||||
self::PROCESSING,
|
||||
self::REJECTED // This is a special case, as the job gets pushed back into the queue for reprocessing.
|
||||
];
|
||||
|
||||
public const FINISHED_STATES = [
|
||||
self::FINISHED,
|
||||
self::FAILED,
|
||||
];
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
public const WORKER = 'worker';
|
||||
|
||||
public const NONE = 'none';
|
||||
|
||||
public const ALL = [
|
||||
self::CLIENT,
|
||||
self::WORKER
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
|
||||
namespace TamerLib\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class JobManagerException extends \Exception
|
||||
class JobManagerException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use Exception;
|
||||
use TamerLib\Enums\JobStatus;
|
||||
use TamerLib\Enums\JobType;
|
||||
|
||||
class JobPacket
|
||||
{
|
||||
|
@ -20,11 +19,6 @@
|
|||
*/
|
||||
private $channel;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $job_type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
@ -60,11 +54,6 @@
|
|||
*/
|
||||
private $return_channel;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $created_at;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws Exception
|
||||
|
@ -73,7 +62,6 @@
|
|||
{
|
||||
$this->id = $data['id'] ?? random_int(1000000000, 9999999999);
|
||||
$this->channel = $data['channel'] ?? 0;
|
||||
$this->job_type = $data['job_type'] ?? JobType::CLOSURE;
|
||||
$this->status = $data['status'] ?? JobStatus::WAITING;
|
||||
$this->worker_id = $data['worker_id'] ?? null;
|
||||
$this->parameters = $data['parameters'] ?? null;
|
||||
|
@ -81,7 +69,6 @@
|
|||
$this->return_value = $data['return_value'] ?? null;
|
||||
$this->exception = $data['exception'] ?? null;
|
||||
$this->return_channel = $data['return_channel'] ?? null;
|
||||
$this->created_at = $data['created_at'] ?? time();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,23 +81,6 @@
|
|||
return (int)$this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the JobPacket, if null is passed, a random ID will be generated
|
||||
*
|
||||
* @param int|null $id
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setId(?int $id=null): void
|
||||
{
|
||||
if($id !== null)
|
||||
{
|
||||
$this->id = random_int(1000000000, 9999999999);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->id = (int)$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the channel the JobPacket is assigned to
|
||||
*
|
||||
|
@ -140,24 +110,6 @@
|
|||
$this->channel = (int)$channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Job Type of the JobPacket
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getJobType(): int
|
||||
{
|
||||
return (int)$this->job_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $job_type
|
||||
*/
|
||||
public function setJobType(int $job_type): void
|
||||
{
|
||||
$this->job_type = $job_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
|
@ -166,14 +118,6 @@
|
|||
return (int)$this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $status
|
||||
*/
|
||||
public function setStatus(int $status): void
|
||||
{
|
||||
$this->status = (int)$status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
|
@ -182,14 +126,6 @@
|
|||
return (string)$this->worker_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $worker_id
|
||||
*/
|
||||
public function setWorkerId(?string $worker_id): void
|
||||
{
|
||||
$this->worker_id = $worker_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
|
@ -230,14 +166,6 @@
|
|||
return $this->return_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null $return_value
|
||||
*/
|
||||
public function setReturnValue(mixed $return_value): void
|
||||
{
|
||||
$this->return_value = $return_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
|
@ -246,14 +174,6 @@
|
|||
return $this->exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $exception
|
||||
*/
|
||||
public function setException(?string $exception): void
|
||||
{
|
||||
$this->exception = $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
|
@ -271,22 +191,6 @@
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int|mixed
|
||||
*/
|
||||
public function getCreatedAt(): mixed
|
||||
{
|
||||
return $this->created_at;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|mixed $created_at
|
||||
*/
|
||||
public function setCreatedAt(mixed $created_at): void
|
||||
{
|
||||
$this->created_at = $created_at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the JobPacket
|
||||
*
|
||||
|
@ -297,7 +201,6 @@
|
|||
return [
|
||||
'id' => $this->getId(),
|
||||
'channel' => $this->getChannel(),
|
||||
'job_type' => $this->getJobType(),
|
||||
'status' => $this->getStatus(),
|
||||
'worker_id' => $this->getWorkerId(),
|
||||
'parameters' => $this->getParameters(),
|
||||
|
@ -305,7 +208,6 @@
|
|||
'return_value' => $this->getReturnValue(),
|
||||
'exception' => $this->getException(),
|
||||
'return_channel' => $this->getReturnChannel(),
|
||||
'created_at' => $this->getCreatedAt()
|
||||
];
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
use LogLib\Log;
|
||||
use RuntimeException;
|
||||
use TamerLib\Classes\Utilities;
|
||||
use TamerLib\Exceptions\NoAvailablePortException;
|
||||
|
||||
class ServerConfiguration
|
||||
{
|
||||
|
@ -55,7 +54,7 @@
|
|||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Log::warning(Utilities::getName(), 'No available port found. Using random port.');
|
||||
Log::warning(Utilities::getName(), 'No available port found. Using random port.', $e);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -89,14 +89,6 @@
|
|||
return $this->worker_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $worker_id
|
||||
*/
|
||||
public function setWorkerId(string $worker_id): void
|
||||
{
|
||||
$this->worker_id = $worker_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new ServerException('Failed to initialize the server.', 0, $e);
|
||||
throw new ServerException('Failed to initialize the server.', $e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -228,7 +228,7 @@
|
|||
*/
|
||||
public static function monitor(int $timeout=0): void
|
||||
{
|
||||
if($timeout > 0)
|
||||
if($timeout > 0 || $timeout === -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -293,6 +293,7 @@
|
|||
self::$supervisor->spawnWorker($path, $count, $channel);
|
||||
}
|
||||
|
||||
var_dump('monitoring');
|
||||
self::monitor(-1);
|
||||
}
|
||||
|
||||
|
@ -302,9 +303,9 @@
|
|||
* @param string $function
|
||||
* @param array $arguments
|
||||
* @param int $channel
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public static function do(string $function, array $arguments, int $channel=0): mixed
|
||||
public static function do(string $function, array $arguments, int $channel=0): int
|
||||
{
|
||||
if(self::$mode !== TamerMode::CLIENT)
|
||||
{
|
||||
|
@ -558,11 +559,11 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Invokes the call() function, returns the Job ID.
|
||||
* Invokes the do() function, returns the Job ID.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public static function __callStatic(string $name, array $arguments)
|
||||
{
|
||||
|
|
59
tests/ExampleClass.php
Normal file
59
tests/ExampleClass.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
class ExampleClass
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* ExampleClass constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in the data array
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function set(string $key, mixed $value): void
|
||||
{
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from the data array
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function get(string $key): mixed
|
||||
{
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a key exists in the data array
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ use TamerLib\tm;
|
|||
|
||||
// Start as client mode, if no configuration is passed on then
|
||||
// Tamer will spawn its own Redis server and use it.
|
||||
tm::initalize(TamerMode::CLIENT);
|
||||
tm::initialize(TamerMode::CLIENT);
|
||||
tm::createWorker(20, __DIR__ . DIRECTORY_SEPARATOR . 'worker.php');
|
||||
|
||||
$total_sleep = 0;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import('net.nosial.tamerlib');
|
||||
|
||||
// Initialize as a worker, will fail if the process is executed directly
|
||||
\TamerLib\tm::initalize(\TamerLib\Enums\TamerMode::WORKER);
|
||||
\TamerLib\tm::initialize(\TamerLib\Enums\TamerMode::WORKER);
|
||||
|
||||
// Callback Examples
|
||||
\TamerLib\tm::addFunction('sleep', function($sleep_time){
|
||||
|
|
Loading…
Add table
Reference in a new issue