вторник, 31 января 2017 г.

[life.cinema] Очередной кинообзор (2017/01)

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

Пассажиры (Passengers, 2016). Кино, конечно же, для девочек. Но блин, как же классно оно сделано! Посмотреть можно только для того, чтобы окунуться в мир очень качественно снятой фантастики.

Великая стена (The Great Wall, 2016). Ни в коем разе не шедевр. А вот в качестве красочного фэнтезийного боевика -- хорош.

Война против всех (War on Everyone, 2016). Посмотреть можно. Но лично я ждал большего.

Уличный кот по кличке Боб (A Street Cat Named Bob, 2016). Хороший, добрый фильм. На 80% держится на обаянии главного героя -- рыжего кота.

Пустыня (Desierto, 2015). На удивление неплохо. Финалом лично я несколько разочарован, но все-таки на удивление неплохо.

Демон внутри (The Autopsy of Jane Doe, 2016). Весьма достойный представитель жанра мистических ужастиков. Не могу сказать, что мне прям понравилось-понравилось. Но посмотрел с удовольствием.

Шпионы по соседству (Keeping Up with the Joneses, 2016). Странное впечатление. Похоже, авторы балансировали между тем, чтобы сделать нормальный фильм и тем, чтобы опустить возрастное ограничение для зрителей как можно ниже. В результате получилось впихнуть фильм в категорию PG-13, что на пользу фильму явно не пошло.

Автобан (Collide, 2016). Начало было многообещающим, но финал фильма все испортил.

Под покровом ночи (Nocturnal Animals, 2016). Операторская работа в фильме выше всяких похвал. По после просмотра без ответа остаются следующие вопросы: что это было? Почему у этого такой высокий рейтинг на Кинопоиске? Зачем я это посмотрел?

вторник, 24 января 2017 г.

[prog.c++] Исходники эксперимента mosquitto_transport на BitBucket-е

Где-то с год назад попробовали сделать эксперимент: написали на SObjectizer небольшую обертку над mosquitto. Написали, попробовали каково это, поиспользовали для прототипирования. И забыли :)

Теперь вот вспомнили. Чуток причесали и открыли исходники на BitBucket-е: mosquitto_transport-0.6.

Обертка самая простая. SSL не поддерживаем. Сообщения с QoS выше 0 -- не поддерживаем. За счет того, что libmosquitto, как мне показалось, с Windows не дружит, то работает это все только под Unix-ами (мы проверяли только под Linux-ами).

Цель эксперимента была в том, чтобы посмотреть, насколько просто будет подружить разработку на SObjectizer с использованием MQTT в качестве транспорта. А т.к. MQTT -- это всего лишь протокол передачи данных, который не определяет, как именно будут упакованы сами пользовательские данные, то мы еще хотели сделать так, чтобы mosquitto_transport не был привязан к конкретному типу encoding-а. В общем, все цели были достигнуты. Использовать MQTT можно, получается довольно удобно (по крайней мере на мой взгляд). Разные типы encoding-а подключаются посредством несложной шаблонной магии (подробнее я писал об этом в прошлом году). У себя мы использовали JSON-encoding (посредством rapidjson и json_dto, о json_dto Коля Гродзицкий рассказывал на Corehard C++ Autumn 2016).

Разве что быстро стало понятно, что libmosquitto не есть хорошо. Во-первых, libmosquitto заточен под однопоточную синхронную обработку MQ-шных сообщений. Т.е. когда приходит сообщение, вызывается соответствующий callback и при возврате из него libmosquitto сразу же начинает обработку QoS. Т.е., если сообщение пришло с QoS выше 0, то факт успешного возврата из callback-а воспринимается libmosquitto как факт успешной доставки и подтверждение получения. Что делает невозможным длительную асинхронную обработку сообщений. Во-вторых, исходники libmosquitto оставляют печальное впечатление, да и нам их пришлось патчить, чтобы можно было использовать libmosquitto-овский event-loop в многопоточном окружении (поэтому, кстати, mosquitto_transport использует пропатченную мной версию libmosquitto, а не оригинальную). В-третьих, хотелось бы больше кроссплатформенности.

В общем, mosquitto_transport сделали на libmosqitto, в самом libmosquitto разочаровались, начали делать свою реализацию MQTT. Но пришлось пока это дело заморозить. Может быть к весне получится разморозить.

Еще нужно добавить, что mosquitto_transport для управления зависимостями использует MxxRu::externals. Так что для того, чтобы собрать, нужно воспользоваться MxxRu. Приносим свои извинения, но нам так было удобнее, да и сам mosquitto_transport вряд ли кому-то потребуется. Поэтому адаптацию под какие-то другие менеджеры зависимостей для C++ (коих, по сути-то и нет), мы не делали. Да, еще нужен Boost, но Boost через MxxRu::externals мы не подключали (еще раз лучи поноса Boost-оводам, которым, блин, нравятся ну очень большие архивы и которые, блин, не знают, что такое нормальная модульность). Так что Boost нужно ставить либо вручную, либо через систему пакетов конкретного дистрибутива Linux-а.

Ну вот как-то так. Сам mosquitto_transport работает стабильно, но развивать мы его вряд ли будем. Скорее это станет основой для нашего собственного MQTT-шного транспорта для SObjectizer. Но если есть какие-то вопросы или замечания, или предложения, то всегда пожалуйста: выслушаем, ответим, прислушаемся... :)

четверг, 12 января 2017 г.

[prog] Бывают ли встраиваемые http-сервера для C/C++ с асинхронной обработкой запросов?

Беглым взглядом прошерстил списки встраиваемых http-серверов для C/C++ отсюда и отсюда. Показалось, что они практически все сделаны так, что когда для обработки GET или POST запроса вызывается пользовательский callback, то этот callback должен отработать синхронно, т.е. должен сразу отдать весь ответ на запрос. А вот такого, чтобы:

  • http-сервер синхронно дернул callback на какой-то своей рабочей нити (соответственно, рабочая нить блокируется);
  • callback инициировал асинхронную обработку запроса и вернул http-серверу некий future;
  • рабочая нить http-сервера разблокируется и http-сервер получает возможность обрабатывать другие запросы;
  • когда асинхронная обработка запроса завершается, future взводится;
  • http-сервер обнаруживает факт того, что future взведен, забирает готовый ответ и отсылает его клиенту.

Вот такого прям с ходу не нашел. Может быть C++ REST SDK (aka Casablanca) от Microsoft это позволяет делать, надо будет внимательнее посмотреть, вроде бы там что-то похожее на task-based parallelism-а используется.

Может кто-то сталкивался с подобным встраиваемым http-сервером? Если ли такое вообще?

PS. Пикантность ситуации в том, что нужно именно C/C++, т.к. обработчики HTTP-запросов должны дергать довольно сложные C++ные вещи. Плюс VC++ и Windows на первом месте в списке поддерживаемых платформ. Посему библиотеки, заточенные только под Unix-ы и GCC/clang, идут лесом.

PPS. На всякий случай список ссылок, по которым прошелся:

вторник, 10 января 2017 г.

[prog.thoughts] Какое тонкое различие между message-driven и event-driven...

Продавцы Akka и, заодно, главные пиарщики Reactive Manifesto, на днях опубликовали очередной white paper: Reactive Programming versus Reactive Systems. Материал наполовину технический, наполовину маркетинговый. Но, не смотря на то, что маркетингового бла-бла-бла там порядком, почитать все-таки интересно.

Мое внимание привлекли пару фрагментов, которые описывают разницу между message-driven и event-driven подходами (выделения в цитате взяты из первоисточника):

The main difference between a Message-driven system with long-lived addressable components, and an Event-driven dataflow-driven model, is that Messages are inherently directed, Events are not. Messages have a clear, single, destination; while Events are facts for others to observe. Furthermore, messaging is preferably asynchronous, with the sending and the reception decoupled from the sender and receiver respectively.

Что, в моем кривом переводе на русский язык, будет звучать как:

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

А далее приводится цитата из Reactive Manifesto, в которой эта разница раскрывается более подробно:

A message is an item of data that is sent to a specific destination. An event is a signal emitted by a component upon reaching a given state. In a message-driven system addressable recipients await the arrival of messages and react to them, otherwise lying dormant. In an event-driven system notification listeners are attached to the sources of events such that they are invoked when the event is emitted. This means that an event-driven system focuses on addressable event sources while a message-driven system concentrates on addressable recipients.

В моем пересказе это будет звучать так:

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

Вот как-то так. Вот какие проблемы людей волнуют :)

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

А у людей из Lightbend-а есть и другая головная боль: они свои Reactive Streams пытаются навесить на акторы, а это непростая задача. Поскольку акторы по природе своей асинхронны, что плохо согласуется с непрерывными потоками данных из-за отсутствия естественного back-pressure. Тут лучше подходят CSP-каналы, но это уже совсем другая парадигма получается... И, как мне думается, именно в попытках скрестить ужа с ежом разработчики из Lightbend-а и вынуждены мешать в одну кучу message-driven и event-driven, а потом старательно объяснять в чем же именно разница между первым и вторым.

У нас в SObjectizer таких проблем нет :) У нас сообщение -- это просто способ доставки информации до того, кто в этой информации заинтересован. А событие -- это факт доставки сообщения до получателя (т.е. вызов обработчика для доставленного сообщения). При этом отсылка сообщения возможна как в режиме 1:1, т.е. у сообщения есть единственный получатель, которому целенаправленно сообщение и отсылается. Так и в режиме 1:N, т.е. у сообщения будет N получателей. Так что у нас все приложения получаются event-driven, при этом унутрях у них message-driven механизм распределения информации между агентами и рабочими потоками :)

Это, конечно же, идет в разрез с Моделью Акторов, в которой сообщение отсылается конкретному актору-получателю, а массовую рассылку в режиме 1:N нужно делать ручками. Но нам пофиг ;) Publish-Subscribe, с асинхронной доставкой сообщений подписчикам рулит и бибикает :) Хотя бы потому, что с ее помощью элементарно реализуется и взаимодействие в режиме 1:1.

PS. У попыток применить publish-subscribe для dataflow-driven обработки больших потоков данных будут те же самые проблемы, что и у Модели Акторов: т.е. отсутствие естественного механизма back-pressure. Год назад в SO-5 мы добавили CSP-шные каналы. Так что dataflow на mchain-ах в SO-5 уже делать можно. А если еще придумать, как более удобным и естественным образом отобразить mchain-ы и события агентов, то можно будет удобство dataflow-driven подхода в SO-5 вывести на совсем другой уровень.

понедельник, 9 января 2017 г.

[prog] В склерозник: три основных принципа в симуляции Boids от Крейга Рейнольдса

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

С тех пор время от времени я забывал про эти правила, вспоминал, искал в Интернетах, иногда находил, иногда нет. Сейчас вот вновь нашел, решил зафиксировать в склерознике. Речь, как оказалось, шла о симуляции поведения птичьих стай, под названием Boids. Эту симуляцию в середине 1980-х разработал Крейг Рейнольдс. Вот ссылка на статью в Wiki на эту тему.

А вот эти самые три простых правила:

  • каждая птица стремиться избежать столкновения с другими птицами стаи;
  • каждая птица стремиться двигаться в том же направлении, что и находящиеся неподалеку от нее птицы;
  • птицы стремятся двигаться на одинаковом расстоянии друг от друга.

Чем эта тема интересна мне? А тем, что когда в программе создается большое количество однотипных акторов, каждый из которых, вроде как работает по вполне себе простым и понятным правилам, предсказать поведение всей программы в какой-то определенный момент времени оказывается не так-то просто. И объяснять этот феномен на примере простых правил поведения птиц в стае оказывается очень удобно.

[prog.c++] Готовлю доклад для Corehard C++ Winter 2017

12-го февраля 2017-го года, в Минске пройдет очередная конференция сообщества Corehard C++. Я туда уже заявился с докладом "Шишки, набитые за 15 лет использования акторов в C++", в котором постараюсь рассказать про несколько "граблей", на которые довелось наступить, набить несколько шишек и задуматься о том, как этого не делать впредь.

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

Текста уже набралось на восемь страниц в Google.Doc-е. Полагаю, этого достаточно, чтобы уложиться в 40-минутный доклад. Увеличивать объем дальше стремно, повышаются риски не уложиться как в прошлый раз.

Из "граблей" в доклад попали следующие:

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

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

пятница, 6 января 2017 г.

[prog.memories] Неожиданный, приятный новогодний подарок :)

Бывший коллега по КБ СП сделал просто шикарный подарок к Новому Году:

Это каким-то чудом сохранившаяся документация по системе управления объектно-ориентированными БД, разработкой которой я занимался с 1995-го по 2000-й год.