boost::redis::connection::async_receive2 :: Boost.Redis

# boost::redis::connection::async_receive2

Wait for server pushes asynchronously.

## Synopsis

Declared in `<boost/redis/connection.hpp>`

    template<class CompletionToken = asio::deferred_t>
    auto
    async_receive2(CompletionToken&& token = {});

## Description

This function suspends until at least one server push is received by the connection. On completion an unspecified number of pushes will have been added to the response object set with `set_receive_response`. Use the functions in the response object to know how many messages they were received and consume them.

To prevent receiving an unbound number of pushes the connection blocks further read operations on the socket when 256 pushes accumulate internally (we don't make any commitment to this exact number). When that happens any `async_exec`s and health‐checks won't make any progress and the connection may eventually timeout. To avoid this, apps that expect server pushes should call this function continuously in a loop.

This function should be used instead of the deprecated `async_receive`. It differs from `async_receive` in the following:

- `async_receive` is designed to consume a single push message at a time. This can be inefficient when receiving lots of server pushes. `async_receive2` is batch‐oriented. All pushes that are available when `async_receive2` is called will be marked as consumed.

- `async_receive` is cancelled when a reconnection happens (e.g. because of a network error). This enabled the user to re‐establish subscriptions using `async_exec` before waiting for pushes again. With the introduction of functions like `request::subscribe`, subscriptions are automatically re‐established on reconnection. Thus, `async_receive2` is not cancelled on reconnection.

- `async_receive` passes the number of bytes that each received push message contains. This information is unreliable and not very useful. Equivalent information is available using functions in the response object.

- `async_receive` might get cancelled if `async_run` is cancelled. This doesn't happen with `async_receive2`.

This function does not remove messages from the response object passed to `set_receive_response`

- use the functions in the response object to achieve this.

Only a single instance of `async_receive2` may be outstanding for a given connection at any time. Trying to start a second one will fail with `error::already_running`.

| To avoid deadlocks the task (e.g. coroutine) calling `async_receive2` should not call `async_exec` in a way where they could block each other. This is, avoid the following pattern:

    asio::awaitable<void> receiver()
    {
       // Do NOT do this!!! The receive buffer might get full while
       // async_exec runs, which will block all read operations until async_receive2
       // is called. The two operations end up waiting each other, making the connection unresponsive.
       // If you need to do this, use two connections, instead.
       co_await conn.async_receive2();
       co_await conn.async_exec(req, resp);
    }

For an example see cpp20_subscriber.cpp.

The completion token must have the following signature:

    void f(system::error_code);

## Per‐operation cancellation

This operation supports the following cancellation types:

- `asio::cancellation_type_t::terminal`.

- `asio::cancellation_type_t::partial`.

- `asio::cancellation_type_t::total`.

## Parameters

Name | Description
--- | ---
token | Completion token.

Created with MrDocs