asio::awaitable< void >
producer(asio::experimental::channel< void(error_code, std::string) > &chan)
{
for (int i = 1; i <= 100; ++i)
{
auto str = fmt::format("message {}", i);
if (!chan.try_send(error_code(), str))
co_await chan.async_send(
error_code(), std::move(str), asio::deferred);
}
// this is a proxy for an async_close
if (!chan.try_send(error_code(asio::error::eof), std::string()))
co_await chan.async_send(
error_code(asio::error::eof), std::string(), asio::deferred);
// chan.close();
}
If the explicit async_send of the error is removed and the chan.close() is uncommented, then the consumer will miss messages produced by this producer. In my test case I initialised the channel with a buffer space of 100 messages. In that case, the consumer didn't receive any messages.
It seems to me that it would be more correct either:
modify close() so that it inserts a marker into the internal queue to close after the most recent sent message, or
add an async_close() method, or
add an async_flush() method
2 & 3 would allow the producer to coincide the closure of the channel with the consumption of the last message sent prior to the close.
Please consider this simple producer:
If the explicit async_send of the error is removed and the chan.close() is uncommented, then the consumer will miss messages produced by this producer. In my test case I initialised the channel with a buffer space of 100 messages. In that case, the consumer didn't receive any messages. It seems to me that it would be more correct either:
2 & 3 would allow the producer to coincide the closure of the channel with the consumption of the last message sent prior to the close.