Показаны сообщения с ярлыком RESTinio. Показать все сообщения
Показаны сообщения с ярлыком RESTinio. Показать все сообщения

суббота, 26 апреля 2025 г.

[prog.c++] Еще раз вспомнил про easy_parser из RESTinio

Потребовалось намедни разобрать строку, в которой содержатся разделенные запятыми неотрицательные целые числа. Делал такое недавно посредством std::regex и мне не понравилось. Скорее всего потому, что и с регулярными выражениями на "Вы", и интерфейс std::regex в C++, по моим ощущениям, делали какие-то инопланетяне (не, наверное там все сделано по уму и с прицелом на сценарии, которые мне даже и не снились). Но когда прикасаешься к std::regex раз в два года, то как-то все слишком сложно 🙁

В общем, не понравился мне недавний опыт.

Тут-то и вспомнилась штука, которую мы делали в RESTinio для упрощения разбора HTTP-заголовков. easy_parser называется.

Вспомнилась, решил восстановить в памяти, полез смотреть что и как...

Слегка прифигел от собственной крутизны 🙂

Начать с того, что эта штука была описана. Да, не сильно подробно, но основные принципы изложены. Чтобы вспомнить что к чему этого хватило. Плюс к тому рассказывали про easy_parser на Хабре на русском (здесь, но и здесь есть немного). Т.е. понять как пользоваться можно из описаний, а не из разрозненных демонстрационных примеров.

Продолжить можно тем, что построен easy_parser на простых идеях: есть producer-ы, которые производят значения из разобранного текста, есть consumer-ы, которые потребляют произведенные значения. Связь producer-а и consumer-а образует выражение (clause). Можно делать составных producer-ов из последовательности clause-ов. Вот, собственно, и все.

Если вникнуть в эту незамысловатую схему, то дальше сложностей не возникает.

Да, конечно, когда в дело вступают transformer-ы, или когда нужно порождать не единичные значения, а наборы значений (std::vector чего-нибудь, к примеру), то потребуется въехать чуть поглубже. Но тоже не сказать, чтобы архисложно.

Ну и закончить можно тем, что самое удивительное, что такая, не побоюсь этого слова, мощная и полезная для меня лично штука, появилась меньше чем за месяц как побочный эффект решения совсем другой задачи. Парсить HTTP-заголовки можно было разными способами. Но вот как-то так получилось, что был сделан собственный лисапед для PEG-грамматик, на котором все это дело и поехало.

Причем применялся easy_parser затем еще несколько раз именно как инструмент для парсинга. Примеры можно найти в нашем arataga. Мне лично нравится вот этот фрагмент, он предназначен для разбора вот таких вот выражений.

Но это было давно. Последний раз прикасался к easy_parser, если мне не изменяет склероз, в декабре 2023-го года.

Сейчас же решил воспользоваться еще раз и был снова приятно поражен тем, насколько же это все неплохо, а скорее даже и хорошо. На мой вкус, конечно же. А мои вкусы несколько специфичны ©

Вот что было сделано чтобы разобрать строку с последовательностью чисел, разделенных запятыми:

[[nodiscard]]
std::vector<std::size_t>
extractDimsSizeListFromStr(std::string_view listAsStr)
{
   namespace ep = restinio::easy_parser;

   auto parser = ep::produce< std::vector<std::size_t> >(
            ep::non_negative_decimal_number_p<std::size_t>() >> ep::to_container(),
            ep::repeat(0, ep::N,
               ep::symbol(','),
               ep::non_negative_decimal_number_p<std::size_t>() >> ep::to_container())
         );


   const auto parsingResult = ep::try_parse(listAsStr, parser);
   if(!parsingResult)
   {
      throw std::invalid_argument{ "Unable to parse list of dimensions size ("
         + ep::make_error_description(parsingResult.error(), listAsStr)
         + ")"
      };
   }

   return std::move(*parsingResult);
}

Ключевой момент, имеющий отношение к easy_parser, выделен жирным. Там все просто ;) Нужно получить вектор чисел. Для этого требуется одно число (которое сразу же помещается в контейнер). А за ним может быть еще 0 или более последовательностей из запятой и еще одного числа (которое сразу же записывается в контейнер).

Вот, собственно, и всё.

Конечно, ради такого простого кейса привлекать либу на трехэтажных шаблонах, пытающуюся выразить в C++ном DSL-е PEG грамматику выглядит так себе идеей.

Но я подозревал, что простого списка чисел мне окажется недостаточно.

И, действительно, буквально несколькими часами спустя этот список уже приобрел вид:

size[ '(' start [',' step] ')' [ ',' size [ '(' start [ ',' step] ')' ...]]

Т.е. каждому значению size может быть привязано два необязательных значения start и step. Если start и step есть, то они должны быть заключены в круглые скобки. Может быть либо одно значение start, либо и start, и step. В последнем случае start и step разделяются запятой.

Если я еще не забыл полностью PEG, то в PEG это должно выражаться чем-то вроде:

values := one_value (',' one_value)*
one_value := NUMBER start_step?
start_step := '(' NUMBER (',' NUMBER)? ')'

Для чего показанный выше пример был переписан вот так:

struct DimParamsFromUser {
   std::size_t _size{};
   std::optional<int> _startFrom{ std::nullopt };
   std::optional<int> _step{ std::nullopt };
};

[[nodiscard]]
std::vector<DimParamsFromUser>
extractDimsSizeListFromStr(std::string_view listAsStr)
{
   namespace ep = restinio::easy_parser;

   auto oneDimParamsP = ep::produce<DimParamsFromUser>(
            ep::non_negative_decimal_number_p<std::size_t>()
                  >> &DimParamsFromUser::_size,
            ep::maybe(
               ep::symbol('('),
               ep::non_negative_decimal_number_p<int>()
                     >> &DimParamsFromUser::_startFrom,
               ep::maybe(
                  ep::symbol(','),
                  ep::non_negative_decimal_number_p<int>()
                     >> &DimParamsFromUser::_step
               ),
               ep::symbol(')')
            )
         );

   auto parser = ep::produce< std::vector<DimParamsFromUser> >(
            oneDimParamsP >> ep::to_container(),
            ep::repeat(0, ep::N,
               ep::symbol(','),
               oneDimParamsP >> ep::to_container())
         );

   const auto parsingResult = ep::try_parse(listAsStr, parser);
   if(!parsingResult)
   {
      throw std::invalid_argument{ "Unable to parse list of sizes of dimensions ("
         + ep::make_error_description(parsingResult.error(), listAsStr)
         + ")"
      };
   }

   return std::move(*parsingResult);
}

Если присмотреться, то можно узнать чуть ли не оригинальные PEG-правила. С поправкой на то, что ()? из PEG записывается как maybe, а ()* в C++ коде выражается через repeat(0, N, ...).

Но самое, на мой взляд, красивое -- это то, что определение для переменной parser осталось практически таким же, только `std::size_t` заменили на `DimParamsFromUser`, а `non_negative_decimal_number_p` на `oneDimParamsP`.

Оно, конечно же, понятно, что каждый кулик свое болото хвалит... Но ведь лепота же! 🙂


PS. Прошу простить мне сие бахвальство, но в последние две недели занимался задачей, от которой временами мозги закипали. А вот этот эксперимент с easy_parser стал неожиданной и приятной отдушиной, отсюда и избыток эмоций.

понедельник, 13 ноября 2023 г.

[prog.c++] Несколько слов про реализацию цепочек асинхронных обработчиков в RESTinio-0.7.0

Этот пост можно рассматривать и как логическое продолжение поста "Наглядная иллюстрация на тему "ушел рисовать каракули на бумаге"..." и как дополнение к релизу RESTinio-0.7.0, где появились цепочки асинхронных обработчиков. Здесь я попытаюсь рассказать почему эти самые цепочки получились именно такими.

Текста будет много, кода и картинок не будет вообще. Кому не лень в это все погружаться, милости прошу под кат.

пятница, 29 сентября 2023 г.

[prog.c++] Список встраиваемых в C++ приложения HTTP-серверов написанных на C++ (сентябрь 2023)

Стало уже традицией публиковать в блоге подобный список. Для меня это очень удобно: если в каком-то обсуждении нужно показать, куда смотреть, если потребовалось реализовать HTTP-точку входа в приложение, то достаточно поискать по блогу.

Но все течет, все изменяется. Кто-то прекращает свое существование, кто-то появляется и становится новым "царем горы". Поэтому публикую очередную подборку. Вроде бы все нижеперечисленное подает признаки жизни и имеет не одну сотню (тысячу) звезд на GitHub-е.

Специально не даю никаких своих комментариев по поводу перечисленного, т.к. чукча не читатель (пользователь), чукча писатель (т.е. разработчик одного из перечисленных). Но к тем, кто сходу советует "бери Boost.Beast и не парься" отношусь с неодобрением ;)

И да, список отсортирован по алфавиту, так что в порядке следования названий никакого другого смысла искать не стоит. Но все должны знать, что выбирать и поддерживать следует RESTinio :))). Да, это неприкрытая реклама. Да, проплаченная мной. Да, могу себе позволить! ;)

Список не претендует на полноту, это лишь то, о чем я наслышан.

Это только чисто С++ные разработки. Инструменты, написанные на чистом Си, но которые могут использоваться и из C++ (вроде CivetWeb и Mongoose) сюда не включены намеренно.

среда, 5 апреля 2023 г.

[prog.c++] Очередное небольшое обновление для RESTinio

Благодаря одному из пользователей RESTinio получил обновление, исправляющее проблему с обработкой запросов с сжатым посредством zlib телом. Новая версия 0.6.18 уже доступна через Conan и vcpkg, так что есть смысл обновиться.

У меня лично работа над этим обновлением вызвала довольно сильные эмоции.

Был рад получить еще одно подтверждение тому, что RESTinio все еще используется (и, как я понял, используется активно и в нагруженных проектах). Даже не смотря на то, что дальнейшую разработку мы уже пару лет как поставили на паузу. Тем не менее, проект поддерживается, мы реагируем на открытые issue и сделанные PR.

Однако, время от времени кто-то говорит, что RESTinio, мол, не выглядит живым. Что неприятно, т.к. не соответствует действительности: проект никто не бросал и, уж тем более, не хоронил.

Посему отрадно узнавать, что RESTinio продолжает использоваться. Мелочь, а приятно ;)

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

Когда шла активная разработка RESTinio это не ощущалось. Подумаешь, очередная фича, очередной тест, очередной раздел в документации. Но вот когда заглядываешь под капот RESTinio в первый раз за последние полгода, то несколько офигеваешь от того, сколько же всего было сделано. Даже не верится, что это все мы...

PS. Дальнейшая разработка RESTinio приостановлена потому, что у нас пока нет собственных средств на ее дальнейшую разработку. Сам по себе RESTinio денег не приносит, а ведь жить на что-то надо, поэтому пока что наше время тратится на другие проекты. Но, если кто-то хочет видеть в RESTinio какую-то функциональность и готов это проспонсировать, то возобновление работ на RESTinio можно предметно обсудить ;)

понедельник, 30 января 2023 г.

[memories:prog,work,life] Фотография шестилетней давности...

Facebook любезно напомнил фотографию из января 2017-го года:

Это самое начало проекта RESTinio, я даже не уверен, что у нас уже к тому времени было само название RESTinio.

На снимке мой коллега и основной разработчик RESTinio, Николай Гродзицкий, фиксирует на доске свои идеи о том, как RESTinio будет устроена.

Насколько я помню, именно в тот день у нас в офисе сама эта доска появилась, мы ее только только повесили (внизу фото можно увидеть красный чемодан с перфоратором, приведенным в офис специально для этих целей).

Сам офис уже обжит. А за три месяца до этого было вот так:


Не знаю, что еще добавить. Разве что банальное: как же быстро летит время.

Но радует то, что все еще живы, все еще работаем. Сейчас тот же RESTinio пока вынуженно поставлен на паузу, но времена нынче непредсказуемые, невозможно предугадать куда все развернется. Так что поживем, увидим. Надеюсь, сможем сделать очередной релиз SObjectizer, а там и до RESTinio руки дойдут.

среда, 9 февраля 2022 г.

[prog.c++] Вспомнил давеча про aragata

Где-то с год назад мы открыли разработку под названием arataga. Это был прокси-сервер, который делали под специфические запросы, но который остался невостребованным. Немного о том, что, как и почему можно прочитать в посте годичной давности.

Давеча довелось вспомнить про этот проект. Ну раз довелось, то почему бы и не посвятить этой теме небольшой пост, с картинками :)

Когда открывали arataga в январе 2021-го это был всего лишь работающий прототип, протестировать который под реальной нагрузкой у нас не было возможности.

Но вот в апреле-мае 2021 такая возможность появилась.

Погоняли на реальных серверах по реальными запросами реальных пользователей, посмотрели что к чему. Что-то подшаманили и, местами, стало намного лучше. Так что arataga, по моему мнению, перешел из категории прототипов во вполне себе работающий продукт. Недостаточно проверенный реальной эксплуатацией, к сожалению, но все-таки.

О том, что было сделано в arataga по следам натурных испытаний мы даже рассказали в виде статьи на Хабре. А потом еще и сделали презентацию на тему arataga (вот она на slideshare, а отсюда ее можно взять в PDF). Так что, если кому-то интересно, то можно ознакомиться.

Я же позволю себе в этом посте опубликовать две картинки. Это скриншоты, которые я делал во время испытаний на реальном трафике.

Первая картинка -- это загрузка сервера с работающим старым прокси. Этих прокси там запущено четыре экземпляра. Такая схема была выбрана в процессе сопровождения, поскольку в единственном экземпляре нагрузку держать уже не получалось.

Интересные циферки можно увидеть: в каждом из экземпляров старого прокси работает больше 4K нативных тредов. Это то, к чему приводит использование модели thread-per-connection. Причем это еще слабо нагруженный сервер, доводилось видеть картинки, когда в каждом экземпляре работало более чем по 13K тредов и более...

Вторая картинка -- это загрузка того же сервера, но уже с работающим на нем новым aragata.


Решение открыть arataga до сих пор считаю правильным. Хотя дивидендов нам это пока никаких не принесло.

Тем не менее, пусть лежит в открытом доступе. Отличный пример того, что мы можем делать. И как мы это можем делать. Вдруг когда-то да и стрельнет.

среда, 15 декабря 2021 г.

[prog.work] Грустные впечатления от очередной сотни звезд для RESTinio

Намедни счетчик звездочек на GitHub-е для RESTinio взял еще одну сотню. И хотя GitHub-овские звездочки -- это нечто виртуальное, что на хлеб точно не намазывается, но все-таки хоть какой-то метрикой популярности/востребованности они являются.

Года три назад очередная сотня звезд вызывала гордость и доказывала, что мы делаем полезные вещи и двигаемся в верном направлении.

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

В 2021-ом году для RESTinio события развивались по худшему сценарию: внешнего финансирования мне найти не удалось, собственные ресурсы закончились, приходилось принимать решение о приостановке развития RESTinio.

Опасаясь этого я был готов готов работать над нашими OpenSource проектами за копейки, т.к. потеря денег -- это всего лишь потеря денег, а вот потерю времени восполнить невозможно. Но не сложилось. По итогу для проекта был потерян целый год.

Как будет в 2022-ом не берусь предсказывать. Надеюсь, что будет получше. Но именно с RESTinio все усугубляется тем, что там предстоит очень большой объем работы. Непросто будет обеспечить все это лишь собственными средствами. А искать где-то на стороне нет желания -- уже пробовал и пришел к выводу, что принцип "не верь, не бойся, не проси" спасает от многих разочарований и сильно экономит нервы.

В общем, пока все не просто. Желание побороться еще есть. Поскольку тут затронуты более серьезные материи, такие ощущение полноты от проживаемой жизни. Однако, это уже совсем другая история.

вторник, 23 ноября 2021 г.

[prog.c++] Небольшое обновление RESTinio с исправлением проблемы под C++20

Мы тут выкатили очередной релиз RESTinio. Ничего серьезного, но исправлена проблема при использовании RESTinio и fmt-8.0.1 под C++20. Так что теперь RESTinio может спокойно применяться и в C++20, хотя все еще остается проектом C++14.

Сама по себе новость мелкая и вряд ли заслуживала бы отдельного поста. Но есть два момента, на которые мне самому хочется обратить внимание.

Первый момент связан с тем, что уходящий год оказался для наших OpenSource проектов очень тяжелым. Внешнего финансирования для его развития мы не нашли, открытые разработки пришлось приостановить. Вообще не думал, что в 2021-ом получится хоть какие-то обновления выпускать.

В этом плане даже такой мелкий релиз лично для меня уже оказывается знаковым. Таки живем, таки творим (как бы высокопарно это не звучало).

Боюсь загадывать, но может быть какие-то небольшие обновления получится сделать и для SObjectizer, и для json-dto. По крайней мере есть хотелки и надежда, что под их реализацию найдется возможность. А для 2021-го года само по себе наличие надежды -- это, блин, ну очень редкое явление.

Второй момент связан с тем, что при разработке RESTinio мы используем SObjectizer в некоторых тестах, где требуется проверки в многопоточных сценариях. И SObjectizer в самом RESTinio применяется уже довольно старый, еще из ветки 5.5.

Так вот, я был сильно удивлен тому, что SObjectizer-5.5 спокойно и без каких-либо проблем собрался и заработал под C++20.

Вообще, с годами, стал относиться к вопросам совместимости между версиями гораздо более трепетно. Решение делать SO-5.6 с серьезным нарушением совместимости до сих пор выглядит неоднозначно. С одной стороны, это было нужно, т.к. в ветке 5.5 накопилось всякого, что уже не удавалось никак развязать. С другой стороны, лишать пользователей возможности просто так перейти на новую версию, без необходимости менять что-то в своем коде, не есть хорошо.

И тот факт, что пользователи SObjectizer-5.5, которые не имеют возможности перевести свой софт на 5.6/5.7, могут продолжать жить с SO-5.5 и под C++20, меня сильно радует. Эдакое теплое чувство внутри.

понедельник, 7 июня 2021 г.

[prog.c++] Презентация о проекте arataga на английском

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

Эта же презентация есть на SlideShare.

вторник, 2 февраля 2021 г.

[soft.business] Послесловие к неудачной попытке найти внешнее финансирование для RESTinio/SObjectizer/so5extra

На данный момент история с поиском финансирования закончилась ничем. Развитие наших OpenSource-проектов приостановлено. Попробуем поднакопить средства на заказной разработке/консультациях, чтобы затем вернуться к работам над RESTinio/SObjectizer/so5extra.

А в этом послесловии просто расскажу на что был расчет когда писался пост о поиске внешнего финансирования, может кому-то пригодится наш опыт.

Суть в том, что у SObjectizer-а и у RESTinio совершенно разные ситуации.

SObjectizer старый и устоявшийся программный продукт. Далеко не самый популярный и известный. Если его следующий релиз выйдет в конце 2021-го или даже в начале 2022-го, то отрицательно на SObjectizer-е это вряд ли скажется. А если и скажется, то не сильно.

Тогда как RESTinio -- это молодой, динамично развивающийся и еще не принявший свою окончательную форму проект. Который развивается в гораздо более конкурентной среде, чем SObjectizer.

В конце 2020-го года мы попали в ситуацию, которая, по хорошему, требует оперативного разрешения: проект http-parser, использующийся в RESTinio, остался без сопровождения. Соответственно, чтобы не зависеть от проекта без поддержки, RESTinio нужно сменить парсер HTTP-протокола на что-то другое.

Добавим сюда еще и то, что для успешной конкуренции с аналогичными проектами RESTinio очень желательно было бы иметь поддержку не только http/1.1, но и хотя бы http/2.

И если уж менять http-parser на что-то другое, то можно было бы под этим соусом добавить в RESTinio и http/2. А если получится, то и заложить возможность последующего добавления http/3.

Сложно сказать, во что бы это все вылилось по трудозатратам. Но по первым впечатлениям, от 3 до 5 месяцев это могло бы занять. Тут нужно учитывать, что мы стараемся тщательно тестировать RESTinio, писать примеры и расширять документацию. Это такая работа, которая может быть не видна, но которая должна быть выполнена, и которая занимает изрядное время. Поэтому если кому-то кажется, что 3-5 месяца для написания собственной поддержки http/1.1 и http/2 -- это слишком много, то мне лишь остается позавидовать вашей производительности и трудолюбию.

Итого, если начать работы над RESTinio-0.7 сейчас и вести их не отрываясь ни на что другое, то выкатить новую версию получится лишь где-то к лету 2021-го.

В прошлом году мы рассчитывали заработать на arataga, также в начале весны маячили на горизонте новые заказы. Но ничего этого не случилось. Поэтому у нас сейчас нет денег на то, чтобы вложиться в разработку следующей версии RESTinio.

Мы встали перед выбором: либо заняться заказной разработкой и остановить развитие RESTinio на какое-то время, либо же поискать внешние вложения.

Остановка развития RESTinio выглядела слишком рискованно. Сперва RESTinio будет заморожен на 5-6 месяцев, затем в течении еще 3-5 месяцев будет вестись разработка новой версии с релизом RESTinio-0.7 где-то через год... Отличная перспектива чтобы закопать проект.

Поэтому мы решились на поиск внешнего финансирования.

Фактически, мы пошли с протянутой рукой. Мол, сами мы не местные, помогите кто чем может.

Варианты с платной техподдержкой и "рекламными услугами" были выбраны по следующим причинам:

1. В РБ (да и в РФ) нельзя просто так взять и внести деньги на счет коммерческой структуры. Поступление денег должно быть оформлено договором. Лучше всего, если это договор на оказание каких-то услуг или на выполнение каких-то работ. Техподдержка и "рекламные услуги" как раз и являются теми формами договорных отношений, которые позволяют нам получать деньги ровно за то, что мы и делаем. И не требуют от нас ничего больше, за исключением оформления некоторого количества дополнительных бумажек раз в квартал (в виде актов по выполненным работам).

2. Суммы мы выбрали такие, которые крупные (и даже не очень крупные) компании могут выложить не задумываясь. Грубо говоря, в компании с несколькими тысячами сотрудников 150USD в квартал отдел маркетинга может запросто потратить просто "на скрепки". Мы надеялись, что сумма в 600USD в год для крупного производителя софта будет достаточно мизерной для того, чтобы ответственные люди могли дать добро на помощь нашим открытым проектам не заморачиваясь на то, что мы можем дать взамен.

Если же называть вещи своими именами, то мы рассчитывали на благотворительность.

Что нам дадут денег потому, что мы делаем полезные инструменты и отдаем их просто так с возможностью бесплатного использования в закрытых коммерческих разработках. А предлагаемые нами формы "договорных отношений" являлись лишь способом должным образом оформить эту благотворительность в глазах налоговой инспекции и других проверяющих органов. И эти договора не были бы фикцией, мы бы действительно выполняли именно то, на что подписались бы.

Эта ставка не сыграла. Внешнего финансирования мы не нашли. На техподдержку согласилась всего одна компания из тех, что используют наши открытые продукты. Ни одного положительного ответа на "рекламные услуги" в предлагаемой нами форме нет, хотя есть несколько другие варианты, но они еще требуют проработки с неочевидным для всех выхлопом.

Так что попробуем вариант с заказной разработкой. Посмотрим, что из этого выйдет. Пост о том, какие именно ресурсы мы можем выставить на рынок труда опубликую в ближайшие пару дней. Upd. Собственно, вот.

В завершении хочу поблагодарить всех, кто отозвался и попытался помочь. Огромное вам человеческое спасибо. Я лично это очень ценю. Не буду говорить пафосных фраз про "познается в беде", но ваша желание помочь лишний раз доказывает актуальность этой старой мудрости.

PS. Если какая-то компания хочет вложиться в разработку RESTinio/SObjectizer/so5extra (например, хочет поиметь какую-то специфическую функциональность), то давайте пообщаемся на eao197 на gmail тчк com. Можно обсуждать различные варианты сотрудничества.

понедельник, 25 января 2021 г.

[soft.business] Ищу финансирование для развития RESTinio/SObjectizer/so5extra

Наша совсем маленькая компания stiffstream на протяжении нескольких лет делает такие OpenSource инструменты для С++ как:

  • RESTinio: встраиваемый HTTP/WebSocket сервер, ориентированный на эффективную асинхронную обработку входящих HTTP-запросов;
  • SObjectizer/so5extra: реализация Actor Model, Publish-Subscribe и Communicating Sequential Processes, существенно упрощающая разработку сложных многопоточных приложений.

Прибыли эти разработки не приносят, мы вели их за свои деньги.

К сожалению, кризис 2020-го ударил и по нам. Наши собственные финансовые ресурсы для развития RESTinio и SObjectizer/so5extra практически исчерпаны.

Поэтому мы приостанавливаем работы над этими проектами на неопределенный срок.

UPD. На данный момент история с поиском финансирования закончилась ничем. Развитие наших OpenSource-проектов пока приостановлено. Мы попробуем поднакопить средства на заказной разработке/консультациях, чтобы затем вернуться к работам над RESTinio/SObjectizer/so5extra. Кому интересно, вот послесловие к этой затее.

Соответственно, те предложения, которые были первоначально описаны в этом посте, стали не актуальны. Я спрятал их под кат, сохранив просто для истории.

Если же кто-то на тех или иных условиях готов вложиться в разработку наших OpenSource-проектов, то контакты под катом внизу. Давайте пообщаемся, нам нужна не такая уж и большая сумма.

[work.opensource.c++] arataga: что это вообще и зачем мы публикуем это в OpenSource?

arataga -- это работающий прототип socks5+http/1.1 прокси сервера, который мы в прошлом году разрабатывали для одного из наших клиентов. К сожалению, этот прототип остался невостребованным. Ну а чтобы не пропадать добру и самопиара ради, мы решили открыть его исходники.

Как все развивалось

Дело было так: с 2019-го года мы работали с заказчиком, который эксплуатировал у себя некий старый прокси-сервер. Весьма старый, написанный с применением модели thread-per-connection, да еще и оставшийся без сопровождения. Собственно, мы как раз и занимались его доработкой под нужды заказчика.

Где-то к концу весны 2020-го стало понятно, что больше ничего хорошего из этого прокси-сервера не выжать. Что нужно его заменять на что-то новое, написанное с нуля или же переделанное готовое (типа nginx или envoy после обработки напильником).

Изначально в этот проект влезать не хотелось вообще, т.к. объем работ предполагался большим, сроки короткими, поэтому наших ресурсов могло тупо не хватить. Но мы согласились помочь в написании ТЗ для будущих исполнителей и уже в процессе подготовки ТЗ сложилось ощущение, что здесь можно будет применить и SObjectizer, и RESTinio, и что при должном разбиении на итерации можно будет справиться и своими скромными силами. Посему ввязались в разработку нового прокси-сервера под требования заказчика.

В итоге в довольно сжатые (как мне кажется) сроки мы сделали прототип, который уже нужно было запускать на нормальное тестирование на площадке клиента... Но сам клиент утратил интерес к этой разработке и перестал реагировать на внешние раздражители.

Что стало неприятным сюрпризом, тем более, что до этого никаких проблем с заказчиком не было. И даже по ходу работ над arataga мы взаимодействовали по другим вопросам и он оплачивал нам сделанные ранее работы.

Наши обязательства перед клиентом закончились. У нас на руках остался arataga и с этим нужно было что-то делать. Например, выбросить и забыть. Или же открыть.

Зачем нужно было делать arataga?

У заказчика были следующие и, как мне представляется, местами весьма специфические условия:

суббота, 9 января 2021 г.

[prog.c++] Пару слов про позиционирование RESTinio и основные хотелки для RESTinio на 2021-й

Начало года отличное время для того, чтобы попытаться прикинуть планы на ближайшее (и не очень) будущее. Сегодня скажу пару слов про то, в каком направлении я вижу смысл развивать RESTinio.

ИМХО, уже пришла пора более точно определиться с позиционированием RESTinio в экосистеме C++. Это раньше RESTinio был молодой и мало кому известной разработкой. Сейчас же ситуация меняется, мы уже не молоды ;)

Позиционирование важно потому, что на данный момент можно насчитать с дюжину подобных инструментов для C++. И хотя на слуху находится всего пара-тройка названий, но если какой-то C++ разработчик захочет подобрать встраиваемый HTTP-сервер под свою задачу, то у него будет приличный выбор на любой вкус, цвет и размер кошелька. Конкурировать со всеми и во всех направлениях бессмысленно. Посему следует обозначить нишу для RESTinio.

Мне представляется, что RESTinio уникален тем, что под одной крышей здесь собрано:

  • простота использования RESTinio для каких-то очевидных и понятных действий. Так, чтобы получить запрос и пройтись по списку HTTP-полей, не нужно выписывать вручную процедуры чтения данных из сокета;
  • гибкая настройка RESTinio под условия пользователя. Захотел пользователь применять Boost.Log для логирования? Нет проблем, RESTinio позволяет написать адаптер и RESTinio будет логировать свои действия с помощью этого адаптера. Или, например, захотел пользователь запускать вместе с RESTinio на io_context еще и какие-то свои сетевые операции... Опять же, нет проблем;
  • набор инструментов, которые позволяют применять RESTinio для каких-то нетривиальных сценариев. Например, средства работы с HTTP-заголовками используются в arataga даже для исходящих HTTP-запросов.

Что делает RESTinio хорошим выбором для ситуаций, когда разработчику нужно что-то сильно повыше уровнем, чем Boost.Beast, но при этом хочется иметь гораздо больший контроль за происходящим, чем в oat++ или cpp-httplib.

Отличный пример такой задачи, на мой взгляд, -- это прокси-сервер типа arataga. На Boost.Beast его делать будет слишком хлопотно. А oat++/cpp-httplib вряд ли дадут доступ к своим потрохам.

Именно в этом направлении, думаю, и стоит развивать RESTinio дальше.

Т.е., RESTinio должен быть выше уровнем, чем Boost.Beast, но ниже, чем oat++ и cpp-httplib. Но при этом средствами RESTinio продвинутый разработчик с небольшими усилиями должен уметь создать для себя что-то похожее на oat++/cpp-httplib, но заточенное под специфические требования конкретной прикладной задачи.

Или же, в более лаконичной форме:

RESTinio должен стать конструктором из продвинутых инструментов, отлично подогнанных друг к другу.

Как именно это будет выглядеть пока сказать не могу. Надеюсь, что в процессе дальнейшей эволюции RESTinio это выяснится.


Теперь попробую обозначить несколько приоритетов в предполагаемом развитии RESTinio в 2021-ом году.

Во-первых, это замена http_parser на что-то другое. Конечно же, хочется иметь собственную реализацию, которая бы a) сделала RESTinio полностью header-only библиотекой, и b) поддерживала бы различные тонкие моменты в HTTP-протоколе (вроде chunk extensions). Если это не получится, то рассмотреть и внедрить какую-то готовую альтернативную реализацию (llhttp, picohttpparser, что-то еще).

Во-вторых, добавление режима работы в котором RESTinio не будет загружать весь запрос в память перед вызовом обработчика, а будет отдавать читаемые от клиента данные кусками по мере их поступления. Это позволит a) эффективно обрабатывать запросы с большим объемом входящих данных, и b) использовать RESTinio для сценариев, в которых сейчас RESTinio не может применяться в принципе (например, для разработки прокси-сервисов).

В-третьих, добавление поддержки http/2. Пока RESTinio жестко завязана на работу со всего лишь один протокол. От этого нужно уходить, т.к. рано или поздно, http/2 и http/3 вытеснят http/1.1. И если в 2021-ом получится изменить RESTinio так, чтобы в нем поддерживалось сразу два протокола, то это откроет отличную возможность добавить со временем еще и http/3, а может и еще что-нибудь.

Если в 2021-ом получится реализовать в RESTinio все эти три хотелки, то это будет очень хороший результат. Если получится. Но для этого нужны условия. Впрочем, об этом поговорим через несколько дней.

По поводу поддержки в RESTinio клиента я могу лишь повторить то, что уже говорил раньше: без внешнего финансирования мы поднять такую задачу не сможем. Так что если кто-то готов вложить в RESTinio, минимально, 3.5K USD, то давайте всерьез обсудим такую возможность.


Если кого-то интересует перечень встраиваемых HTTP-серверов для C++, то выглядит он приблизительно так (перечисление в случайном порядке): RESTinio, Boost.Beast, cpp-httplib, http_backend, Pistache, RestBed, served, C++ REST SDK, proxygen, Simple-Web-Server, drogon, oat++

вторник, 29 декабря 2020 г.

[prog.c++] RESTinio-0.6.13: последний большой релиз в 2020-ом и, возможно, вообще последний в рамках ветки 0.6

Состоялся очередной релиз RESTinio: версия 0.6.13, в которой таки были реализованы идеи по выстраиванию обработчиков запросов в цепочки (по аналогии с ExpressJS-овскими middleware). Подробнее про новшества версии 0.6.13 я собираюсь рассказать в отдельной статье на Хабре. Кто не хочет ждать, тот может заглянуть в нашу документацию.

Скорее всего, этот релиз станет последним большим релизом в рамках ветки 0.6. И дальнейшее развитие RESTinio будет происходить уже в рамках новой ветки 0.7 без оглядки на совместимость с веткой 0.6. Это не значит, что мы все поломаем напрочь, но какие-то несовместимости обязательно будут и код под RESTinio-0.7 придется адаптировать.

В пользу того, чтобы перестать развивать ветку 0.6 и начать делать новую 0.7 говорит несколько факторов (порядок их перечисления случаен):

  • в RESTinio уже накопилось несколько моментов, которые требуют переделки (какие-то из них прямо в коде помечены как FIXME). А эта переделка невозможна без слома текущего API;
  • до сих пор в RESTinio поддерживался только http/1.1. Думаю, чтобы двигаться дальше нужно добавлять в RESTinio и http/2, и http/3. А на такую мультпротокольность RESTinio не был расчитан. Непонятно, можно ли уместить поддержку мультипротокольности в существующую архитектуру и API RESTinio. Поэтому проще заниматься этим вопросом без оглядки на совместимость с предыдущими версиями RESTinio;
  • поддержка цепочек обработчиков, которая появилась в 0.6.13, распространяется только на синхронные обработчики. А хочется иметь такую же и для цепочек асинхронных обработчиков. Но придумать как это сделать в рамках версии 0.6 у меня не получилось. Есть смутная идея, но она требует изменения API;
  • сейчас RESTinio сперва полностью загружает в память входящий запрос и лишь затем вызывает обработчик для него. Хочется добавить режим работы, в котором RESTinio сможет отдавать входящий запрос на обработку частями, без предварительного накопления всего содержимого запроса;
  • один из важнейших факторов: лежащая в качестве базы RESTinio внешняя библиотека http-parser осталась без сопровождения. Поэтому в RESTinio парсер HTTP нужно заменить на что-то. Либо на другую готовую стороннюю библиотеку, либо на свой собственный велосипед. Такая замена существенно изменит список зависимостей для RESTinio, а это уже точно ведет к переходу к следующему номеру в версии.

Так что, подозреваю, развитие RESTinio переходит в новую стадию. И впереди меня ждет период вынашивания новых идей и лепки из того, что получится придумать, новой версии RESTinio.

Сколько времени это займет и когда можно ждать 0.7.0 не могу сказать. Вряд ли раньше весны 2021-го.

Соответственно, сейчас очень хороший момент, чтобы рассказать нам о том, чтобы вам хотелось видеть в RESTinio. Любые конструктивные замечания и предложения всячески приветствуются.

Сразу хочу сказать по поводу поддержки клиента в RESTinio. Без внешнего финансирования мы не сможем поднять эту тему. Так что если кто-то использует RESTinio на работе и хотел бы с помощью RESTinio обслуживать не только входящие, но и исходяще соединения, то рассмотрите, пожалуйста, возможность заказать такую доработку RESTinio у нас. Цена вопроса, думаю, будет где-то в районе 3.5-6k USD.


Пользуясь случаем хочу поблагодарить всех, кто интересуется RESTinio. И особенно тех, кто рискнул и выбрал нашу разработку. Очень надеюсь, что вы не разочаровались.

Если кто-то хочет помочь в развитии RESTinio, то на данный момент одним из самых больших подспорьев для нас является распространение информации о RESTinio. Каждое упоминание RESTinio в Интернете (Facebook, LinkedIn, Reddit-е, HackerNews, Twitter, Slack, Telegram и т.д.) поддерживает нашу мотивацию и желание развивать RESTinio дальше.

суббота, 12 декабря 2020 г.

[prog.c++] Думаю как добавить в RESTinio что-то похоже на middleware из Express.js

В конце августа и в сентябре я уже пытался поднять эту тему. Но не вышло в силу общего падения производительности на фоне того, что у нас творилось. Сейчас вот пытаюсь сделать очередную попытку. Уже с вариантами, которые мне нравятся куда больше.

В общем, если кто-то интересуется развитием RESTinio, то милости прошу: https://github.com/Stiffstream/restinio/discussions/140

ЗЫ. За подобие английского прощу не бить, это лучшее, на что способны Google-Translate в паре с Grammarly в настоящее время ;)

четверг, 12 ноября 2020 г.

[prog.c++] Библиотека RESTinio обновилась до версии 0.6.12

RESTinio продолжает развиваться. Выкатили версию 0.6.12. В этой версии появились возможности для более жесткого контроля за тем, что приходит от клиента. Что может помочь в случае, если написанный на базе RESTinio сервис смотрит напрямую в Интернет, а не прячется за каким-то proxy-сервером.

Если кому-то интересны потроха RESTinio, то на Хабре опубликована свежая статья о том, как новая функциональность включается/выключается посредством C++ных шаблонов.

По поводу дальнейшего развития RESTinio можно сказать следующее: соображения о том, куда двигаться дальше, есть. Часть озвучивалась ранее, часть нет (как из суеверия, так и из недостаточной проработки). Но тут нужно понимать простую вещь: RESTinio напрямую нам денег не приносит, поэтому что-то новое в RESTinio появляется только тогда, когда у нас находятся для этого и время, и возможности. Се ля ви.

В завершение хочу сказать спасибо всем, кто выбрал и использует RESTinio. Вы ведь могли предпочесть что-то другое, но сделали правильный выбор ;) За что вам большое спасибо.

Так же напомню, что если вы что-то хотите увидеть в RESTinio, но ничего нам об этом не говорите, то оно и не появится. Ибо мы об этом даже и не узнаем. Посему не стесняйтесь открывать issue ;)

четверг, 8 октября 2020 г.

[prog.c++] Наш RESTinio упомянули в докладе про I/O Objects из Networking TS на CppCon2020

При просмотре доклада "The Networking TS from Scratch: I/O Objects" от Robert Leahy уронил челюсть на пол при появлении вот этого слайда:

Отрадно. Не зря, выходит.

Пользуюясь случаем хочу напомнить, что если вам не хватает чего-то в RESTinio или же вам что-то не нравится в RESTinio, то об этом можно рассказать нам. Возможно, мы сможем вам помочь.

четверг, 20 августа 2020 г.

[prog.c++] Незапланированный, но показательный релиз RESTinio

Сегодня была зафиксирована очередная версия RESTinio: 0.6.10. В ней только одно нововведение, но зато оно показательно.

Пару дней назад пользователь открыл issue на GitHub, в котором попросил возможность сделать так, чтобы экземпляр asio::ssl::context можно было разделять между RESTinio-сервером и другими частями приложения. Что изначально в RESTinio предусмотренно не было.

Поскольку была высказана потребность в действительно полезной функциональности, то мы эту функциональность реализовали. И выкатили новую версию не дожидаясь воплощения в жизнь других хотелок и идей, которые есть у нас в загашнике.

Мораль сей басни: если вы что-то хотите видеть в RESTinio, то дайте нам об этом знать. Попробуем решить вопрос.

Да, и это касается не только RESTinio ;)

четверг, 13 августа 2020 г.

[prog.c++] My view of the near (and not so) future of the RESTinio project

Now, after the official release of RESTinio-0.6.9, it's a good time to share some thoughts about the near (and not only near) future of the RESTinio project.

It is worth noting that the text below is only my point of view. This point of view can change over time.

This text is split into two parts. The first part tells about rather practical things that I want to see in the upcoming releases of RESTinio. The second part is more philosophical and intended for the discussion about the role of RESTinio in the modern C++ landscape.

Part One. What I want to have in RESTinio 0.6 and what could be seen in 0.7?

пятница, 8 мая 2020 г.

[prog.c++] Теперь и SObjectizer, и RESTinio перечислены в списке Awesome C++

В общем-то мелочь (на самом деле нет), а очень приятно: теперь и SObjectizer, и RESTinio перечислены в важном для C++сообщества списке Awesome C++.

Для нас, как разработчиков SObjectizer и RESTinio, это важно потому, что в мире C++ люди нередко начинают поиск подходящих для себя инструментов именно с Awesome C++. В этом смысле Awesome C++ -- это нечто вроде "желтых страниц". И теперь оба наших основных OpenSource продукта на этих "желтых страницах" перечислены.

RESTinio в Awesome C++ попал достаточно бысто. А вот включения туда SObjectizer-а пришлось ждать в течении нескольких лет. Поэтому большое спасибо всем тем, кто отдал свой голос за добавление наших разработок в этот престижный список!


Как обычно добавлю, что мы очень внимательно относимся ко всем пожеланиям и предложениям наших пользователей. Поэтому если вам чего-то не хватает в SObjectizer/so5extra, RESTinio или json_dto, то дайте нам знать. Постараемся учесть ваше мнение.

Так же, если у кого-то есть сложности в освоении и/или использовании SObjectizer и RESTinio, то не стесняйтесь, спрашивайте. Обязательно поможем. И еще с большим энтузиазмом поможем вам, если вы решите заказать у нас разработку, в которой будут использованы SObjectizer или RESTinio ;)