Home  >  Article  >  Backend Development  >  How to implement Swoole custom project initialization event handling (code)

How to implement Swoole custom project initialization event handling (code)

不言
不言Original
2018-09-13 17:01:151855browse

The content of this article is about how to implement Swoole custom project initialization event processing (code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Recently using the imi framework developed based on Swoole to develop a project, I encountered a requirement, which is to do project initialization processing. You don't want Swoole to handle the request before the initialization process is completed. Because there may be some values ​​that are not loaded in, there is a high possibility of problems processing the request.

The thinking process and demo code for solving the problem are given below.

First of all, after analysis, Swoole runs in multi-process mode and is divided into Master, Manager and Worker processes.

The Master process is the process where the cli command file where we start the service is located. There is a problem with the initialization here. All loaded classes and global variables can be used in other Worker processes and cannot be hot restarted to take effect.

The situation of the Manager process is basically the same as above.

Then only the Worker process does the processing, but if it is written in the WorkerStart event, each Worker process will execute it.

WorkerStart event definition:

function onWorkerStart(swoole_server $server, int $worker_id);
$worker_id is a number between 0-$worker_num, indicating the ID of this Worker process

Then this is easy to handle, directly determine the workerid is 0 To trigger the project initialization event. The remaining question is how to prevent all Worker processes from processing requests until the initialization execution is completed.

Thinked about it and tried it. This problem can be solved by hanging the coroutine. The demo code is as follows:

<?php

use Swoole\Coroutine;

$http = new swoole_http_server(&#39;127.0.0.1&#39;, 8080);

$http->on(&#39;WorkerStart&#39;, function(swoole_http_server $server, $workerId){
    $initFlagFile = __DIR__ . &#39;/init.flag&#39;;
    if(0 === $server->worker_id && (!is_file($initFlagFile) || file_get_contents($initFlagFile) != $server->manager_pid))
    {
        // 处理项目初始化事件
        initApp();
        // 写入文件,保证不再重复触发项目初始化事件
        file_put_contents($initFlagFile, $server->manager_pid);
        // 当前worker进程恢复协程
        resumeCos();
        // 通知其它worker进程
        for($i = 1; $i < $server->setting[&#39;worker_num&#39;]; ++$i)
        {
            $server->sendMessage(&#39;init&#39;, $i);
        }
    }
});

$http->on(&#39;PipeMessage&#39;, function(swoole_http_server $server, $srcWorkerId, $data) {
    if(0 === $srcWorkerId && &#39;init&#39; === $data && !defined(&#39;APP_INITED&#39;))
    {
        // 其它worker进程恢复协程
        resumeCos();
    }
});

$http->on(&#39;request&#39;, function (swoole_http_request $request, swoole_http_response $response) {
    // 判断未初始化完毕,则挂起协程
    if(!defined(&#39;APP_INITED&#39;))
    {
        $GLOBALS[&#39;WORKER_START_END_RESUME_COIDS&#39;][] = Coroutine::getuid();
        Coroutine::suspend();
    }
    $response->header(&#39;content-type&#39;, &#39;text/html;charset=utf-8&#39;);
    $response->end(&#39;IMI 是一款基于 Swoole 开发的协程 PHP 开发框架,拥有常驻内存、协程异步非阻塞IO等优点。官方网站:<a href="https://imiphp.com" target="_blank">https://imiphp.com</a>&#39;);
});

$http->start();

/**
 * 处理项目初始化事件,比如这里延时5秒,模拟初始化处理
 *
 * @return void
 */
function initApp()
{
    $count = 5;
    for($i = 0; $i < $count; ++$i)
    {
        echo &#39;initing &#39;, ($i + 1), &#39;/&#39;, $count, PHP_EOL;
        sleep(1);
    }
}

/**
 * 恢复协程
 *
 * @return void
 */
function resumeCos()
{
    define(&#39;APP_INITED&#39;, true);
    $coids = $GLOBALS[&#39;WORKER_START_END_RESUME_COIDS&#39;] ?? [];
    fwrite(STDOUT, &#39;suspend co count: &#39; . count($coids) . PHP_EOL);
    foreach($coids as $id)
    {
        Coroutine::resume($id);
    }
}

By judging whether the initialization is completed in the request event, if the initialization is not completed, hang Start the current coroutine and add the coroutine ID to the global variable.

After the 0th worker process completes the initialization, it wakes up the suspended coroutines by sending messages to other worker processes. The requests that came in during the initialization period will be executed at this time.

Related recommendations:

Detailed explanation of javascript implementation of custom events_javascript skills

How to use Angularjs custom instructions in the project use

The above is the detailed content of How to implement Swoole custom project initialization event handling (code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn