пятница, 8 февраля 2019 г.

[prog.c++] Первая чужая статья про опыт использования SObjectizer-а

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

Вот эта статья: "Если проект «Театр» используй акторов…"

Автору статьи большое спасибо. Даже два. Больших. Одно за то, что отважился применить SObjectizer в продакшене. Второе за то, что нашел время и поделился своим опытом.

От себя хочу добавить несколько вещей, которые мне представляются важными.

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

Во-вторых, отрадно получить подтверждение, что ключевые особенности, можно сказать, краеугольные камни, на которых базируется SObjectizer -- почтовые ящики, агенты+состояния, кооперации и диспетчеры -- действительно оказываются таковыми не только для нас. Это значит, что в свое время мы сделали правильный выбор при проектировании основных принципов работы пятого SObjectizer-а. Это так же означает, что нами был правильно переосмыслен опыт предыдущих версий SObjectizer-а (и его предтечи, SCADA Objectizer-а). Не то, чтобы мы в этом очень сомневались, но получить подтверждение из независимых источников более чем приятно.

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

Сюда же можно добавить еще и то, что SObjectizer написан на C++. Поэтому, если у вас уже есть собственные многолетние наработки на C++ или C, то вам не придется их выбрасывать. Вы вполне можете использовать SObjectizer с уже имеющимся у вас кодом.

В-четвертых, интересно развивается история. SCADA Objectizer создавался для решения задач АСУТП. Затем в SObjectizer-е мы от АСУТП-ных задач ушли. Но при этом использовали, можно сказать, АСУТП-ные подходы для разработке на SObjectizer-е других систем (из области телекома и платежных сервисов). Но, тем не менее, наследственность оказалась столь сильной, что SObjectizer в своем нынешнем виде вновь вернулся к задачам АСУТП. Что лично у меня вызвало огромный приступ ностальгии :)


Отдельно хочу поблагодарить всех, кто на протяжении уже многих лет проявляет интерес к тому, что мы делаем. Это может казаться мелочью, но на самом деле каждый лайк в соцсетях, каждый +1 к статьям о SObjectizer-е, каждый комментарий, каждый репост новости или статьи -- все это в итоге оказывает очень большое влияние. Мы сами ощущаем интерес и поддержку, что дает нам силы и желание продолжать свою работу, что ведет к тому, что SObjectizer становится еще лучше, мощнее и удобнее. И потенциальные пользователи, видя, что проект развивается, что к нему есть какой-то интерес, начинают смотреть на наш инструмент внимательнее. Что ведет к тому, что в какой-то момент они решаются взять и попробовать. А ведь это именно то, ради чего мы работаем.

PS. Какой же сегодня все-таки хороший повод сгонять в магазин! ;)

четверг, 7 февраля 2019 г.

[prog] А где было бы удобнее всего обсуждать связанные с SObjectizer-ом идеи?

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

Я вижу следующие варианты:

понедельник, 4 февраля 2019 г.

[prog.c++] Небольшое послесловие про "Обедающих философов" и exception-safety

В статье про реализацию задачи про обедающих философов посредством Actors и CSP я отдельно затронул тему обеспечения exception-safety при использовании модели CSP. И, пожалуй, можно на этом моменте остановится подробнее еще раз.

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

Первое, что нам придется сделать -- это выполнить рекомендации из статьи по корректному завершению нитей для вилок. Т.е. сперва мы будем закрывать каналы, созданные для вилок, только потом будем вызывать join(). OK. С этим все понятно.

Далее нам нужно будет при возникновении каких-либо проблем завершить нити для философов.

И тут, если мы просто вызовем join(), мы опять наступим на те же грабли, не лежащие несколько по-другому. Дело в том, что внутри philosopher_process есть цикл, в котором выполняются вызовы receive(). Выход из receive() может произойти либо при получении ответа от вилки, либо при закрытии канала.

Но, если нити для вилок уже завершили свою работу, то вилки прислать ответ философу уже не смогут. И канал никто не закроет, т.к. каналом владеет сам philosopher_process, а run_simulation() к каналу доступа не получит.

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

OK. Это уже шаг в верном направлении.

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

К сожалению, нет. Т.к. внутри philosopher_process цикл с вызовами receive(). Из receive-то мы выйдем принудительно закрыв канал. А вот из цикла?

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

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

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