пятница, 20 июля 2018 г.

[prog.flame] И еще раз про Rust. Как я к Rust-у отношусь на самом деле

Судя по статистике посещений, недавние посты про Rust (№1, №2 и №3) продолжают привлекать к себе внимание. И, к сожалению, у некоторых альтернативно одаренных личностей складывается впечатление, что я пытаюсь гнобить Rust. Поэтому нужно расставить все точки над ё.

четверг, 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 и мы берем самый старый элемент из очереди. Но, если ключ этого элемента не уникален (т.е. есть более свежие запросы с тем же ключом), то оставлять в очереди другие аналогичные элементы нет смысла. Ведь когда картинка будет трансформирована, то ее можно будет отдать сразу всем этим запросам.