I’m trying to read some data from a few web sockets at the same time:
- Sockets are independent of each other
- Frequency of inputs varies a lot between sockets
- Occasionally, I would need to redirect data from one socket to another on certain inputs.
My approach is to await on read operations in parallel using awaitable operator ||
.
Consider the following pseudocode:
#include <boost/asio/experimental/awaitable_operators.hpp>
using namespace boost::asio::experimental::awaitable_operators;
auto stream1 = provider->get_stream_type1();
auto stream2 = provider->get_stream_type2();
while (true) {
auto parallel_group = co_await (stream1->read() || stream2->read());
const auto completed_index = parallel_group.index();
std::string response{};
if (completed_index == 0) response = std::get<0>(parallel_group);
else if (completed_index == 1) response = std::get<1>(parallel_group);
else throw std::runtime_error("unknown index");
process(response);
}
The issue is that operator ||
cancels all outstanding operations when any op succeeds. In my case, I would need to reconnect websocket back, which is rather expensive and does not sound right in general. What I’m doing wrong? What would be a better approach?
you can use operator&&
instead, or not make the parallel group at all (just co_spawn separate operations, since, you know, they are separate).
Further Thought
How you planned to fulfill your requirements (“Occasionally, I would need to redirect data from one socket to another on certain inputs”) is unclear to me.
I think you accidentally work on a too-low level of abstraction here. What you want parallelized is not individual read operations, but rather the entire websocket sessions.
Once you do, you might use channels to coordinate traffic between sessions.
3