改名
This commit is contained in:
+28
-3
@@ -62,6 +62,20 @@ class Server extends Application
|
||||
|
||||
public $daemon = 0;
|
||||
|
||||
|
||||
private $process = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $process
|
||||
*/
|
||||
public function addProcess($name, $process)
|
||||
{
|
||||
$this->process[$name] = $process;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $configs
|
||||
* @return Http|Packet|Receive|Websocket
|
||||
@@ -172,7 +186,6 @@ class Server extends Application
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
@@ -180,11 +193,23 @@ class Server extends Application
|
||||
public function onProcessListener()
|
||||
{
|
||||
$processes = Config::get('processes');
|
||||
if (!empty($processes) && is_array($processes)) {
|
||||
return $this->deliveryProcess(merge($processes, $this->process));
|
||||
}
|
||||
return $this->deliveryProcess($this->process);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $processes
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deliveryProcess($processes)
|
||||
{
|
||||
$application = Snowflake::app();
|
||||
if (empty($processes) || !is_array($processes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$application = Snowflake::app();
|
||||
foreach ($processes as $name => $process) {
|
||||
$this->debug(sprintf('Process %s', $process));
|
||||
if (!is_string($process)) {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue\Abstracts;
|
||||
|
||||
|
||||
use Snowflake\Process\Process;
|
||||
|
||||
/**
|
||||
* Class AbstractsQueue
|
||||
* @package Queue\Abstracts
|
||||
*/
|
||||
abstract class AbstractsQueue extends Process
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue\Abstracts;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Queue\Consumer;
|
||||
use Snowflake\Abstracts\Component;
|
||||
use Snowflake\Exception\ComponentException;
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
/**
|
||||
* Class Queue
|
||||
* @package Queue\Abstracts
|
||||
*/
|
||||
abstract class Queue extends Component implements Relyon
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param Consumer $consumer
|
||||
* @param int $score
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function push(string $key, Consumer $consumer, $score = 0)
|
||||
{
|
||||
$redis = Snowflake::app()->getRedis();
|
||||
$serialize = serialize($consumer);
|
||||
if (!$redis->lock($hash = md5($serialize))) {
|
||||
return false;
|
||||
}
|
||||
$isExists = $redis->zRevRank($key, $serialize);
|
||||
if ($isExists !== null) {
|
||||
$redis->zAdd($key, $score, $serialize);
|
||||
}
|
||||
return $redis->unlink($hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param Consumer $consumer
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function pop($key, Consumer $consumer)
|
||||
{
|
||||
$serialize = serialize($consumer);
|
||||
$redis = Snowflake::app()->getRedis();
|
||||
if (!$redis->lock($hash = md5($serialize))) {
|
||||
return false;
|
||||
}
|
||||
$isExists = $redis->zRevRank($key, $serialize);
|
||||
if ($isExists === null) {
|
||||
return $redis->unlink($hash);
|
||||
}
|
||||
$redis->zRem($key, $serialize);
|
||||
return $redis->unlink($hash);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue\Abstracts;
|
||||
|
||||
|
||||
use Queue\Consumer;
|
||||
|
||||
interface Relyon
|
||||
{
|
||||
|
||||
// /**
|
||||
// * @param string $key
|
||||
// * @param Consumer $consumer
|
||||
// * @param int $score
|
||||
// * @return mixed
|
||||
// *
|
||||
// * 追加
|
||||
// */
|
||||
// public function push(string $key, Consumer $consumer, $score = 0);
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * @param string $key
|
||||
// * @param Consumer $consumer
|
||||
// * @return mixed
|
||||
// * 消费
|
||||
// */
|
||||
// public function pop(string $key, Consumer $consumer);
|
||||
//
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
use Queue\Abstracts\Relyon;
|
||||
use Snowflake\Exception\ComponentException;
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
|
||||
/**
|
||||
* Class Complete
|
||||
* @package Queue
|
||||
*/
|
||||
class Complete extends \Queue\Abstracts\Queue
|
||||
{
|
||||
|
||||
const QUEUE_COMPLETE = 'queue:complete:lists';
|
||||
|
||||
|
||||
/**
|
||||
* @param Consumer $consumer
|
||||
* @param int $score
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function add(Consumer $consumer, $score = 0)
|
||||
{
|
||||
return $this->push(self::QUEUE_COMPLETE, $consumer, $score);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $consumer
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function del(Consumer $consumer)
|
||||
{
|
||||
return $this->pop(self::QUEUE_COMPLETE, $consumer);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
interface Consumer
|
||||
{
|
||||
|
||||
|
||||
public function __construct(array $params);
|
||||
|
||||
|
||||
|
||||
public function onWaiting();
|
||||
|
||||
|
||||
public function onRunning();
|
||||
|
||||
|
||||
public function onComplete();
|
||||
|
||||
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
use Exception;
|
||||
use ReflectionException;
|
||||
use Snowflake\Exception\ComponentException;
|
||||
use Snowflake\Exception\NotFindClassException;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Process;
|
||||
use Swoole\Timer;
|
||||
|
||||
/**
|
||||
* Class Queue
|
||||
* @package Queue
|
||||
*/
|
||||
class Queue extends \Snowflake\Process\Process
|
||||
{
|
||||
|
||||
/** @var Waiting */
|
||||
private $waiting;
|
||||
|
||||
/** @var Complete */
|
||||
private $complete;
|
||||
|
||||
/** @var Running */
|
||||
private $running;
|
||||
|
||||
|
||||
private $shutdown = false;
|
||||
|
||||
|
||||
/**
|
||||
* Queue constructor.
|
||||
* @param $application
|
||||
* @param $name
|
||||
* @throws ReflectionException
|
||||
* @throws NotFindClassException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct($application, $name)
|
||||
{
|
||||
parent::__construct($application, $name);
|
||||
$this->waiting = Snowflake::createObject(Waiting::class);
|
||||
$this->running = Snowflake::createObject(Running::class);
|
||||
$this->complete = Snowflake::createObject(Complete::class);
|
||||
|
||||
Process::signal(9 | 15, function () {
|
||||
$this->shutdown = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Process $process
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function onHandler(Process $process)
|
||||
{
|
||||
$redis = Snowflake::app()->getRedis();
|
||||
Timer::tick(50, function ($timerId) use ($redis) {
|
||||
if ($this->shutdown) {
|
||||
return Timer::clear($timerId);
|
||||
}
|
||||
$data = $redis->zRevRangeByScore(Waiting::QUEUE_WAITING, 0, 20);
|
||||
if (empty($data)) {
|
||||
return 1;
|
||||
}
|
||||
return $this->scheduler($data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Consumer $consumer
|
||||
* @param int $score
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function delivery(Consumer $consumer, $score = 0)
|
||||
{
|
||||
$this->waiting->add($consumer, $score);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws Exception
|
||||
*/
|
||||
private function scheduler($data)
|
||||
{
|
||||
$scheduler = new Coroutine\Scheduler();
|
||||
foreach ($data as $datum) {
|
||||
$scheduler->add([$this, 'runner'], $datum);
|
||||
}
|
||||
$scheduler->start();
|
||||
if ($this->shutdown === true) {
|
||||
Snowflake::shutdown($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
* @return mixed|void
|
||||
* @throws ComponentException
|
||||
*/
|
||||
private function runner(string $class)
|
||||
{
|
||||
$logger = $this->application->getLogger();
|
||||
try {
|
||||
$rely_on = unserialize($class);
|
||||
$this->waiting->remove($class);
|
||||
if ($rely_on instanceof Consumer) {
|
||||
return;
|
||||
}
|
||||
$this->running->add($rely_on);
|
||||
$rely_on->onRunning();
|
||||
} catch (\Throwable $exception) {
|
||||
$logger->write($exception->getMessage(), 'queue');
|
||||
} finally {
|
||||
$this->running->del($class);
|
||||
if (isset($rely_on) && $rely_on instanceof Consumer) {
|
||||
$rely_on->onComplete();
|
||||
$this->complete->add($rely_on);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Waiting
|
||||
*/
|
||||
public function getWaiting(): Waiting
|
||||
{
|
||||
return $this->waiting;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Complete
|
||||
*/
|
||||
public function getComplete(): Complete
|
||||
{
|
||||
return $this->complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Running
|
||||
*/
|
||||
public function getRunning(): Running
|
||||
{
|
||||
return $this->running;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
use Exception;
|
||||
use HttpServer\Server;
|
||||
use Snowflake\Abstracts\Providers;
|
||||
use Snowflake\Application;
|
||||
|
||||
|
||||
/**
|
||||
* Class QueueProviders
|
||||
* @package Queue
|
||||
*/
|
||||
class QueueProviders extends Providers
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Application $application
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onImport(Application $application)
|
||||
{
|
||||
/** @var Server $server */
|
||||
$server = $application->get('server');
|
||||
$server->addProcess('queue', Queue::class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Queue\Abstracts\AbstractsQueue;
|
||||
use Queue\Abstracts\Relyon;
|
||||
use Snowflake\Exception\ComponentException;
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
/**
|
||||
* Class Running
|
||||
* @package Queue
|
||||
*/
|
||||
class Running extends \Queue\Abstracts\Queue
|
||||
{
|
||||
|
||||
const QUEUE_RUNNING = 'queue:runner:lists';
|
||||
|
||||
|
||||
/**
|
||||
* @param Consumer $consumer
|
||||
* @param int $score
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function add(Consumer $consumer, $score = 0)
|
||||
{
|
||||
return $this->push(self::QUEUE_RUNNING, $consumer, $score);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $consumer
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function del(string $consumer)
|
||||
{
|
||||
$consumer = unserialize($consumer);
|
||||
if (!($consumer instanceof Consumer)) {
|
||||
return true;
|
||||
}
|
||||
return $this->pop(self::QUEUE_RUNNING, $consumer);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
/**
|
||||
* Class TestQueue
|
||||
* @package Queue
|
||||
*/
|
||||
class TestQueue implements Consumer
|
||||
{
|
||||
|
||||
public $params;
|
||||
|
||||
|
||||
/**
|
||||
* TestQueue constructor.
|
||||
* @param array $params
|
||||
*/
|
||||
public function __construct(array $params)
|
||||
{
|
||||
$this->params = $params;
|
||||
$this->onWaiting();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function onWaiting()
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function onRunning()
|
||||
{
|
||||
// TODO: Implement onRunning() method.
|
||||
}
|
||||
|
||||
public function onComplete()
|
||||
{
|
||||
// TODO: Implement onComplete() method.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Queue;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Queue\Abstracts\Relyon;
|
||||
use Snowflake\Exception\ComponentException;
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
/**
|
||||
* Class Waiting
|
||||
* @package Queue
|
||||
*/
|
||||
class Waiting extends \Queue\Abstracts\Queue
|
||||
{
|
||||
|
||||
const QUEUE_WAITING = 'queue:waiting:lists';
|
||||
|
||||
|
||||
/**
|
||||
* @param Consumer $consumer
|
||||
* @param int $score
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function add(Consumer $consumer, $score = 0)
|
||||
{
|
||||
return $this->push(self::QUEUE_WAITING, $consumer, $score);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $consumer
|
||||
* @return false|int
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function del(Consumer $consumer)
|
||||
{
|
||||
return $this->pop(self::QUEUE_WAITING, $consumer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,10 +14,12 @@ use Console\ConsoleProviders;
|
||||
use Database\DatabasesProviders;
|
||||
use Exception;
|
||||
use HttpServer\ServerProviders;
|
||||
use Queue\QueueProviders;
|
||||
use Snowflake\Abstracts\BaseApplication;
|
||||
use Snowflake\Abstracts\Config;
|
||||
use Snowflake\Abstracts\Input;
|
||||
use Snowflake\Exception\NotFindClassException;
|
||||
use Snowflake\Exception\ConfigException;
|
||||
use Swoole\Timer;
|
||||
|
||||
/**
|
||||
@@ -37,6 +39,7 @@ class Application extends BaseApplication
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
* @throws NotFindClassException
|
||||
*/
|
||||
public function init()
|
||||
@@ -44,6 +47,9 @@ class Application extends BaseApplication
|
||||
$this->import(ConsoleProviders::class);
|
||||
$this->import(DatabasesProviders::class);
|
||||
$this->import(ServerProviders::class);
|
||||
if (Config::get('queue.enable', false, false)) {
|
||||
$this->import(QueueProviders::class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ class Logger extends Component
|
||||
/**
|
||||
* @param $messages
|
||||
* @param string $category
|
||||
* @throws Exception
|
||||
* @throws
|
||||
*/
|
||||
public function write(string $messages, $category = 'app')
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ use ReflectionException;
|
||||
use Snowflake\Abstracts\Config;
|
||||
use Snowflake\Di\Container;
|
||||
use Snowflake\Exception\NotFindClassException;
|
||||
use Snowflake\Process\Process;
|
||||
use Swoole\Coroutine;
|
||||
|
||||
class Snowflake
|
||||
@@ -214,6 +215,23 @@ class Snowflake
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $process
|
||||
* @return mixed|void
|
||||
*/
|
||||
public static function shutdown($process)
|
||||
{
|
||||
static::app()->server->getServer()->shutdown();
|
||||
if ($process instanceof Process) {
|
||||
$process->exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $tmp
|
||||
* @return string
|
||||
*/
|
||||
public static function rename($tmp)
|
||||
{
|
||||
$hash = md5_file($tmp['tmp_name']);
|
||||
|
||||
Reference in New Issue
Block a user