Git Product home page Git Product logo

bjo's Introduction

bjo

Данная библиотека призвана упростить процесс написания асинхронных приложений, использующих boost::asio и boost::beast. Использование bjo делает c++ код, решающий типовые высокоуровневые задачи, более читабельным и простым для восприятия, без ущерба производительности.

Библиотека bjo предоставляет удобные и эффективные абстракции для написания асинхронных приложений. Приоритетный способ написания асинхронного кода в bjo - это корутины, которые вошли в стандарт языка C++ в 2020 году. Предполагается, что пользователь библиотеки будет использовать именно их, в процессе написания кода, несмотря на то, что альтернативные подходы к написанию асинхронного кода тоже поддерживаются.

Установка

Чтобы использовать библиотеку в своем C++ проекте, ее нужно подключить как CMake подпроект:

add_subdirectory(bjo)
include_directories(bjo/include)
target_link_libraries(${PROJECT_NAME} bjo)

И установить зависимости с помощью conan.

conan install <путь до conanfile.txt, который лежит в папке с библиотекой>

Что такое корутины?

Корутина - это функция, которая может приостановить свое выполнение на какое-то время или до наступления какого-то события, а после возобновиться с того места, где была приостановлена.

Корутины позволяют писать асинхронный код, который выглядит как синхронный. Это очень круто, честно.

Как написать корутину в boost::asio

  • Чтобы ваша функция стала корутиной, нужно чтобы она возвращала boost::asio::awaitable<ТИП ДАННЫХ> (на самом деле много чего другого, но на базовом уровне этого хватает). После этого, в ее теле станет возможно использовать такие ключевые слова как co_return и co_await. Но! уже нельзя использовать обычный return.
  • Чтобы запустить свою корутину, ее нужно создать(заспавнить) в executor-e. Для этого нужно написать следующий код:
boost::asio::co_spawn(
        экземпляр io_context, или другой executor из asio,
        вызов вашей корутины, 
        указать completion_token  
);

Для работы с c++20 корутинами используются 2 токена:

  • boost::asio::use_awaitable - для того, чтобы иметь возможность отпустить контекст, до тех пор, пока задача не будет выполнена
  • boost::asio::detached - отправить корутину в "свободное плавание". Заспавнить ее в исполнителе и никак не дожидаться ее завершения

Основные компоненты фреймворка:

bjo::TaskProcessor

Важнейшим классом библиотеки является TaskProcessor, который представляет собой обертку над boost::asio::io_context, позволяющую исполнять асинхронные задачи в собственном пуле потоков, не блокируя вызвавший поток.

Зачем это нужно?

Иногда в асинхронном приложении может возникать необходимость запустить сложные CPU-bound вычисления, или обратиться к БД. Возникает проблема. Например, если запустить такую операцию в потоке, принимающем новые соединения (предположим, что мы пишем http-сервер) мы заблокируемся до окончания тяжелой операции. Это чревато тем, что мы перестанем обслуживать клиентов на какое-то время.

Исполнение задач в разных TaskProcessor-ах решает данную проблему. Пользователь библиотеки может определить TaskProcessor-ы на типы решаемых задач и запускать таски(корутины, коллбэки, футуры) в соответствующих Executor-ах.

Что ещё?

Пользователь может выбрать то, каким образом запустить асинхронную задачу. Можно использовать как стандартные корутины, так и std::future или классические callback-и.

Пример использования:

// Run task in detached mode. Don't wait completion.
 task_processor_.ProcessTask(Listen(), asio::detached); 

// When we need to perform task in another executor and fetch results.
auto result =  co_await task_processor_.ProcessTask(Coro(), asio::use_awaitable);

// using futures
std::future<Тип> res = task_processor_.ProcessTask(FutureTask(), asio::use_future);
// to get results type res.get() 

bjo::http::Server

bjo предоставляет пользователю удобную и эффективную высокоуровневую абстракцию, позволяющую реализовывать http серверы.

Как этим пользоваться?

Для того чтобы запустить http::Server в bjo нужно:

  • Задать обработчики на соответствующие таргеты
  • Зарегистрировать их в сервере
  • Запустить сервер

ПРИМЕР СОЗДАНИЯ СЕРВЕРА:

namespace asio = boost::asio;
namespace http = bjo::http;

  http::Server server(http::server::DefaultConfig());
  
  server.RegisterHandlers()
      (http::METHODS::GET, http::server::Route<"/">(), AsClass{})
      (http::METHODS::GET | http::METHODS::POST, http::server::Route<"/users/id=[0-9]+">(), AsFunc)
      (http::METHODS::GET, http::server::Route<"/values">(),
        [](const http::Request& req) -> asio::awaitable<http::Response> {
          // Handler can be implemented as lambda
        }
      )
  ;
  
  server.Serve(); // starts server

ВАЖНО

  • Обработчик http запроса должен иметь сигнатуру вида asio::awaitable< http::Response > (const http::Request& req)
  • Объект типа http::server::Route принимает шаблонным параметром регулярное выражение, описывающее паттерн, с которым будет сравниваться роут из заголовка

ПРИМЕР ОБРАБОТЧИКА

namespace asio = boost::asio;
namespace http = bjo::http;

// As Function
asio::awaitable<http::Response> AsFunction(const http::Request& req);


// As Lambda, that returns asio::awaitable<bjo::http::Response>
[](const http::Request& req) -> asio::awaitable<http::Response> {} 


// As Class
struct Handler {
    asio::awaitable<http::Response> operator()(const http::Request& req) {} 
};

bjo::http::Request и bjo::http::Response

Классы bjo::http::Request и bjo::http::Response - это alias-ы для реализаций из boost::beast.

bjo's People

Contributors

bersen66 avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.