2021-04-13 11:02:41 +08:00
# Custom process
2019-04-05 09:35:27 +08:00
2021-04-13 11:02:41 +08:00
[hyperf/process ](https://github.com/hyperf-cloud/process ) allows you to add user-defined processes. This feature is usually used to create a special process for monitoring, reporting or other special tasks. When the server starts, it will automatically create a process and execute the specified subprocess. If the process exits unexpectedly, the server will automatically restart the process.
2019-04-05 09:35:27 +08:00
2021-04-13 11:02:41 +08:00
## Create a custom process
2019-04-05 09:35:27 +08:00
2021-04-13 11:02:41 +08:00
Implement a subclass that inherits `Hyperf\Process\AbstractProcess` and implement the interface method `handle(): void` , with your logic code in the method. Let's take this code as an example:
2019-05-07 17:46:12 +08:00
```php
< ?php
declare(strict_types=1);
namespace App\Process;
use Hyperf\Process\AbstractProcess;
class FooProcess extends AbstractProcess
{
public function handle(): void
{
2021-04-13 11:02:41 +08:00
// Your code...
2019-05-07 17:46:12 +08:00
}
}
```
2021-04-13 11:02:41 +08:00
This defines a custom process class, but the class has not been registered in the `ProcessManager` . We can register it using one of the two ways: `configuration file` or `annotation` .
2019-05-07 17:46:12 +08:00
2021-04-13 11:02:41 +08:00
### Register via configuration file
2019-05-07 17:46:12 +08:00
2021-04-13 11:02:41 +08:00
Just add your custom process class in `config/autoload/processes.php` :
2019-05-07 17:46:12 +08:00
```php
// config/autoload/processes.php
return [
\App\Process\FooProcess::class,
];
```
2021-04-13 11:02:41 +08:00
### Register via annotation
2019-05-07 17:46:12 +08:00
2022-01-13 12:09:04 +08:00
Just define the #[Process] annotation on the custom process class, and Hyperf will collect and automatically complete the registration work:
2019-05-07 17:46:12 +08:00
```php
< ?php
declare(strict_types=1);
namespace App\Process;
use Hyperf\Process\AbstractProcess;
use Hyperf\Process\Annotation\Process;
2022-01-13 12:09:04 +08:00
#[Process(name: "foo_process")]
2019-05-07 17:46:12 +08:00
class FooProcess extends AbstractProcess
{
public function handle(): void
{
2021-04-13 11:02:41 +08:00
// Your code...
2019-05-07 17:46:12 +08:00
}
}
```
2022-01-13 12:09:04 +08:00
> When using `#[Process]` annotation, `use Hyperf\Process\Annotation\Process;` namespace is required;
2019-05-07 17:46:12 +08:00
2021-04-13 11:02:41 +08:00
## Add conditions for process startup
2019-05-07 17:46:12 +08:00
2021-04-13 11:02:41 +08:00
Sometimes a custom process should not be started at all times. Whether a custom process is started or not may be determined according to certain configurations or conditions by overriding `isEnable(): bool` method in the custom process class. The method is implemented by default with the return value of `true` , which will start with the service. If the method returns `false` , the custom process will not be started when the service starts.
2019-05-07 17:46:12 +08:00
```php
< ?php
declare(strict_types=1);
namespace App\Process;
use Hyperf\Process\AbstractProcess;
use Hyperf\Process\Annotation\Process;
2022-01-13 12:09:04 +08:00
#[Process(name: "foo_process")]
2019-05-07 17:46:12 +08:00
class FooProcess extends AbstractProcess
{
public function handle(): void
{
2021-04-13 11:02:41 +08:00
// Your code...
2019-05-07 17:46:12 +08:00
}
2021-04-13 11:02:41 +08:00
2020-08-28 18:13:38 +08:00
public function isEnable($server): bool
2019-05-07 17:46:12 +08:00
{
2021-04-13 11:02:41 +08:00
// Do not start with service startup
return false;
2019-05-07 17:46:12 +08:00
}
}
```
2021-04-13 11:02:41 +08:00
## Configuring a custom process
2019-05-07 17:46:12 +08:00
2022-01-13 12:09:04 +08:00
There are some configurable parameters in the custom process, which can be defined by overriding the attributes corresponding to the parameters on the subclass or defining the corresponding attributes in the `#[Process]` annotation.
2019-04-05 09:35:27 +08:00
```php
< ?php
2019-05-07 17:46:12 +08:00
declare(strict_types=1);
2019-04-05 09:35:27 +08:00
2019-05-07 17:46:12 +08:00
namespace App\Process;
use Hyperf\Process\AbstractProcess;
use Hyperf\Process\Annotation\Process;
2022-01-13 12:09:04 +08:00
#[Process(name: "foo_process", name: "user-process", redirectStdinStdout: false, pipeType: 2, enableCoroutine: true)]
2019-05-07 17:46:12 +08:00
class FooProcess extends AbstractProcess
{
/**
2021-04-13 11:02:41 +08:00
* Number of processes
2019-05-07 17:46:12 +08:00
* @var int
*/
public $nums = 1;
/**
2021-04-13 11:02:41 +08:00
* Process name
2019-05-07 17:46:12 +08:00
* @var string
*/
public $name = 'user-process';
/**
2021-04-13 11:02:41 +08:00
* Redirect the standard input and output of a custom process
2019-05-07 17:46:12 +08:00
* @var bool
*/
public $redirectStdinStdout = false;
/**
2021-04-13 11:02:41 +08:00
* Pipe type
2019-05-07 17:46:12 +08:00
* @var int
*/
public $pipeType = 2;
/**
2021-04-13 11:02:41 +08:00
* Whether to enable coroutine
2019-05-07 17:46:12 +08:00
* @var bool
*/
public $enableCoroutine = true;
}
```
2021-04-13 11:02:41 +08:00
## Usage example
2019-05-07 17:46:12 +08:00
2021-04-13 11:02:41 +08:00
We create a child process to monitor the number of failure queues, and report a warning when there is data in the failure queue.
2019-05-07 17:46:12 +08:00
```php
< ?php
2019-04-05 09:35:27 +08:00
declare(strict_types=1);
2019-04-05 09:45:00 +08:00
namespace App\Process;
2019-04-05 09:35:27 +08:00
use Hyperf\Process\AbstractProcess;
use Hyperf\Process\Annotation\Process;
use Hyperf\Contract\StdoutLoggerInterface;
2022-01-13 12:09:04 +08:00
#[Process(name: "demo_process")]
2019-04-05 09:35:27 +08:00
class DemoProcess extends AbstractProcess
{
public function handle(): void
{
$logger = $this->container->get(StdoutLoggerInterface::class);
while (true) {
$redis = $this->container->get(\Redis::class);
$count = $redis->llen('queue:failed');
if ($count > 0) {
$logger->warning('The num of failed queue is ' . $count);
}
sleep(1);
}
}
}
2021-04-13 11:02:41 +08:00
```