Skip to content

Commit

Permalink
Add user process
Browse files Browse the repository at this point in the history
  • Loading branch information
stelin committed Jul 14, 2019
1 parent c61b8f7 commit c328d54
Show file tree
Hide file tree
Showing 16 changed files with 579 additions and 30 deletions.
13 changes: 2 additions & 11 deletions src/event/src/EventHandlerInterface.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
<?php declare(strict_types=1);
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://swoft.org/docs
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/

namespace Swoft\Event;

/**
* Interface EventHandlerInterface - 独立的事件监听器接口
* Class EventHandlerInterface
*
* @package Swoft\Event
* @author inhere <[email protected]>
* @since 2.0
*/
interface EventHandlerInterface
{
Expand Down
4 changes: 3 additions & 1 deletion src/framework/src/Helper/Functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
{
Expand Down
36 changes: 36 additions & 0 deletions src/log/src/Error.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php declare(strict_types=1);


namespace Swoft\Log;


use ReflectionException;
use Swoft\Bean\Exception\ContainerException;
use Swoft\Co;
use Swoft\Log\Helper\CLog;
use Swoft\Log\Helper\Log;

/**
* Class Error
*
* @since 2.0
*/
class Error
{
/**
* @param string $message
* @param mixed ...$params
*
* @throws ReflectionException
* @throws ContainerException
*/
public static function log(string $message, ...$params): void
{
CLog::error($message, ...$params);

// In coroutine to write application log
if (Co::id() > 0) {
Log::error($message, ...$params);
}
}
}
33 changes: 33 additions & 0 deletions src/process/src/AutoLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php declare(strict_types=1);


namespace Swoft\Process;


use Swoft\SwoftComponent;

/**
* Class AutoLoader
*
* @since 2.0
*/
class AutoLoader extends SwoftComponent
{
/**
* @return array
*/
public function getPrefixDirs(): array
{
return [
__NAMESPACE__ => __DIR__,
];
}

/**
* @return array
*/
public function metadata(): array
{
return [];
}
}
19 changes: 19 additions & 0 deletions src/process/src/Context/ProcessContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php declare(strict_types=1);


namespace Swoft\Process\Context;

use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Context\AbstractContext;

/**
* Class ProcessContext
*
* @since 2.0
*
* @Bean(scope=Bean::PROTOTYPE)
*/
class ProcessContext extends AbstractContext
{

}
68 changes: 68 additions & 0 deletions src/process/src/Context/UserProcessContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);


namespace Swoft\Process\Context;

use ReflectionException;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Concern\PrototypeTrait;
use Swoft\Bean\Exception\ContainerException;
use Swoft\Context\AbstractContext;
use Swoft\Process\Process;
use Swoft\Server\Server;

/**
* Class UserProcessContext
*
* @since 2.0
*
* @Bean(scope=Bean::PROTOTYPE)
*/
class UserProcessContext extends AbstractContext
{
use PrototypeTrait;

/**
* @var Process
*/
private $process;

/**
* @var Server
*/
private $server;

/**
* @param Server $server
* @param Process $process
*
* @return UserProcessContext
* @throws ReflectionException
* @throws ContainerException
*/
public static function new(Server $server, Process $process): self
{
$self = self::__instance();

$self->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;
}
}
22 changes: 22 additions & 0 deletions src/process/src/Contract/ProcessInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php declare(strict_types=1);


namespace Swoft\Process\Contract;

use Swoole\Process\Pool;

/**
* Class ProcessInterface
*
* @since 2.0
*/
interface ProcessInterface
{
/**
* Run
*
* @param Pool $pool
* @param int $workerId
*/
public function run(Pool $pool, int $workerId): void;
}
36 changes: 36 additions & 0 deletions src/process/src/Contract/UserProcessInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php declare(strict_types=1);


namespace Swoft\Process\Contract;

use Swoft\Process\Process;

/**
* Class UserProcessInterface
*
* @since 2.0
*/
interface UserProcessInterface
{
/**
* Run
*
* @param Process $process
*/
public function run(Process $process): void;

/**
* @return bool
*/
public function isStdinOut(): bool;

/**
* @return int
*/
public function getPipeType(): int;

/**
* @return bool
*/
public function isCoroutine(): bool;
}
88 changes: 88 additions & 0 deletions src/process/src/Listener/AddProcessListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php declare(strict_types=1);


namespace Swoft\Process\Listener;


use Swoft;
use Swoft\Event\Annotation\Mapping\Listener;
use Swoft\Event\EventHandlerInterface;
use Swoft\Event\EventInterface;
use Swoft\Log\Error;
use Swoft\Process\Contract\UserProcessInterface;
use Swoft\Process\Process;
use Swoft\Process\ProcessEvent;
use Swoft\Server\Exception\ServerException;
use Swoft\Server\Server;
use Swoft\Server\ServerEvent;
use Swoft\Stdlib\Helper\PhpHelper;
use Swoole\Process as SwooleProcess;
use Throwable;

/**
* Class AddProcessListener
*
* @since 2.0
*
* @Listener(event=ServerEvent::ADDED_PROCESS)
*/
class AddProcessListener implements EventHandlerInterface
{
/**
* @param EventInterface $event
*
* @throws ServerException
*/
public function handle(EventInterface $event): void
{
/* @var Server $server */
$server = $event->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);
}
}
}
37 changes: 37 additions & 0 deletions src/process/src/Listener/AfterUserProcessListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types=1);


namespace Swoft\Process\Listener;


use Swoft;
use Swoft\Bean\Exception\ContainerException;
use Swoft\Event\Annotation\Mapping\Listener;
use Swoft\Event\EventHandlerInterface;
use Swoft\Event\EventInterface;
use Swoft\Process\ProcessEvent;
use Swoft\SwoftEvent;

/**
* Class AfterUserProcessListener
*
* @since 2.0
*
* @Listener(event=ProcessEvent::AFTER_USER_PROCESS)
*/
class AfterUserProcessListener implements EventHandlerInterface
{
/**
* @param EventInterface $event
*
* @throws ContainerException
*/
public function handle(EventInterface $event): void
{
// Defer
Swoft::trigger(SwoftEvent::COROUTINE_DEFER);

// Destroy
Swoft::trigger(SwoftEvent::COROUTINE_COMPLETE);
}
}
Loading

0 comments on commit c328d54

Please sign in to comment.