The implementation of go like waitGroup multi concurrent scheduling with toolefy based on Toole

Posted by BrandonRoy on Tue, 19 Nov 2019 15:48:58 +0100

Swoolefy is a lightweight and high-performance memory resident API and Web application service framework based on swoole. It highly encapsulates http, websocket, udp server, and extensible rpc service based on tcp. At the same time, it supports the installation and deployment of composer package. Based on practical application, swoolefy abstracts Event processing class, realizes decoupling with underlying callback, supports coordinated scheduling, synchronous | asynchronous call, global Event registration, heartbeat check, asynchronous task, multi process (pool), etc., and built-in common components such as view, log, session, mysql, redis, mongodb, etc.

At present, swoolefy4.2 + fully supports swoole4.2.13 +, and swoole4.3 is recommended+

GitHub: https://github.com/bingcool/s...

The following mainly explains how to realize the function of waitGroup similar to go
1. Define the class of GoWaitGroup:

<?php
/**
+----------------------------------------------------------------------
| swoolefy framework bases on swoole extension development, we can use it easily!
+----------------------------------------------------------------------
| Licensed ( https://opensource.org/licenses/MIT )
+----------------------------------------------------------------------
| Author: bingcool <bingcoolhuang@gmail.com || 2437667702@qq.com>
+----------------------------------------------------------------------
 */

namespace Swoolefy\Core;

use Swoole\Coroutine\Channel;

class GoWaitGroup {
    /**
     * @var int
     */
    private $count = 0;

    /**
     * @var Channel
     */
    private $chan;

    /**
     * @var array
     */
    private $result = [];

    /**
     * WaitGroup constructor
     */
    public function __construct() {
        $this->chan = new Channel;
    }

    /**
     * add
     */
    public function go(\Closure $go_func = null) {
        $this->count++;
        if($go_func instanceof \Closure) {
            go($go_func);
        }
    }

    /**
     * start
     */
    public function start() {
        $this->count++;
        return $this->count;
    }

    /**
     * done
     */
    public function done(string $key, $data = null) {
        if(!empty($data)) {
            $this->result[$key] = $data;
        }
        $this->chan->push(1);
    }

    /**
     * wait
     */
    public function wait() {
        while($this->count--) {
            $this->chan->pop();
        }
        $result = $this->result;
        $this->result = [];
        $this->count = 0;
        return $result;
    }

}

2. Call in swoolefy

class GroupController extends BController {
    public function waitgroup() {
        // Create a waitGroup instance
        $wg = new \Swoolefy\Core\GoWaitGroup();
         
         // The first way is to execute go's coroutine function directly in the $WG - > go() function
        $wg->go(function() use ($wg) {
            // Hang up Association
            $fp = stream_socket_client("tcp://www.baidu.com:80", $errno, $errstr, 30);
            // Data returned by the process
            $wg->done('mysql', 'mysql');
        });

        $wg->go(function() use ($wg) {
            sleep(1);
            $wg->done('tengxun', 'weixin and qq');
        });

        //Suspend the current process and wait for all tasks to complete before resuming
        //$result = $wg->wait();
        //Here $result contains 1 task execution result
        //var_dump($result);
        
        //The second way is to add $WG - > start(), start the process, and then use swoole's native go to execute the process function
        $wg->start();
        go(function () use ($wg) {
            // Hang up Association
            sleep(1);
            $wg->done('taobao', 'ali baba');
        });
        
         //The second way is to add $WG - > start(), start the process, and then use swoole's native go to execute the process function
        $wg->start();
        go(function () use ($wg) {
            // Hang up Association
            sleep(1);
            $wg->done('baidu', 'baidu');
        });
        // The above three processes will be called concurrently, and the wait() function will wait for the data of the three processes to return
        //Suspend the current process, give up the cpu control, and the cpu can do other things until all tasks are completed
        $result = $wg->wait();
        //Here $result contains 2 task execution results
        var_dump($result);
    }
}

At this point, the simplest concurrent call is completed, and you can use the gowaitGroup's coordination call happily

Topics: PHP MySQL github Session Redis