Читатели блога, особенно читатели со стажем, знают, что я много лет продвигаю в массы инструмент для упрощения разработки многопоточных приложений под названием SObjectizer. Вроде бы процесс идет, но, к сожалению, не настолько быстро, чтобы услуги по техподдержке SObjectizer-а смогли кормить нашу небольшую компанию. Поэтому время от времени приходится заниматься выполнением заказов, никак не связанных ни с SObjectizer, ни с RESTinio.
Как правило это сопровождение и доработка уже существующих решений, которые заказчиком продолжают эксплуатироваться. Но у заказчиков либо уже нет собственных специалистов по C или C++, или же нет свободных ресурсов, поэтому и привлекаются люди со стороны.
Ну а раз это старый чужой код, то SObjectizer-а там нет и в помине.
И вот на этом фоне временами становится очевидно, насколько бы проще оказалось бы доработка/сопровождение, если бы SObjectizer или что-то подобное в проекте использовалось бы.
Несколько месяцев назад довелось делать в чужом приложении механизм ограничения доступа к некоторому ресурсу внутри приложения. Ресурс имел ограниченную пропускную способность (т.е. мог одновременно обрабатывать не больше N обращений), но в программе временами одномоментно могло прийти гораздо больше запросов к этому ресурсу. И без выстраивания этих запросов в очередь приложение просто затыкалось и могло не восстановиться.
Если бы данный ресурс можно было оформить в виде агента/актора или хотя бы подобия CSP-шного процесса, то все решалось бы элементарно: агент получает запросы, N из них может обрабатывать параллельно, остальные ждут в очереди. Причем очередь можно сделать с учетом приоритетов и делать любые политики обслуживания его содержимого (например, можно выявлять дубликаты запросов, т.е. если один и тот же запрос прилетел несколько раз, то его можно обработать лишь однажды).
Но ни акторов, ни CSP в проекте не было, запросы к ресурсу шли из разных рабочих нитей, причем сам ресурc не был отдельной нитью, это был объект, методы которого можно было дергать из разных тредов одновременно. Поэтому пришлось делать систему очередей на mutex-ах и куче condition_variables. Что оказалось сильно сложнее, чем если бы использовались SObjectizer-овские агенты.
А на днях был другой случай. В приложении есть ряд рабочих нитей, каждая последовательно делает какую-то свою работу. И вдруг появляется необходимость периодически очищать некоторые внутренние списки (грубо говоря, если информация внутри списка прожила больше 5 минут, то она уже не актуальна), а так же периодически выдавать часть информации наружу (причем желательно с каким-то фиксированным темпом, скажем, раз в 10 минут).
Но фокус в том, что таймеров в приложении не было. Вот не были предусмотрены такие сценарии изначально, поэтому каждая рабочая нить просто в цикле фигачит что-то свое и ни про какие таймеры нет и речи.
Опять же, была бы возможность использовать SObjectizer-овских агентов, вообще никаких забот: таймеры -- это важная и неотъемлемая часть SObjectizer-а, поэтому агенты могут использовать сколько угодно таймеров и когда они этого захотят.
Но вот когда акторов нет, то приходится изгаляться, вести временные метки и расставлять в коде дополнительные проверки на истечение времени после последнего события. Что гораздо муторнее и не столь надежно.
В общем, оглядываясь назад могу смело сказать, что мне очень повезло, что в последние 18 лет у меня был инструмент, который сильно упрощал разработку многопоточных приложений. Я настолько привык к удобству SObjectizer-а, что сталкиваясь с кодом, в котором SObjectizer-а нет, временами тихо офигеваю от количества усилий для достижения результата, который в SObjectizer-е можно получить просто по щелчку.
Поэтому еще раз предлагаю тем, кто пишет код на C++, посмотреть в сторону SObjectizer-а.
Это бесплатный и свободный инструмент с большой историей. С поддержкой. С возможностью доработать под ваши нужды.
Вся эта нынешняя история с короновирусом, которая лишний раз показывает, что жизнь коротка, а люди не просто смертны, а внезапно смертны, и скоропостижно уйти могут талантливые разработчики, которым еще творить и творить, лично мне показывает, что наше время нужно ценить гораздо больше, чем мы это делали до сих пор.
Поэтому зачем нужно жрать кактус и пердолится с голой многопоточностью когда можно взять SObjectizer или какой-то подобный инструмент... Я не понимаю.
Важное дополнение: как любой другой инструмент, SObjectizer может применяться не везде. А если вы не знаете, подойдет или SObjectizer для решения вашей задачи, то можно спросить у нас. Нам не нужен ни ваш геморрой, ни свой, поэтому советовать применять SObjectizer там, где этого не стоит делать, не будем.
Ну и да, если вам нужна помощь в разработке на C++, то вы можете обратиться к нам. Даже если это не связано, ни с SObjectizer, ни с RESTinio.