Я пытаюсь реализовать трубопровод 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
Как создать несколько развлечений с CO_SPAWN, которые работают одновременно в ожидании результатов в другой COROUTINE в ⇐ C++
Программы на C++. Форум разработчиков
1753323681
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;
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79703473/how-do-i-spawn-multiple-coroutines-with-co-spawn-that-run-concurrently-while-awa[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия