Coletinas

Coletinas são um mecanismo de concorrência de nível de usuário mais leve do que threads, capaz de implementar agendamento de múltiplas tarefas dentro de um processo. Elas permitem a troca entre coletinas por meio do controle manual de suspensão e retomada, evitando o custo de troca de contexto de processo.
O Workerman fornece uma interface genérica para coletinas, com compatibilidade automática para drivers Swoole/Swow/Fiber.

Dica
Esse recurso requer workerman>=5.1.0

Atenção

  • Coletinas suportam apenas os drivers Swoole Swow Fiber
  • Se utilizar o driver Fiber, é necessário instalar composer require revolt/event-loop
  • Os drivers Swoole ou Swow podem realizar a corotização automática de funções bloqueantes do PHP, permitindo que o código síncrono original execute de forma assíncrona
  • No entanto, o Fiber não pode ser automaticamente corotizado como os drivers Swoole e Swow, e ao encontrar funções bloqueantes nativas do PHP, bloqueará todo o processo, sem ocorrer troca de coletinas
  • Ao usar os drivers Swoole Swow Fiber, o workerman criará automaticamente uma coletina para executar sempre que chamar os callbacks onWorkerStart, onMessage, onConnect, onClose, etc.
  • É possível utilizar $worker->eventLoop=xxx; para definir diferentes drivers de coletina para diferentes workers
<?php
use Workerman\Connection\TcpConnection;
use Workerman\Coroutine;
use Workerman\Events\Swoole;
use Workerman\Events\Fiber;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';

$worker1 = new Worker('http://0.0.0.0:8001');
$worker1->eventLoop = Swoole::class; // Usando coletina Swoole
$worker1->onMessage = function (TcpConnection $connection, Request $request) {
    Coroutine::create(function () {
        echo file_get_contents("http://www.example.com/event/notify");
    });
    $connection->send('ok');
};

$worker2 = new Worker('http://0.0.0.0:8001');
$worker2->eventLoop = Fiber::class; // Usando coletina Fiber nativa
$worker2->onMessage = function (TcpConnection $connection, Request $request) {
    Coroutine::create(function () {
        echo file_get_contents("http://www.example.com/event/notify");
    });
    $connection->send('ok');
};

Worker::runAll();

Interfaces oferecidas pelas coletinas

interface CoroutineInterface
{

    /**
     * Criar coletina e executar imediatamente
     */
    public static function create(callable $callable, ...$data): CoroutineInterface;

    /**
     * Iniciar a execução da coletina
     */
    public function start(mixed ...$args): mixed;

    /**
     * Retomar a execução da coletina
     */
    public function resume(mixed ...$args): mixed;

    /**
     * Obter o id da coletina
     */
    public function id(): int;

    /**
     * Definir um callback para quando a coletina for destruída
     */
    public static function defer(callable $callable): void;

    /**
     * Pausar a coletina atual
     */
    public static function suspend(mixed $value = null): mixed;

    /**
     * Obter a coletina atual
     */
    public static function getCurrent(): CoroutineInterface|Fiber|SwowCoroutine|static;

    /**
     * Verificar se estamos em um ambiente de coletina
     */
    public static function isCoroutine(): bool;

}

Sobre Coletinas

Vantagens

A maior vantagem da introdução de coletinas no PHP é que elas permitem escrever código assíncrono de forma síncrona, evitando o chamado "callback hell" e aumentando a legibilidade e a manutenibilidade do código.
Coletinas podem aumentar significativamente a resiliência de serviços que são intensivos em I/O, permitindo oferecer uma maior capacidade de processamento com menos processos.

Desvantagens

No entanto, a introdução de coletinas requer que os desenvolvedores estejam sempre atentos a problemas de poluição de variáveis globais, competição por recursos e transformações em bibliotecas de terceiros, o que aumenta o custo de desenvolvimento e a carga mental.

A introdução de coletinas resulta em despesas adicionais relacionadas à criação, agendamento, destruição e gerenciamento de pools de conexões.
Dados de testes extensivos mostram que, ao utilizar de maneira eficaz o CPU, a performance máxima com coletinas é cerca de 10%-20% inferior em comparação com I/O bloqueante.