Swoole Server task()

4.x is outdated, please check the latest version 22.x


Latest version: pecl install openswoole-22.1.2

Declaration

<?php Swoole\Server->task(mixed $data, int $dstWorkerId = -1, callable $finishCallback = null): int

Parameters

data

The data which to send to the task worker, must be a serializable PHP variable

dstWorkerId

The ID number of the task worker. If this parameter hasn't been passed, the swoole server would select a random and unoccupied task worker process for you.

finishCallback

The callback function that is called when the task has been finished. If this parameter has been passed, there is no need to register the callback function of the event of onFinish

Return

success

If success, it returns the task ID of which process accepted it, otherwise it returns false.

Description

Send data to a task worker processes.

Start a new asynchronous task. This function is non-blocking and will return immediately after sending the task to the pool of task workers. The current worker process can then continue to process new requests.

To call this method, you need to set the configuration of task_worker_num and the callback function of onTask and onFinish.

Things to Consider

  • This function is used to execute slow tasks asynchronously, such as a chat server, which can be used to send broadcasts. When the task is completed, the task process calls $server->finish("finish") telling the worker process this task has been completed. Of course, Swoole\Server->finish is optional. The task can then operate without blocking the main server from processing new requests.

  • The task worker design uses UnixSocket to communication, when the memory is full, no I/O is used. Tasks have huge Read and write performance of up to a single process being able to handle around 100k, more processes using different UnixSocket communication pipes, can be maximized by using more CPU cores.

  • If the task worker is not a specified, Swoole determines which task processes are in a busy state, Swoole will only select idle Task processes to deliver new tasks to. If all Task processes are busy, Swoole will poll and deliver tasks to each process. You can use the $server->stats method to get the number of tasks currently queued and waiting, this results in no disk I/O being used.

  • The third parameter (finishCallback) can be set to avoid any event triggers for onFinish, if the task has a set callback function then the task system executes the specified callback function and any results are returned, no longer performing the Server onFinish event.

  • The data that is sent to a task is usually best not too exceed 8k, if this does occur then Swoole will temporarily save the data to disk while waiting for the task system to use the data that is queued. If the temporarily saved data on disk exceeds package_max_length, Swoole will then start to throw warnings but, this is not an error, it just means you may experience performance issues with the server.

  • Task worker processes can not be used by user defined processes, instead you can use sendMessage to communicate between them.

  • Inside a task worker process, you should not return data using return otherwise $Server->finish() will output the result.

Example

Using the task finish callback

<?php
$task_id = $server->task("some data");

$server->task("taskcallback", -1, function (Swoole\Server $server, $task_id, $data)
{
    echo "Task Callback: ";
    var_dump($task_id, $data);
});

General server task usage

<?php
$server = new Swoole\Server("127.0.0.1", 9501, SWOOLE_BASE);

$server->set([
    'worker_num'      => 2,
    'task_worker_num' => 4,
]);

$server->on('Receive', function (Swoole\Server $server, $fd, $reactorId, $data)
{
    echo "Received data: " . $data . "\n";
    $data    = trim($data);

    $server->task($data, -1, function (Swoole\Server $server, $task_id, $data)
    {
        echo "Task Callback: ";
        var_dump($task_id, $data);
    });

    $task_id = $server->task($data, 0);

    $server->send($fd, "New task started with id: $task_id\n");
});

$server->on('Task', function (Swoole\Server $server, $task_id, $reactorId, $data)
{
    echo "Task Worker Process received data";

    echo "#{$server->worker_id}\tonTask: [PID={$server->worker_pid}]: task_id=$task_id, data_len=" . strlen($data) . "." . PHP_EOL;

    $server->finish($data);
});

$server->on('Finish', function (Swoole\Server $server, $task_id, $data)
{
    echo "Task#$task_id finished, data_len=" . strlen($data) . PHP_EOL;
});

$server->on('workerStart', function ($server, $worker_id)
{
    if($worker_id >= $server->setting['worker_num'])
    {
        swoole_set_process_name("php {$argv[0]}: task_worker");
    }
    else
    {
        swoole_set_process_name("php {$argv[0]}: worker");
    }
});

$server->start();
Last updated on August 31, 2022