Precautions for using coroutines in spool and exception capture in coroutines

Time:2021-6-12

Points for attention in use of coroutine

  • It is forbidden to use global variables in the coroutine to avoid data confusion;
  • Use of coroutineuseKeywords introduce external variables into the current scope, and prohibit the use of references, so as to avoid data confusion;
  • Class static variables cannot be usedClass::$array/Global variables$_array/Global object properties$object->array/Other super global variables$GLOBALSSave the context of the collaboration to avoid data confusion;
  • Channel must be used for communication between CO programs;
  • It is not allowed to share a client connection among multiple coroutines to avoid data confusion; It can be realized by connection pool;
  • In spool server, the client connection should be created in onworkerstart;
  • In spool process, the client connection should be created in the callback function of the child process after spool process > start;
  • The exception must be caught in the coroutine, not across the coroutine;
  • stay__get / __setMagic methods cannot have coroutine switching.

Exception capture in coroutines

Example 1: using the exit function to throw an exitexception exception in a coroutine

function route()
{
    controller();
}

function controller()
{
    your_code();
}

function your_code()
{
    co::sleep(.001);
    exit(1);
}

go(function () {
    try {
        route();
    } catch (\Swoole\ExitException $e) {
        var_dump($e->getMessage());
        var_dump($e->getStatus() === 1);
        var_dump($e->getFlags());
    }
});

Example 2: using the exit function to throw an exitexception exception in a coroutine

$exit_status = 0;
go(function () {
    try {
        exit(123);
    } catch (\Swoole\ExitException $e) {
        global $exit_status;
        $exit_status = $e->getStatus();
    }
});
swoole_event_wait();
var_dump($exit_status);

Example 3: the runtimeException exception is thrown directly in the coroutine

function test() {
    throw new \RuntimeException(__FILE__, __LINE__);
}

Swoole\Coroutine::create(function () {
    try {
        test();
    }
    catch (\Throwable $e) {
        echo $e;
    }
});