Как создать несколько развлечений с CO_SPAWN, которые работают одновременно в ожидании результатов в другой COROUTINE в C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как создать несколько развлечений с CO_SPAWN, которые работают одновременно в ожидании результатов в другой COROUTINE в

Сообщение Anonymous »

Я пытаюсь реализовать трубопровод HTTP 1.1 с использованием Boost Asio, Boost Beast и Coroutines. />
После получения запроса он порождает новую Coroutine для обработки запроса с помощью CO_SPAWN (исполнитель, обработчик (запрос), use_awaitable) < /code> и отправляет полученный ожидаемый ожидаемый в кораутину ответы через канал. Коратики (к моему удивлению) не выполняются одновременно.

Я вставил в свой обработчик 1 секунду (который ожидается, так что это не должно остановить исполнение), что сделало это легко. Эти обработчики выполняются одновременно, в то же время способным получить результаты?

Я думал об использовании каналов (и использовании отдельных < /code> вместо use_awaitable < /code>) для этого тоже, но это также кажется немного излишним, и, как у меня, где-то не понимается. PrettyPrint-Override ">auto operator()(auto stream, std::stop_token stop_token) noexcept -> boost::asio::awaitable
{
auto executor = co_await boost::asio::this_coro::executor;
boost::asio::experimental::channel channel(executor, response_queue_size_);
boost::asio::co_spawn(executor, response_worker(channel, stream), boost::asio::detached);

std::stop_callback stop_callback(stop_token, [&]() {
boost::asio::co_spawn(executor, helper::close_stream(stream), boost::asio::detached);
});

boost::asio::streambuf buffer{};
while (!stop_token.stop_requested()) {
boost::beast::http::request_parser parser{};

const auto [ec, _] = co_await boost::beast::http::async_read_header(stream, buffer, parser, boost::asio::as_tuple(boost::asio::deferred));

if (!channel.is_open()) {
//the responder closed the channel and the stream
co_return;
}

if (ec == boost::asio::error::operation_aborted) {
//the stream is closed already
break;
}

if (ec) {
co_await helper::close_stream(stream);
break;
}

co_await channel.async_send({}, boost::asio::co_spawn(executor, handler(parser, stop_token, stream, buffer), boost::asio::use_awaitable));
}
//tell the responder to stop
co_await channel.async_send(boost::asio::error::eof, {});
}

auto response_worker(boost::asio::experimental::channel &channel, auto &stream) -> boost::asio::awaitable
{
while (true) {
auto [ec, response_awaitable] = co_await channel.async_receive(boost::asio::as_tuple);
if (ec == boost::asio::error::eof || !response_awaitable.has_value())
co_return channel.close();

http_handler_result_t handler_result = co_await *std::move(response_awaitable);

std::visit(
[&](auto &response) {
response.set(
boost::beast::http::field::keep_alive,
std::format("max={}, timeout={}", response_queue_size_, std::chrono::duration_cast(header_read_timeout_).count()));
response.set(
boost::beast::http::field::connection,
"Keep-Alive");
response.prepare_payload();
},
handler_result);
bool need_eof = std::visit(
[&](const auto &response) {
return response.need_eof();
},
handler_result);

if (const auto [ec2, _] = co_await boost::beast::async_write(
stream,
std::visit(
[](auto response) {
return boost::beast::http::message_generator{std::move(response)};
},
std::move(handler_result)),
boost::asio::as_tuple)) {
//log
}

if (need_eof) {
channel.close();
co_await helper::close_stream(stream);
co_return;
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... -while-awa
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»