Coroutine Client Timeout Setup

Latest version: pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5

All network requests (establish a connection, send data and receive data) may time out. This client has a few ways for how you can setup timeouts.

This timeout guide relates to the following coroutine Clients and API:

  • TCP/UDP Client
  • Coroutine Socket Client
  • HTTP/2 Clients
  • PostgreSQL Client
  • FastCGI Client
  • Coroutine System API

Method One: Direct Parameters

Most of the coroutine enabled clients allow you to pass in a $timeout parameter as a float, so 1.5 will mean 1.5 seconds. This is the direct way to set a timeout but it must be set each time, so it is not very flexible.


Method Two: Using class set configuration

Each OpenSwoole coroutine client can be configured before being used, this allows you to setup things like SSL or EOF checking etc. But it also allows you to set global timeout options for the class instance that is created.

Let's go through some examples:

Coroutine Enabled Clients

<?php

// Our coroutine enabled clients can be created like so...
$client1 = new Co\Client(OpenSwoole\Constant::SOCK_TCP);
$client2 = new Co\Http\Client("127.0.0.1", 80);
$client3 = new Co\Http2\Client("127.0.0.1", 443, true);

// Each client has its OWN configuration...
$client->set([
    'timeout' => 0.5,
    'connect_timeout' => 1.0,
    'write_timeout' => 10.0,
    'read_timeout' => 0.5,
]);

Each client as seen in the example is created and each instance can set its own timeout configuration. This means these options are global for that client only.

  • timeout: Total timeout, including all timeouts for connecting, sending, and receiving
  • connect_timeout: If set, the connection timeout will overwrite the total timeout
  • write_timeout: If set, the sending timeout, will overwrite the total timeout
  • read_timeout: If set, the receive timeout, will overwrite the total timeout

MySQL and Redis

It is recommended to use coroutine hooks and use the native clients built for PHP to use MySQL or Redis, refer to their own documentation for timeout configuration/setup.

The disadvantage of using global class configuration is that the timeout is only valid for that specific instance, so the timeout has to be set per client, per class.


Method Three: Global Coroutine Configuration

When you have coroutines enabled on your server, you can set global coroutine configuration options. These are set using Co::set(...). In order for a more permanent, global timeout configuration, we can set timeout options using the socket configuration.

<?php

Co::set([
    'socket_timeout' => 60,
    'socket_connect_timeout' => 2,
    'socket_read_timeout' => 1,
    'socket_write_timeout' => 1,
]);

Because this method is directly changing configuration options for coroutines, this will affect the coroutine clients, so there will then be no need to set timeouts again once this is done, these options last for the lifetime of the running program. Refer to coroutine documentation for more information.

Coroutine Configuration Considerations

  • Setting -1 will mean never to timeout, always wait

  • Setting 0 means that the timeout period will not be changed

  • Values greater than 0 will indicate to set the timeout timer corresponding to the number of seconds. A float of 0.5 represents 500ms.

  • The configuration socket_connect_timeout indicates the TCP connection timeout, by default 2 seconds

  • The configuration socket_timeout is the TCP read/ write operation timeout, by default it is 60 seconds. If you want to set read and write separately, use the separate options for read and write.

  • The configuration socket_read_timeout is for setting the TCP read operation timeout, the default is 60 seconds

  • The configuration socket_write_timeout is for setting the TCP write operation timeout, the default is 60 seconds

As coroutine options with Co::set() can be changed dynamically, be careful because if the client is created before Co::set() is used, the options won't take affect.


Native PHP Socket Timeout

If you are using coroutine hooks, you can use the native PHP socket classes, which means you can set a default timeout using default_socket_timeout.

So you are able to set ini_set('default_socket_timeout', 60) which will affect the timeout when using native PHP sockets and coroutine hooks.

Last updated on September 20, 2022