Сегодня мы опубликовали очередную статью на Хабре про свой демо-проект Shrimp: "Делаем Shrimp еще полезнее: добавляем перекодирование картинок в другие форматы". Статья, вероятно, заключительная в серии. Ибо дальнейшее развитие Shrimp-а возможно разве что при выполнении одного из следующих условий:
пятница, 17 августа 2018 г.
среда, 15 августа 2018 г.
[prog.c++] Про попытку изобразить strong typedef из подручных средств
У нас завершается очередная итерация работ над демо-проектом Shrimp. На днях выйдет статья на Хабре с некоторыми подробностями (если кто-то пропустил, то вот первая статья про Shrimp, а вот вторая). Сегодня же я попробую рассказать об одной штуке в коде Shrimp-а, которая у меня самого вызывает неоднозначные впечатления. Если кому-то интересны потуги натянуть сову на глобус извращения старого сиплюсплюсника, то милости прошу под кат.
четверг, 19 июля 2018 г.
[prog.c++] Вторая статья про демо-проект Shrimp
Мы подготовили и опубликовали вторую статью про свой демо-проект Shrimp, наглядно показывающий, как может выглядеть более-менее реальное приложение на RESTinio и SObjectizer (ну и на C++17): "Развиваем Shrimp: контролируем параллельные запросы, логируем через spdlog и еще…".

Вторая статья описывает результат следующей итерации вокруг Shrimp-а. Мы кое-что доработали напильником и устранили шероховатости, которые были в самой первой версии Shrimp-а. Интересно было добавлять команду на принудительный сброс содержимого кэша в Shrimp-е. За счет удобного механизма роутинга запросов в RESTinio добавить обработку еще одного URL в HTTP-сервере -- это буквально дело нескольких минут. Правда, реализация реакции на эту команду в агенте transform_manager заняла больше времени, но и там отложенные сообщения, которые есть в SObjectizer-е, сильно помогли и упростили работу.
По результатам первых двух итераций над Shrimp-ом у нас уже обозначился набор фич, которые было бы полезно добавить как в RESTinio, так и в SObjectizer. Что-то уже пошло в работу (и даже нашло свое воплощение в RESTinio-0.4.7), до чего-то руки дойдут как только, так сразу. Если вы сами хотели бы увидеть что-то в RESTinio и/или SObjectizer-е, то дайте знать, к конструктивным соображениям мы всегда прислушиваемся и стараемся их воплотить. Ярчайший пример -- это добавление в SObjectizer мутабельных сообщений, идея которых возникла при обсуждении возможностей SObjectizer-а в кулурах C++Russia 2017. В том же Shrimp-е практически весь обмен данными между агентами выполняется как раз посредством мутабельных сообщений.
Касательно самого Shrimp-а: после того, как мы поработали над ним напильником и теперь Shrimp стал больше напоминать что-то пригодное к эксплуатации, открылась возможность сделать в Shrimp-е еще что-нибудь интересное. Поэтому мы запланировали еще одну итерацию. Постараемся сделать в Shrimp-е преобразование картинок из одного формата в другой. Так же, к очередной публикации мы думаем выложить и Dockerfile для самостоятельной упаковки Shrimp-а в Docker. А может быть и сделаем вот прям готовый Docker образ со Shrimp-ом внутри, дабы желающие поиздеваться над Shrimp-ом имели возможность это сделать.
В общем, планы на ближайшее время есть. Осталось воплотить их в жизнь. Чем мы, собственно говоря, и займемся.
понедельник, 16 июля 2018 г.
[prog.c++] Довелось столкнуться со странной структурой данных: и очередь, и multimap.
В рамках следующей итерации над демо-проектом Shrimp постарались закрыть несколько "косяков" самой первой, простейшей версии Shrimp-а. В частности, в простейшей версии Shrimp-а были возможны ситуации, когда пришедшие практически одновременно одинаковые запросы шли в параллельную обработку. Т.е., если мы получаем запрос "demo.jpg?op=resize&max=1024" и следом еще один такой же, то операция трансформации картинки demo.jpg к размеру 1024px могла быть запущена дважды.
Происходило это потому, что Shrimp проверял наличие уже трансформированной картинки в своем кэше. Если ее в кэше нет, то при наличии свободных worker-ов запрос сразу же шел в обработку. Получили запрос для demo.jpg, увидели, что в кэше результата нет, отдали на трансформацию. Результат трансформации еще не пришел, а у нас уже еще один запрос для demo.jpg. Поскольку трансформированной картинки в кэше, ожидаемо, нет, то отдаем запрос на обработку. И получаем, что одна и так же картинка трансформируется параллельно несколькими воркерами. Что не есть хорошо.
Понятное дело, что для самой первой, самой простейшей версии Shrimp-а не было смысла делать контроль уникальности запросов. Но вот добавить подобный контроль в последующих версиях нужно было. Работы тут не так много, а солидности демо-проекту добавляет :)
И вот при реализации контроля за уникальностью ждущих/обрабатывающихся запросов оказалось, что хорошо бы иметь такой контейнер, который, с одной стороны, выглядел бы как очередь, сохраняющая хронологический порядок добавления элементов. Это качество оказалось особенно важно для очереди ждущих запросов. Ведь нужно ограничивать время пребывания запросов в pending-queue, а для этого нужно периодически просматривать очередь начиная с самых старых элементов в ней.
С другой же стороны, нужно иметь возможность эффективно проверить наличие конкретного ключа в контейнере. И, сюда же, нужно иметь возможность изъять из очереди сразу все элементы с одинаковым ключом. Нужно это в случае, когда освободился worker и мы берем самый старый элемент из очереди. Но, если ключ этого элемента не уникален (т.е. есть более свежие запросы с тем же ключом), то оставлять в очереди другие аналогичные элементы нет смысла. Ведь когда картинка будет трансформирована, то ее можно будет отдать сразу всем этим запросам.
понедельник, 9 июля 2018 г.
[prog.c++] Первая статья про Shrimp -- наш демо-проект для RESTinio и SObjectizer
Мы сегодня выкатили на Хабр первую статью о демо-проекте на базе RESTinio и SObjectizer-а: "Shrimp: масштабируем и раздаем по HTTP картинки на современном C++ посредством ImageMagic++, SObjectizer и RESTinio". Нам показалось, что такая задачка отлично показывает сценарий, при котором может потребоваться:
- прикрутить HTTP-интерфейс к старому, давно отлаженному и работающему C/C++ коду. Особенно если нет возможности переписать этот код на новом, модном и безопасном языке. Ведь во многих случаях такой возможности нет;
- асинхронно обслуживать HTTP-запросы, поскольку их прикладная обработка занимает на порядки больше времени, чем работа с самим HTTP-подключением;
- использовать многопоточность для прикладной обработки запросов.
В первой статье описана простейшая и минималистичная версия Shrimp-а. Планируется еще пара статей, в которых будет показано дальнейшее усложнение реализации Shrimp-а.
Первые практические результаты от разработки Shrimp-а мы уже получили. Появилось несколько идей и соображений как для RESTinio, так и для SObjectizer-а. Что мы и попытаемся воплотить в жизнь в грядущих обновлениях наших продуктов.
Если же кто-то заинтересуется самим Shrimp-ом, то мы будем рады обсудить любые конструктивные соображения о том, как сделать из Shrimp-а что-то полезное не только нам самим.