{"id":19601289,"url":"https://github.com/bersen66/bjo","last_synced_at":"2025-10-07T16:11:18.995Z","repository":{"id":62171553,"uuid":"537476740","full_name":"bersen66/bjo","owner":"bersen66","description":"set of utilities for writing rest services on cpp20","archived":false,"fork":false,"pushed_at":"2023-02-21T16:44:24.000Z","size":144,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-09T08:18:09.955Z","etag":null,"topics":["asio","asio-library","asynchronous-programming","asynchronous-tasks","beast","cpp20-library","ctre","http","multithreaded-server","rest-api","restful-api"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bersen66.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-09-16T13:46:35.000Z","updated_at":"2024-09-10T05:48:36.000Z","dependencies_parsed_at":"2023-01-20T19:18:59.375Z","dependency_job_id":null,"html_url":"https://github.com/bersen66/bjo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"bersen66/project-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bersen66%2Fbjo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bersen66%2Fbjo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bersen66%2Fbjo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bersen66%2Fbjo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bersen66","download_url":"https://codeload.github.com/bersen66/bjo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240879579,"owners_count":19872391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asio","asio-library","asynchronous-programming","asynchronous-tasks","beast","cpp20-library","ctre","http","multithreaded-server","rest-api","restful-api"],"created_at":"2024-11-11T09:17:50.906Z","updated_at":"2025-10-07T16:11:13.971Z","avatar_url":"https://github.com/bersen66.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bjo\n\nДанная библиотека призвана упростить процесс написания асинхронных приложений,\nиспользующих\n```boost::asio``` и ```boost::beast```. Использование bjo делает c++ код,\nрешающий типовые высокоуровневые задачи, более\nчитабельным и\nпростым для восприятия, без ущерба производительности.\n\nБиблиотека bjo предоставляет удобные и эффективные абстракции для написания\nасинхронных приложений. Приоритетный способ\nнаписания асинхронного кода в bjo - это корутины,\nкоторые вошли в стандарт языка C++ в 2020 году. Предполагается, что пользователь\nбиблиотеки будет использовать именно\nих, в процессе написания кода, несмотря на то, что\nальтернативные подходы к написанию асинхронного кода тоже поддерживаются.\n\n# Установка\n\nЧтобы использовать библиотеку в своем C++ проекте, ее нужно подключить как CMake\nподпроект:\n\n```cmake\nadd_subdirectory(bjo)\ninclude_directories(bjo/include)\ntarget_link_libraries(${PROJECT_NAME} bjo)\n```\n\nИ установить зависимости с помощью ```conan```.\n\n```shell\nconan install \u003cпуть до conanfile.txt, который лежит в папке с библиотекой\u003e\n```\n\n## Что такое корутины?\n\nКорутина - это функция, которая может приостановить свое выполнение на какое-то\nвремя или до наступления какого-то\nсобытия,\nа после возобновиться с того места, где была приостановлена.\n\nКорутины позволяют писать асинхронный код, который выглядит как синхронный. Это\nочень круто, честно.\n\n## Как написать корутину в boost::asio\n\n* Чтобы ваша функция стала корутиной, нужно чтобы она\n  возвращала ```boost::asio::awaitable\u003cТИП ДАННЫХ\u003e``` (на самом деле много чего\n  другого, но на базовом уровне этого хватает).\n  После этого, в ее теле станет возможно использовать такие ключевые слова\n  как ```co_return``` и ```co_await```. Но! уже\n  нельзя использовать\n  обычный ```return```.\n* Чтобы запустить свою корутину, ее нужно создать(заспавнить) в executor-e. Для\n  этого нужно написать следующий код:\n\n```c++\nboost::asio::co_spawn(\n        экземпляр io_context, или другой executor из asio,\n        вызов вашей корутины, \n        указать completion_token  \n);\n```\n\n* Про completion_token-ы написано здесь:\n  https://www.boost.org/doc/libs/develop/doc/html/boost_asio/overview/model/completion_tokens.html\n\nДля работы с c++20 корутинами используются 2 токена:\n\n* ```boost::asio::use_awaitable``` - для того, чтобы иметь возможность отпустить\n  контекст, до тех пор, пока задача не\n  будет выполнена\n* ```boost::asio::detached``` - отправить корутину в \"свободное плавание\".\n  Заспавнить ее в исполнителе и никак не\n  дожидаться ее завершения\n\n## Основные компоненты фреймворка:\n\n### bjo::TaskProcessor\n\nВажнейшим классом библиотеки является ```TaskProcessor```, который представляет\nсобой обертку\nнад ```boost::asio::io_context```, позволяющую исполнять асинхронные задачи в\nсобственном пуле потоков, не блокируя\nвызвавший поток.\n\n#### Зачем это нужно?\n\nИногда в асинхронном приложении может возникать необходимость запустить сложные\nCPU-bound вычисления, или обратиться к\nБД.\nВозникает проблема. Например, если запустить такую операцию в потоке,\nпринимающем новые соединения (предположим, что мы\nпишем http-сервер) мы заблокируемся до окончания тяжелой операции.\nЭто чревато тем, что мы перестанем обслуживать клиентов на какое-то время.\n\nИсполнение задач в разных TaskProcessor-ах решает данную проблему. Пользователь\nбиблиотеки может определить\nTaskProcessor-ы на типы решаемых задач и\nзапускать таски(корутины, коллбэки, футуры) в соответствующих Executor-ах.\n\n#### Что ещё?\n\nПользователь может выбрать то, каким образом запустить асинхронную задачу. Можно\nиспользовать как стандартные корутины,\nтак и ```std::future``` или классические callback-и.\n\n#### Пример использования:\n\n```c++\n// Run task in detached mode. Don't wait completion.\n task_processor_.ProcessTask(Listen(), asio::detached); \n\n// When we need to perform task in another executor and fetch results.\nauto result =  co_await task_processor_.ProcessTask(Coro(), asio::use_awaitable);\n\n// using futures\nstd::future\u003cТип\u003e res = task_processor_.ProcessTask(FutureTask(), asio::use_future);\n// to get results type res.get() \n```\n\n### bjo::http::Server\n\nbjo предоставляет пользователю удобную и эффективную высокоуровневую абстракцию,\nпозволяющую реализовывать http серверы.\n\n#### Как этим пользоваться?\n\nДля того чтобы запустить http::Server в bjo нужно:\n\n* Задать обработчики на соответствующие таргеты\n* Зарегистрировать их в сервере\n* Запустить сервер\n\n#### ПРИМЕР СОЗДАНИЯ СЕРВЕРА:\n\n```c++\nnamespace asio = boost::asio;\nnamespace http = bjo::http;\n\n  http::Server server(http::server::DefaultConfig());\n  \n  server.RegisterHandlers()\n      (http::METHODS::GET, http::server::Route\u003c\"/\"\u003e(), AsClass{})\n      (http::METHODS::GET | http::METHODS::POST, http::server::Route\u003c\"/users/id=[0-9]+\"\u003e(), AsFunc)\n      (http::METHODS::GET, http::server::Route\u003c\"/values\"\u003e(),\n        [](const http::Request\u0026 req) -\u003e asio::awaitable\u003chttp::Response\u003e {\n          // Handler can be implemented as lambda\n        }\n      )\n  ;\n  \n  server.Serve(); // starts server\n\n```\n\n#### ВАЖНО\n\n* Обработчик http запроса должен иметь сигнатуру\n  вида ```asio::awaitable\u003c http::Response \u003e (const http::Request\u0026 req)```\n* Объект типа http::server::Route принимает шаблонным параметром регулярное\n  выражение, описывающее паттерн, с которым будет сравниваться роут из заголовка\n\n#### ПРИМЕР ОБРАБОТЧИКА\n\n```c++\nnamespace asio = boost::asio;\nnamespace http = bjo::http;\n\n// As Function\nasio::awaitable\u003chttp::Response\u003e AsFunction(const http::Request\u0026 req);\n\n\n// As Lambda, that returns asio::awaitable\u003cbjo::http::Response\u003e\n[](const http::Request\u0026 req) -\u003e asio::awaitable\u003chttp::Response\u003e {} \n\n\n// As Class\nstruct Handler {\n    asio::awaitable\u003chttp::Response\u003e operator()(const http::Request\u0026 req) {} \n};\n```\n\n### bjo::http::Request и bjo::http::Response\n\nКлассы ```bjo::http::Request``` и ```bjo::http::Response``` - это alias-ы для\nреализаций из boost::beast. \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbersen66%2Fbjo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbersen66%2Fbjo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbersen66%2Fbjo/lists"}