вторник, 1 января 2030 г.

О блоге

Более двадцати лет я занимался разработкой ПО, в основном как программист и тим-лид, а в 2012-2014гг как руководитель департамента разработки и внедрения ПО в компании Интервэйл (подробнее на LinkedIn). В настоящее время занимаюсь развитием компании по разработке ПО stiffstream, в которой являюсь одним из соучредителей. Поэтому в моем блоге много заметок о работе, в частности о программировании и компьютерах, а так же об управлении.

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

понедельник, 31 декабря 2029 г.

[life.photo] Характерный портрет: вы и ваш мир моими глазами. Безвозмездно :)

Вы художник? Бармен или музыкант? Или, может быть, коллекционер? Плотник или столяр? Кузнец или слесарь? Владеете маленьким магазинчиком или управляете большим производством? Реставрируете старинные часы или просто починяете примус? Всю жизнь занимаетесь своим любимым делом и хотели бы иметь фото на память?

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

четверг, 7 сентября 2017 г.

[prog.actors] Хотите решить задачу с помощью акторов? Спросите меня как! :)

После того, как мне довелось разным людям в разных местах рассказывать про Модель Акторов вообще и про SObjectizer в частности, сложилось впечатление, что продвижению Модели Акторов в массы препятствует две вещи:

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

Тут можно провести аналогию с молотком: понять как действовать молотком не сложно, не сложно и научить им бить. Гораздо сложнее разобраться куда же именно и с какой силой стукнуть молотком дабы получить нужный результат. Вот с Моделью Акторов, имхо, происходит тоже самое. Когда у человека есть конкретная задача, то не факт, что он может представить себе, как же ее решение будет выглядеть на акторах. Ибо понимать принцип -- это одно, а сделать декомпозицию конкретной задачи -- это другое.

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

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

Зачем это нужно мне? Очевидно, что мои цели исключительно корыстные ;) Прежде всего мне нужен материал, на основе которого можно было бы убедительно рассказывать людям о том, где применение Модели Акторов уместно, а где нет. Кстати говоря, неуместность применения Модели Акторов -- это актуальный вопрос. Бывает, что люди слушая про Модель Акторов теряют представление о том, что данная модель применима далеко не всегда. И хорошо бы уметь вовремя различать, где имеет смысл брать акторов, а где этого делать не нужно. Так же мне полезно прикидывать, насколько наш SObjectizer пригоден для решения тех или иных задач. Опыт показывает, что это сильно идет на пользу SObjectizer-у. А т.к. сам SObjectizer распространяется под BSD-лицензией (бездвоздме т.е. даром), то это пойдет на пользу и всем, кто воспользуется SObjectizer-ом.

Зачем это нужно вам? Ну мало ли :) Может вы хотите убедиться, какая все-таки гадость, эта ваша Модель Акторов, а вот вы молодец, когда придумали свое решение без использования акторов ;) Или может вы правда ломаете голову над чем-то и не прочь бы посоветоваться с умным человеком простофилей, который готов тратить свое время бесплатно. Ну или вам просто захотелось пообщаться ;)

В общем, если есть задачка и желание ее обсудить, то милости прошу. Описывайте свои задачки в комментариях к этой заметке (можно в G+), либо по почте eao197 на gmail тчк com, либо со мной можно связаться через FB, LinkedIn или Habrhabr.

PS. Запись специально повисит вверху до сентября. Но, если дело пойдет, можно будет заказать продление ;)

пятница, 14 июля 2017 г.

[prog.c++14] so_5_extra-1.0.1 и so-5.5.19.3

Сегодня мы выкатили очередную версию so_5_extra -- 1.0.1, а накануне обновили SObjectizer до версии 5.5.19.3. Доступно все, как обычно, на SourceForge: здесь so_5_extra, здесь SObjectizer.

В so_5_extra-1.0.1 добавлена всего одна фича: это collecting_mbox.

Смысл collecting_mbox в том, что иногда агенту X нужно получить строго N сообщений типа M от других агентов. Ну вот, например, стартует родительский агент-менеджер и создает пять нужных ему дочерних коопераций. Каждая дочерняя кооперация тратит какое-то время на свои начальные действия (например, загружается конфигурация, устанавливается подключение к БД, инициализируется внешнее устройство и т.д.), после чего отсылает родителю сигнал о том, что дочерняя кооперация готова. Соответственно, родительскому агенту нужно получить все пять сигналов о готовности дочерних коопераций, лишь после этого родительский агент сможет продолжать работать.

понедельник, 10 июля 2017 г.

[prog.c++14] Развернуть std::tuple в вызов конструктора базового класса

Давеча упоролся шаблонами настолько, что потребовалось сделать на C++ что-то вот такое (проще сперва показать на примере, а уже потом рассказывать словами):

templatetypename First_base, typename Second_base >
class Some_complex_template
   : public First_base // Boom #1
   , public Second_base // Boom #2
{
public :
   // Constructor.
   templatetypename... First_base_args, typename... Second_base_args >
   Some_complex_template(
      First_base_args &&...first_args, // Args for the first base class.
      Second_base_args &&...second_args ) // Args for the second base class.
      : First_base{ std::forward<First_base_args>(first_args)... }
      , Second_base{ std::forward<Second_base_args>(second_args)... }
      {}
   ...
};

Т.е. нужно было отнаследовать шаблонный класс Some_complex_template от двух других классов, которые задаются параметрами шаблона. А затем в конструктор Some_complex_template нужно было передать два независимых друг от друга набора параметров. Первый набор параметров должен уйти в конструктор первого базового класса, второй набор -- в конструктор второго базового класса.

Насколько я понимаю, C++ не позволяет написать фукнцию/метод с переменным количеством параметров вот так: f(First &&...first, Second &&...second), что логично, т.к. при вызове f(a1, a2, a3, a4, a5) невозможно понять, что из a(i) относится к first, а что к second.

Поэтому выход из ситуации сейчас ищется в использовании std::tuple вот в таком сценарии:

templatetypename First_base, typename Second_base >
class Some_complex_template
   : public First_base
   , public Second_base
{
public :
   // Constructor.
   templatetypename... First_base_args, typename... Second_base_args >
   Some_complex_template(
      std::tuple<First_base_args...> && first_args, // Args for the first base class.
      std::tuple<Second_base_args...> && second_args ) // Args for the second base class.
      : First_base{ /*some magic is required here!*/(first_args)... }
      , Second_base{ /*some magic is required here!*/(second_args)... }
      {}
   ...
};

Но вот тут возникает вопрос, как же распаковать содержимое std::tuple в вызов конструктора базового типа?

В принципе, вся эта магия с распаковкой std::tuple в вызов некоторой функции f хорошо проиллюстрирована на том же cppreferece.com в описании возможной реализации функции std::apply. Но есть нюанс: нам нужно сделать вызов конструктора базового типа, поэтому у нас нет возможности заводить вспомогательные функции, вроде apply_impl, в которые передается дополнительный аргумент std::index_sequence...

Или все-таки есть?

пятница, 7 июля 2017 г.

[prog.c++] Программирование на шаблонах плохо дружит с программированием на бумаге

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

Однако, если серьезно упороться C++ными шаблонами, то пользы от предварительного программирования на бумаге оказывается заметно меньше. Думаю, это потому, что C++ я знаю не очень хорошо, поэтому не могу на бумаге написать сложный код с шаблонами так, чтобы затем не пришлось его сильно переделывать из-за того, что компилятор на тему использования шаблонов думает совсем по-другому :( Из-за этого намного проще писать код прямо в Vim-е, пытаться его компилировать, сразу же исправлять те места, по которым у меня с компилятором (и со стандартном) обнаруживаются принципиальные расхождения. Затем все повторяется снова и снова, пока я не получаю то, что мне нужно, причем так, чтобы это компилировалось и VC++, и Gcc, и clang.

Однако, от того, что код начинает появляться прямо сидя за компьютером, зачастую я не знаю, как именно будет использовать какая-то новая сущность. Поэтому на начальном этапе настоящая беда и комментариями, и с самими наименованиями в программе. А для того, чтобы все это можно было со временем доработать напильником и довести до приличного состояния, код щедро размечается тегами FIXME. И выглядит это приблизительно вот так:

template<
   typename COLLECTING_MSG,
   typename TRAITS = runtime_size_traits_t,
   typename LOCK_TYPE = std::mutex >
//FIXME: should it be final or not?
class mbox_template_t final
   : public ::so_5::abstract_message_box_t
   , protected TRAITS::size_specific_base_type
   , protected ::so_5::details::lock_holder_detector< LOCK_TYPE >::type
   {
      using specific_base_type = typename TRAITS::size_specific_base_type;

      //FIXME: document this!
      using config_type = details::config_type< COLLECTING_MSG, TRAITS, LOCK_TYPE >;

      //FIXME: document this!
      using messages_collected_builder_t = typename
            details::collected_bunch_type_selector< config_type >::builder_type;
   public :
      //FIXME: document this!
      using messages_collected_t = typename 
            details::collected_bunch_type_selector< config_type >::message_type;

   private :
      //FIXME: document this!
      using messages_collected_subscription_type = typename
         std::conditional<
               is_mutable_message< COLLECTING_MSG >::value,
               mutable_msg< messages_collected_t >,
               messages_collected_t >
            ::type;

   public :
      //FIXME: what about message tracing traits?
      templatetypename... ARGS >
      mbox_template_t(
         mbox_id_t mbox_id,
         ARGS &&... args )
         :  specific_base_type( mbox_id, std::forward<ARGS>(args)... )
         {
            details::check_mutability_validity_for_target_mbox<config_type>(
                  this->m_target );
         }

PS. Ну и еще наброшу на тему C++ных шаблонов. Когда ими реально упарываешься, то начинаешь совсем по другому относиться к спорам на тему того, что вместо C++ можно использовать plain old C или Rust. Программирование на шаблонах C++ -- это, блин, совсем другой подход к программированию. Ни Rust, ни, тем более, C, тут и рядом не стояли. Т.е. сделать одно и тоже можно будет на разных языках, но это будут совершенно разные решения, абсолютно не похожие на друг друга.

вторник, 4 июля 2017 г.

[prog.c++] Новая большая статья про SObjectizer на Хабре

Мы сделали разбор штатного примера machine_control из дистрибутива SObjectizer в виде большой статьи на Хабре: Имитируем управление устройствами с помощью акторов. По ходу дела была мысль вместо одной статьи сделать две, а может и три поменьше. Но по опыту выходит, что каждую следующую читают меньше, чем предыдущие, поэтому решено было ограничиться всего одной.

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

Темы для следующих статей принимаются :)

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