diff --git a/src/event/src/EventHandlerInterface.php b/src/event/src/EventHandlerInterface.php index 70c8c3cb4..6f3815281 100644 --- a/src/event/src/EventHandlerInterface.php +++ b/src/event/src/EventHandlerInterface.php @@ -1,20 +1,11 @@ + * @since 2.0 */ interface EventHandlerInterface { diff --git a/src/framework/src/Helper/Functions.php b/src/framework/src/Helper/Functions.php index c1365e35a..31e148208 100644 --- a/src/framework/src/Helper/Functions.php +++ b/src/framework/src/Helper/Functions.php @@ -8,6 +8,8 @@ use Swoft\Event\Manager\EventManager; use Swoft\Http\Server\HttpContext; use Swoft\Http\Server\HttpServer; +use Swoft\Process\Context\ProcessContext; +use Swoft\Process\Context\UserProcessContext; use Swoft\Rpc\Server\ServiceContext; use Swoft\Server\Server; use Swoft\Task\FinishContext; @@ -136,7 +138,7 @@ function srun(callable $callable): bool /** * Get current context * - * @return ContextInterface|HttpContext|ServiceContext|TaskContext|FinishContext + * @return ContextInterface|HttpContext|ServiceContext|TaskContext|FinishContext|UserProcessContext|ProcessContext */ function context(): ContextInterface { diff --git a/src/log/src/Error.php b/src/log/src/Error.php new file mode 100644 index 000000000..78ac8861d --- /dev/null +++ b/src/log/src/Error.php @@ -0,0 +1,36 @@ + 0) { + Log::error($message, ...$params); + } + } +} \ No newline at end of file diff --git a/src/process/src/AutoLoader.php b/src/process/src/AutoLoader.php new file mode 100644 index 000000000..b1c3eac20 --- /dev/null +++ b/src/process/src/AutoLoader.php @@ -0,0 +1,33 @@ + __DIR__, + ]; + } + + /** + * @return array + */ + public function metadata(): array + { + return []; + } +} \ No newline at end of file diff --git a/src/process/src/Context/ProcessContext.php b/src/process/src/Context/ProcessContext.php new file mode 100644 index 000000000..616e35594 --- /dev/null +++ b/src/process/src/Context/ProcessContext.php @@ -0,0 +1,19 @@ +server = $server; + $self->process = $process; + + return $self; + } + + /** + * @return Process + */ + public function getProcess(): Process + { + return $this->process; + } + + /** + * @return Server + */ + public function getServer(): Server + { + return $this->server; + } +} \ No newline at end of file diff --git a/src/process/src/Contract/ProcessInterface.php b/src/process/src/Contract/ProcessInterface.php new file mode 100644 index 000000000..aaf108af1 --- /dev/null +++ b/src/process/src/Contract/ProcessInterface.php @@ -0,0 +1,22 @@ +getTarget(); + + $this->addProcess($server); + } + + /** + * Add process + * + * @param Server $server + * + * @throws ServerException + */ + private function addProcess(Server $server): void + { + $process = $server->getProcess(); + if (empty($process)) { + return; + } + + foreach ($process as $name => $userProcess) { + if (!$userProcess instanceof UserProcessInterface) { + throw new ServerException('Server add process must be instanceof UserProcessInterface!'); + } + + $callback = [$userProcess, 'run']; + $stdinOut = $userProcess->isStdinOut(); + $pipeType = $userProcess->getPipeType(); + $coroutine = $userProcess->isCoroutine(); + + $function = function (SwooleProcess $process) use ($callback, $server, $name) { + $process = Process::new($process); + + // Before + Swoft::trigger(ProcessEvent::BEFORE_USER_PROCESS, null, $server, $process, $name); + + try {// Run + PhpHelper::call($callback, $process); + } catch (Throwable $e) { + Error::log('User process fail(%s %s %d)!', $e->getFile(), $e->getMessage(), $e->getLine()); + } + + // After + Swoft::trigger(ProcessEvent::AFTER_USER_PROCESS); + }; + + $process = new SwooleProcess($function, $stdinOut, $pipeType, $coroutine); + $server->getSwooleServer()->addProcess($process); + } + } +} \ No newline at end of file diff --git a/src/process/src/Listener/AfterUserProcessListener.php b/src/process/src/Listener/AfterUserProcessListener.php new file mode 100644 index 000000000..822427674 --- /dev/null +++ b/src/process/src/Listener/AfterUserProcessListener.php @@ -0,0 +1,37 @@ +getParams(); + + $context = UserProcessContext::new($server, $process); + if (Log::getLogger()->isEnable()) { + $data = [ + 'event' => sprintf('swoft.process.user.%s', (string)$name), + 'uri' => '', + 'requestTime' => microtime(true), + ]; + $context->setMulti($data); + } + + Context::set($context); + } +} \ No newline at end of file diff --git a/src/process/src/Process.php b/src/process/src/Process.php index 58122e1f6..30abfe8e0 100644 --- a/src/process/src/Process.php +++ b/src/process/src/Process.php @@ -20,20 +20,47 @@ class Process */ protected $process; + /** + * @param SwooleProcess $process + * + * @return Process + * @throws ProcessException + */ + public static function new(SwooleProcess $process): self + { + $self = new self(null, false, 2, true, $process); + + $self->process = $process; + return $self; + } + /** * Process constructor. * - * @param callable $callback - * @param bool $inout - * @param int $pipeType - * @param bool $coroutine + * @param callable $callback + * @param bool $inout + * @param int $pipeType + * @param bool $coroutine + * @param SwooleProcess|null $process + * + * @throws ProcessException */ public function __construct( - callable $callback, + callable $callback = null, bool $inout = false, int $pipeType = 2, - bool $coroutine = false + bool $coroutine = true, + SwooleProcess $process = null ) { + if (!empty($process)) { + $this->process = $process; + return; + } + + if (empty($callback)) { + throw new ProcessException('Process callback must be not empty!'); + } + $this->process = new SwooleProcess($callback, $inout, $pipeType, $coroutine); } diff --git a/src/process/src/ProcessEvent.php b/src/process/src/ProcessEvent.php new file mode 100644 index 000000000..091d5e5c1 --- /dev/null +++ b/src/process/src/ProcessEvent.php @@ -0,0 +1,32 @@ +stdinOut; + } + + /** + * @return int + */ + public function getPipeType(): int + { + return $this->pipeType; + } + + /** + * @return bool + */ + public function isCoroutine(): bool + { + return $this->coroutine; + } +} \ No newline at end of file diff --git a/src/server/src/Server.php b/src/server/src/Server.php index 3ba4b95f8..b80e959d8 100644 --- a/src/server/src/Server.php +++ b/src/server/src/Server.php @@ -9,6 +9,7 @@ use Swoft\Console\Console; use Swoft\Http\Server\HttpServer; use Swoft\Log\Helper\CLog; +use Swoft\Process\Contract\UserProcessInterface; use Swoft\Server\Contract\ServerInterface; use Swoft\Server\Event\ServerStartEvent; use Swoft\Server\Event\WorkerEvent; @@ -154,6 +155,19 @@ abstract class Server implements ServerInterface */ protected $listener = []; + /** + * Add process + * + * @var array + * + * @example + * [ + * 'name' => UserProcessInterface, + * 'name2' => UserProcessInterface, + * ] + */ + protected $process = []; + /** * Script file * @@ -485,7 +499,8 @@ protected function startSwoole(): void // Set settings $this->swooleServer->set($this->setting); - Swoft::trigger(ServerEvent::BEFORE_BIND_EVENT, $this); + // Before Add event + Swoft::trigger(ServerEvent::BEFORE_ADDED_EVENT, $this); // Register events $defaultEvents = $this->defaultEvents(); @@ -494,14 +509,23 @@ protected function startSwoole(): void // Add events $this->addEvent($this->swooleServer, $swooleEvents, $defaultEvents); - Swoft::trigger(ServerEvent::BEFORE_BIND_LISTENER, $this); + //After add event + Swoft::trigger(ServerEvent::AFTER_ADDED_EVENT, $this); + + // Before listener + Swoft::trigger(ServerEvent::BEFORE_ADDED_LISTENER, $this); // Add port listener $this->addListener(); - // Swoft::trigger(ServerEvent::BEFORE_BIND_PROCESS, $this); - // @TODO Add processes - // $this->addProcesses(); + // Before bind process + Swoft::trigger(ServerEvent::BEFORE_ADDED_PROCESS, $this); + + // Add Process + Swoft::trigger(ServerEvent::ADDED_PROCESS, $this); + + // After bind process + Swoft::trigger(ServerEvent::AFTER_ADDED_PROCESS, $this); // Trigger event Swoft::trigger(ServerEvent::BEFORE_START, $this, array_keys($swooleEvents)); @@ -1094,6 +1118,14 @@ public function getUniqid(): string return $this->uniqid; } + /** + * @return array + */ + public function getProcess(): array + { + return $this->process; + } + /** * @return array */ diff --git a/src/server/src/ServerEvent.php b/src/server/src/ServerEvent.php index 083e59ea6..4e000ebe0 100644 --- a/src/server/src/ServerEvent.php +++ b/src/server/src/ServerEvent.php @@ -12,17 +12,22 @@ final class ServerEvent /** * Before set swoole settings */ - public const BEFORE_SETTING = 'swoft.server.before.setting'; + public const BEFORE_SETTING = 'swoft.server.setting.before'; /** - * Before bind swoole events + * Before add swoole events */ - public const BEFORE_BIND_EVENT = 'swoft.server.bind.event'; + public const BEFORE_ADDED_EVENT = 'swoft.server.added.event.before'; /** - * Before bind listener(s) + * Before add swoole events + */ + public const AFTER_ADDED_EVENT = 'swoft.server.added.event.after'; + + /** + * Before add listener(s) */ - public const BEFORE_BIND_LISTENER = 'swoft.server.bind.listener.before'; + public const BEFORE_ADDED_LISTENER = 'swoft.server.added.listener.before'; /** * After each listener is successfully added @@ -30,9 +35,14 @@ final class ServerEvent public const AFTER_ADDED_LISTENER = 'swoft.server.added.listener.after'; /** - * Before bind process(es) + * Before add process(es) + */ + public const BEFORE_ADDED_PROCESS = 'swoft.server.added.process.before'; + + /** + * Add process(es) */ - public const BEFORE_BIND_PROCESS = 'swoft.server.bind.process.before'; + public const ADDED_PROCESS = 'swoft.server.added.process'; /** * After each process is successfully added @@ -88,4 +98,18 @@ final class ServerEvent * Before worker stop event */ public const BEFORE_WORKER_STOP_EVENT = 'swoft.server.event.worker.stop.before'; + + /** + * Before bind listener(s) + * + * @deprecated + */ + public const BEFORE_BIND_LISTENER = 'swoft.server.added.listener.before'; + + /** + * Before bind swoole events + * + * @deprecated + */ + public const BEFORE_BIND_EVENT = 'swoft.server.added.event.before'; }