mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Fixes async_exec terminal cancellation.
This commit is contained in:
17
README.md
17
README.md
@@ -47,17 +47,16 @@ that ensures that one operation is cancelled as soon as the other
|
||||
completes, these functions play the following roles
|
||||
|
||||
* `connection::async_exec`: Execute commands by writing the request payload to the underlying stream and reading the response sent back by Redis. It can be called from multiple places in your code concurrently.
|
||||
* `connection::async_run`: Coordinate the low-level IO (read and write) operations and remains suspended until the connection is lost.
|
||||
* `connection::async_run`: Coordinate the low-level IO (read and write) operations. It remains suspended until the connection is lost.
|
||||
|
||||
When a connection is lost, the `async_exec` calls won't automatically
|
||||
fail, instead, they will remain suspended until they are either all
|
||||
canceled with a call to `connection::cancel(operation::exec)` or a new
|
||||
connection is established and `async_run` is called again, in which
|
||||
case they will be resent automatically. Users can customise this
|
||||
behaviour by carefully choosing the values of
|
||||
The `async_exec` calls won't automatically fail when the connection is
|
||||
lost, instead, they will remain suspended until either
|
||||
`connection::cancel(operation::exec)` is called to cancel them all or
|
||||
a new connection is established and `async_run` is called again.
|
||||
Users can customise the desired behaviour by carefully choosing
|
||||
`aedis::resp3::request::config`. The role played by `async_run`
|
||||
becomes clearer with long-lived connections, which we will cover
|
||||
in the next section.
|
||||
becomes clearer with long-lived connections, which we will cover in
|
||||
the next section.
|
||||
|
||||
<a name="connection"></a>
|
||||
## Connection
|
||||
|
||||
@@ -139,9 +139,18 @@ EXEC_OP_WAIT:
|
||||
|
||||
if (is_cancelled(self)) {
|
||||
if (info->is_written()) {
|
||||
self.get_cancellation_state().clear();
|
||||
goto EXEC_OP_WAIT; // Too late, can't cancel.
|
||||
if (self.get_cancellation_state().cancelled() == boost::asio::cancellation_type_t::terminal) {
|
||||
// Cancellation requires closing the connection
|
||||
// otherwise it stays in inconsistent state.
|
||||
conn->cancel(operation::run);
|
||||
return self.complete(ec, 0);
|
||||
} else {
|
||||
// Can't implement other cancelation types, ignoring.
|
||||
self.get_cancellation_state().clear();
|
||||
goto EXEC_OP_WAIT;
|
||||
}
|
||||
} else {
|
||||
// Cancelation can be honored.
|
||||
conn->remove_request(info);
|
||||
self.complete(ec, 0);
|
||||
return;
|
||||
|
||||
@@ -110,7 +110,7 @@ auto ignore_implicit_cancel_of_req_written() -> net::awaitable<void>
|
||||
// Will be cancelled before it is written.
|
||||
resp3::request req2;
|
||||
req2.get_config().coalesce = false;
|
||||
//req2.get_config().cancel_on_connection_lost = true;
|
||||
req2.get_config().cancel_on_connection_lost = true;
|
||||
req2.push("PING");
|
||||
|
||||
net::steady_timer st{ex};
|
||||
@@ -123,11 +123,9 @@ auto ignore_implicit_cancel_of_req_written() -> net::awaitable<void>
|
||||
st.async_wait(redir(ec3))
|
||||
);
|
||||
|
||||
BOOST_TEST(!ec1);
|
||||
BOOST_CHECK_EQUAL(ec1, net::error::basic_errors::operation_aborted);
|
||||
BOOST_CHECK_EQUAL(ec2, net::error::basic_errors::operation_aborted);
|
||||
BOOST_TEST(!ec3);
|
||||
|
||||
conn->cancel(operation::run);
|
||||
}
|
||||
|
||||
auto cancel_of_req_written_on_run_canceled() -> net::awaitable<void>
|
||||
|
||||
Reference in New Issue
Block a user