четверг, 21 марта 2019 г.

[prog.bugs] Интересная ошибка, связанная с многопоточностью

В минувший вторник убил целый рабочий день на разбирательство с любопытным багом. В многопоточном коде, в котором пришлось иметь дело с голыми std::mutex-ами и std::thread. Кому интересно, милости прошу под кат. Ошибка, в общем-то, имеет C++ную специфику, но, полагаю, во что-то подобное можно втоптаться и в любом другом языке с ручным управлением ресурсами.

Итак, суть в том, что в один прекрасный момент тест, который до этого долгое время работал исправно, начал стабильно падать. Причем падал по разному под VC++ и MinGW, что добавило ярких красок в процесс поиска причины проблемы. В итоге длительного выкуривания бамбука и множества экспериментов причина была найдена. Ниже я попытаюсь в максимально упрощенном виде рассказать что происходило и почему это происходило.

среда, 20 марта 2019 г.

[prog] Тестов много не бывает...

В SObjectizer-е чуть менее 400 тестов. И когда вносишь ломающие совместимость изменения, то приходится изрядно попотеть, перелопачивая простыни старого кода, чтобы заменить устаревшие API-шные вызовы на новые.

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

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

Ну и да, традиционное: если у вас есть возможность не писать многопоточный код, то не пишите. А если вам все-таки нужно оный написать, то не опускайтесь на уровень голой многопоточности. Используйте лучше высокоуровневый инструментарий. Ну там акторов, CSP, task-flow, data-flow, STM и пр. Багов вы и там насажаете в свой код, можете даже не сомневаться. Но до такого траха, как с голой многопоточностью доходить будете гораздо, гораздо реже.

вторник, 12 марта 2019 г.

[prog.c++] C++Modules: there is no place for simplicity and beauty in C++?

C++Modules has been accepted in C++20. Nobody has a real experience with those modules and only few understand what C++Modules are. I don't understand that too. Moreover I don't read accepted Modules proposal yet. But I read a wonderful post "Understanding C++ Modules: Part 1: Hello Modules, and Module Units" and want to share some impressions.

It seems that simplicity and understandability weren't friends of C++ anytime in the past. But C++Modules lifts this up on another level.

It obvious that work on C++ standards is performed by very smart people. But sometimes you have to be as smart as they if not smarter to understand some of the new C++ additions and to find some beauty in them. C++Modules is an example.

Unfortunately I'm not as smart to participate in the evolution of C++ language. I'm just a (very ordinary) user of C++ and use C++ as a tool for solving my and my client's problems. Because of that, I can understand that there were some reasons to accept C++Modules in that form. But it's very hard to find and understand those reasons.

I can't understand why there are different types of module units (module interface, module implementation, module interface partition, module implementation partition, primary module interface) and very strange looking sentences like "export import :something;". Why not just:

module greeting;

export {

   public import another_module; // Instead of export import another_module.

   ... // Some ordinary C++ code.

// interface.

implementation {

   ... // Some ordinary C++ code.

// implementation.

If we have to deal with very big amount of code for a module we can simply use old #include directive:

module greeting;

export {

   public import another_module; // Instead of export import another_module.

   #include "some_declarations.hpp"
   #include "some_more_declations.hpp"

// interface.

implementation {

   #include "some_implementations.cpp"
   #include "some_more_implementations.cpp"
   #include "yet_more_implementations.cpp"

// implementation.

It's also hard to understand why modules and namespaces are orthogonal. Namespaces played their role in the pre-Modules world where we had only headers files and namespaces were used for "modularization" of C++ code.

But it's hard to imagine why we can write something like that:

import hello;

int main() {
   bye::tell();
}

From experience with different languages I expect that "import hello" introduces stuff from "hello" namespace. But in C++ we can "import hello" but receive "bye" namespace. Maybe there is some logic, but it seems also that "least surprise principle" doesn't live here.

I can suppose that there are some very important reasons why C++Modules and C++ namespaces are different entities. And I want to read the justification for this decision because as for me modules should make namespaces obsolete. With modules, we can get namespaces and nested namespaces (top-level modules and submodules).

Namespaces in C++ are open. It had two benefits in the past:

1. The content of namespace could be stored in several headers and source files. We opened namespace in one header file then reopened it in another file and so on.

But this benefit doesn't have sense with modules. IMHO.

2. An user can add specialization for its own types into external namespace.

But we can keep this benefit with modules if we add something like module's specialization (based on example from our json_dto library):

module json_dto specialization;

export {

   import my_module;

   template<>
   read_json_value( my_module::some_type & v, const rapidjson::Value & object )
   {
      ... // Specific version for some_type from my_module.
   }
}

Instead of conclusion.

I don't want to say that C++Modules proposal is bad. But it seems that C++Modules look much more complex than many of us expected. It also seems that C++Modules are intended to solve different problems than many of us can suppose.

It would be great to have some explanation about what C++Modules actually are, which problems they address, why C++Modules do it that way.

Without such explanation C++Modules remind me things like "export template" and "throw specification" from C++98 and "concept maps" from C++0x. They looked good in theory, but were deprecated or/and eliminated later.

суббота, 9 марта 2019 г.

[life.books] "Мастер своего дела": начал читать, дошел до первого примера, закончил читать

По случаю прикупил книгу "Мастер своего дела" Мортена Хансена. Хансен мне известен тем, что был соавтором у "гуру" Джима Коллинза при работе над "Великие по собственному выбору". В аннотации к "Мастеру своего дела" было сказано, что автор провел многолетнее исследование и выявил ряд привычек, которые присущи людям, демонстрирующим высокую личную производительность.

Начал читать. В начале слишком много вступительных слов о том, как автор пришел к идее этого исследования, как он решился на исследование, как исследование проводилось и о чем же пойдет рассказ дальше. Что уже несколько насторожило. Но потом я все-таки дошел до первой имеющей отношение к делу главы. Это глава под названием "Делай меньше, да лучше". Где автор в качестве самого яркого демонстрационного примера решил использовать удачный поход к Южному полюсу Руаля Амундсена и неудачный поход туда же Роберта Скотта. И вот тут у меня стали закрадываться подозрения: либо автор не очень понимает суть приводимого им примера, либо, что хуже, старается переинтерпретировать факты в свою пользу.

воскресенье, 3 марта 2019 г.

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

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

Оверлорд (Overlord, 2018). Фильм вторичный и трэшовый, но я получил удовольствие от просмотра. Какой-то привет из видеосалонов 1980-х, где можно было попасть на пусть и тупой, но бодрый боевичок в котором несколько главных героев мужественно сражаются с невесть откуда взявшимися монстрами.

На краю (Cut Bank, 2014). Далеко не шедевр. Но мне понравился. Добротный фильм. Хотя какие-то вещи в итоге остались непонятными, что портит общее впечатление.

Море соблазна (Serenity, 2019). Сюжет для меня лично оказался "немного предсказуем", после где-то на последней трети фильма я уже понимал, чем все закончится и как будут оправдывать происходящее. Но вот визуальная составляющая выше всяких похвал: что ни кадр, то образец для изучения композиции и освещения.

Виновный (Den skyldige, 2017). На удивление неплохо. Прекрасный образец того, как можно построить напряженный сюжет только на одном персонаже и диалогах. Хотя некоторые моменты вызывают вопросы и портят впечатление, но сам факт того, что это датская картина, очень сильно и приятно удивляет.

Алита: Боевой ангел (Alita: Battle Angel, 2019). Понравилось исполнение, картинка радует глаз. Понравилось то, что это один из немногих фильмов за последние годы, который хоть как-то претендует на жанр научной фантастики. Сюжет не понравился. Да и само по себе это кино для детей.

Зеленая книга (Green Book, 2019). Мне не зашел. Довольно примитивно, сильно предсказуемо, никакой интриги. Такое ощущение, что целью фильма было скрыть ужас отношения к неграм в США даже спустя 100 лет после отмены рабства обаятельным главным героем. Мол, да, к неграм относились как к скоту, но ведь не все же, были среди белых и нормальные люди.

Время возмездия (Destroyer, 2018). Скучно и затянуто. Возможно, фильм снимался для того, чтобы показать Николь Кидман как сильную драматической актрису. Но это и не получилось из-за занудности происходящего.

Правила бойни (Slaughterhouse Rulez, 2018). Редкая муть. Даже непонятно, как туда попали Саймон Пегг, Марго Робби и Ник Фрост.

пятница, 1 марта 2019 г.

[prog.thoughts] Еще раз на тему недовольства старых C++ников развитием языка

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

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

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

[prog.thoughts] Legacy for the masses?

В свете последних вестей с полей стандартизации C++ (TL;DR: С++ станет еще больше и сложнее, сильно больше и сильно сложнее) подумалось о том, что мы становимся свидетелями того, как с понятием legacy сталкивается все больше и больше разработчиков. Что достаточно необычно для массового софтостроения, как мне кажется.

Попробую пояснить свою мысль.

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

[prog.concurrency] И о чем же потрындели эти трое заслуженных товарищей?

Наткнулся давеча на разговор трех мэтров конкурентного программирования: Джо Армстронга (это который папа Эрланга), Тони Хоара (это который папа модели CSP) и Карла Хьюитта (это который папа модели Акторов): Let's #TalkConcurrency Panel Discussion with Sir Tony Hoare, Joe Armstrong, and Carl Hewitt. За несколько подходов осилил стенограмму их разговоров. Но не осилил главного: что в сухом остатке?

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

Есть ощущение, что три почтенных старца потрепались о чем-то своем, изрядно поржав походу дела. И, собственно, все.

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

Кстати говоря, ссылка на эту беседу была найдена на HackerNews. Там в комментариях ничего интересного не обнаружилось. Мне показалось, что доминирует типичное фанбойство Erlang-еров. Мол, в Erlang-е все зашибись, мы делали на Erlang-а ахриненные программы, ничего лучше и не пожелаешь. И все это на фоне неасиляторов с жалобами в стиле "мы не понимаем как акторы нам помогут". Ну еще и Rust-оманы в очередной раз прибежали с воплями про то, какой у них замечательный фетиш.

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

Но туда же в комментарии пришел и Карл Хьюитт, выдав очередной поток какой-то мутной херни, уж простите мне мой французский. Классы ему, блин чем-то помешали. Ну прямо как в анекдоте: "Не люблю я кошек, от них шерсть, вонь..." -- "Ба! Да вы просто не умеете их готовить!"

В общем, если кто-то хотел потратить часть своего времени на прослушивание/прочтение этой беседы и/или ее обсуждения на HackerNews, то лучше не нужно. Потратьте это время лучше на изучение Erlang, Elixir, Go, Akka, CAF, SObjectizer, Vert.x, Orleans и других инструментов. А так же примеров их использования. Практической пользы будет больше.

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

[prog.c++] bad_alloc == приговор?

В принципе, свое мнение по поводу контроля или не контроля успешности выделения памяти в C++ программах, я в концентрированном виде высказал когда-то в комментариях на Хабре:

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

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

Но в последние несколько недель регулярно приходится сталкиваться с навязыванием мнения, что как-либо бороться с нехваткой памяти бесполезно, что bad_alloc, по сути, является приговором. Причем происходит это так часто, что имеет смысл вновь вернуться к данной теме. Кому интересно, милости прошу под кат.

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

[prog.memories] Фича, о которой я уже успел пожалеть раза три, минимум. И это еще не предел, наверное...

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

пятница, 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 мы не получим, т.к. и вилки уже перестали работать, и наш канал уже закрыли.

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

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

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

[prog.sadness] Buckaroo: заменить одно ненужно на другое :(

Наглядный пример того, как выбросить одно ненужно и заменить его другим ненужно: https://github.com/LoopPerfect/buckaroo/releases/tag/v2.0.0

Есть такая система сборки для C++ проектов: Buck.
И к ней система управления зависимостями Buckaroo.
Кажется, от чуваков из Facebook.

Так вот, раньше эта система управлениями зависимостями была написана на Java. Соответственно, хочешь использовать для своих C++ проектов Buckaroo -- ставь себе JRE.

А теперь это все добро взяли и переписали на чем?

На .NET.

Инсталлятор этой прелести для Windows весит 35Mb, для Linux-а и Mac-а чуть больше 65Mb. Для FreeBSD готового инсталлятора нет.

Что в этом всем печальнее всего?

А то, что по своей задумке и Buck, и особенно Buckaroo, наиболее интересные и вменяемые из всего, что сейчас развивается в мире C++ инструментария, включая CMake, build2, meson, vcpkg, Conan, Hunter и пр. А уж Bockaroo, так это чуть ли не доведенный до своего логического завершения MxxRu::externals. Все ИМХО, конечно же.

[prog.thoughts] Rust дал compiler-driven development широким массам

Вчера, в результате обсуждения в Facebook-е двух вариантов одного и того же кода на Rust-е довелось таки воспользоваться Rust-овским playground-ом и набросать на Rust-е пару-тройку собственных вариантов.

С учетом того, что к Rust-у я не прикасался, наверное, с апреля прошлого года (когда мне пришлось проштудировать доку по Rust-у для участия в панельной дискуссии на C++ CoreHard-е), было, скажем так, любопытно.

Стало понятно, что имеют в виду растоманы, когда говорят, что компилятор им помогает писать код.

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

Поэтому не остается ничего другого, как делать то, что тебе говорит компилятор. А потом оно раз! И работает.

Ну понятно, почему у людей крышу-то сносит. Особенно у тех, кто на Rust с динамики, вроде JS, Python или Ruby приходит.

Имхо, здесь есть сильная аналогия с тем, какую серьезную роль в разработке софта в середине-конце 1990-х годов произвели IDE. Сперва Delphi, затем IDE для Java (при этом IDE для C++, имхо, в те времена, да и потом, сильно недотягивали до Java-аналогов, что обуславливалось особенностями языка). Можно сказать, что в 1990-х сформировался IDE-driven development, который пышным цветом расцвел в 2000-х. Да и сейчас, наверное, цветет и пахнет.

А вот Rust, похоже, делает доступным для широких масс такую штуку, как compiler-driven development.

Что, как мне кажется, неизбежно скажет свое веское слово в индустрии софтостроения.

Но знаете, что по-прежнему удивляет меня сильнее всего касательно Rust-а? Это то, что не смотря на всю крутотень Rust-а и толпы писающих кипятком фанатов для Rust-а еще не появилось ни одного сколько-нибудь заметного GUI-фреймворка. За 3.5 года после выхода стабильного Rust 1.0. За три с половиной, мать его за ногу, года.

Да в 1990-е на первых версиях C++ GUI-фреймворки в одно рыло клепались только в путь и росли как грибы после дождя. Первая версия Qt была сделана за четыре года. В 1990-е, на древнем C++. Маленькой командой. Без GitHub-а. Только вдумайтесь. Да и сейчас люди делают вещи вроде ImGui и Nana. Для C++, не для Rust-а. Загадка, однако.

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

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

Звезда родилась (A Star Is Born, 2018). Сюжет немного предсказуем. Актриса из Леди Гага никакая. Диалоги неестественные и тупые. Бредли Купер хорош. И музыкальное сопровождение немного спасает ситуацию.

Эшер (Asher, 2018). Проходной и не очень интересный фильм. Однако, приятно увидеть, что Ричард Дрейфусс, Рон Перлман и Фамке Янссен в отличной для своих лет форме.

Исчезновение (The Vanishing, 2018). Вот тут сильно двойственные чувства. С одной стороны, хорошая история и отличное техническое воплощение в фильме (работа оператора, имхо, заслуживает отдельных похвал). Но, с другой стороны, неудачный подбор актеров. С трудом верится в то, что брутальный герой Батлера в конце фильма превратится в истеричку.

Репродукция (Replicas, 2017). Хорошая задумка. И несколько звездных актеров в главных ролях. Но катастрофически плохие спецэффекты.

Близко (Close, 2019). Трейлер, к сожалению, оказался интереснее, чем сам фильм. Да еще и вобрал в себя практически весь имевшийся в наличии экшн.

Вдовы (Widows, 2018). Собрали крутых актеров, а вышла какая-то непонятная и тягомотная хрень с мутным финалом.

Хроники хищных городов (Mortal Engines, 2018). Редкая муть и бредятина. Даже отличный видеоряд не спасает.

Робин Гуд: Начало (Robin Hood, 2018). Это какой-то ППЦ. В процессе просмотра разбил себе лицо фейспалами.

[disillusion] Google+ фсе :(

Google сегодня окончательно порадовал: в период с 4-го февраля по 2-е апреля будет уничтожено все, что связано с предназначенным для индивидуальных пользователей Google+. В том числе исчезнут из Blogger-а созданные через G+ комментарии. Собственно, уже исчезли, потому, что в настройках Blogger-а использование G+ комментариев я сегодня отключил.

Приношу свои извинения читателям, т.к. в комментариях содержалась масса интересного.

Google показал волевое решение настоящих, больших бизнесменов. Если уж ходить, так по крупному. Раз сказали в морг, значит в морг. Оставить существующий контент хотя бы в режиме read-only? Актитесь, половинчатые решения -- это для сопляков. Сделать платные аккаунты и брать с пользователей арендную плату за поддержку их контента в G+? Да кому вы нужны со своей жалкой десяткой долларов в год, когда компания ведет многомиллиардный бизнес.

четверг, 31 января 2019 г.

[work.pain] О наболевшем: github or not github?

Простите, я опять на тему SObjectizer-а, хотя постараюсь в этом году в блоге про него писать пореже.

Пора уже вплотную заняться работой над версией 5.6, но я все еще не определился с тем, где держать основной репозиторий с его исходными текстами. Понятно, что это будет не SourceForge. Но вот github, bitlab, bitbucket или что-то еще?

Рассудок подсказывает, что раз де-факто стандартом является github, то нужно делать на github.

Но у этого выбора есть два фатальных недостатка: git и github :)

Так уж получилось, что мне не нравится ни первое, ни второе. Понятное дело, что все это субъективно, что могу пользоваться и тем, и другим (собственно, вынужденно и пользуюсь). Но мне с hg и bitbucket-ом гораздо проще и удобнее. Ну и в работе же должно быть хоть какое-то удовольствие, а какое тут удовольствие, когда в придачу к C++ еще и git с github-ом? ;)

Поэтому пока не могу сделать выбор между просто git+github-ом и hg+bitbucket+зеркало на github-е. Больше склоняюсь к hg+bitbucket+зеркало.

Но есть подозрение, что это неправильный выбор... :(

[prog.flame] Возраст и умение программировать. Или становятся ли программисты с возрастом лучше?

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

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

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

вторник, 29 января 2019 г.

[prog.c++] "Modern" Dining Philosophers in C++ with Actors and CSP (part 2)

In the previous post we discussed several implementations of "dining philosophers problems" based on Actor Model. In this post I will try to tell about some implementations based on ideas from CSP. Forks, philosophers and waiter will be represented as std::thread and will communicate each other via CSP-channels only.

Source code can be found in the same repository.

CSP-based Implementations

Like in the previous post we will start from implementation of Dijkstra's solution, then we will go to simple solution with putting the first fork if an attempt to take the second fork fails (without arbiter), and then we will go to solution with waiter/arbiter. It means that we will see the same solutions like in previous post, but reimplemented without Actors. Moreover the same set of messages (e.g. take_t, taken_t, busy_t, put_t) from Actor-based implementations will be reused "as is" in CSP-based implementations.

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

[prog.c++] "Modern" Dining Philosophers in C++ with Actors and CSP (part 1)

Some time ago a reference to an interesting article "Modern dining philosophers" was published on resources like Reddit and HackerNews. The article discusses several implementations of well-known "dining philosophers problem". All those solutions were built using task-based approach. I think the article is worth reading. Therefore, if you have not read it yet, I recommend read the article. Especially if your impressions of C++ are based on C++03 or more earlier versions of C++.

However there was something that hampered me during the reading and studying proposed solutions.

I think it was usage of task-based parallelism. There are too many tasks created and scheduled thru various executors/serializers and it's hard to understand how those tasks are related one to another, in which order they are executed and on which context.

Anyway the task-based parallelism is not the single approach to be used to solve concurrent programming problems. There are different approaches and I wanted to investigate how a solution of "dining philosophers problem" can looks like if Actors and CSP models will be used.

To do that I implemented some solutions of "dining philosopher problem" with Actors and CSP models. Source code can be found in this repository. In this post you will find description of Actors-based implementation. In the next part I will tell about CSP-based implementations.

пятница, 25 января 2019 г.

[prog.c++] Добавили в RESTinio возможность получить remote_endpoint

Мы выпустили небольшое обновление для RESTinio, в котором добавили возможность получить remote_endpoint для HTTP-запроса или WS-соединения. В классы request_t и websocket::basic::ws_t добавлен метод remote_endpoint(), возвращающий ссылку на значение типа asio::ip::tcp::endpoint.

Свежую версию, 0.4.8.5, в настоящее время можно взять с BitBucket или GitHub. Обновление пакетов для vcpkg и conan-а последует несколько позднее.

В принципе, появление remote_endpoint() рассматривается как первый шаг к тому, чтобы добавить в RESTinio возможность блокировки нежелательных подключений. Например, приложение может контролировать активность клиентских подключений и если видит что-то подозрительное (скажем, большое количество однотипных запросов или запросов с некорректными параметрами от одного узла), то приложение может на какое-то время прекратить обработку подключений от этого узла. Ну, или в совсем простом варианте -- тупо поддержать что-то вроде black/white lists.

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

Пару слов о состоянии RESTinio. У нас сейчас нет достаточных ресурсов для активной работы над RESTinio, поэтому разработка новой функциональности несколько заморожена. Но если вы встречаетесь с какими-то косяками или непонятными моментами в работе RESTinio, то дайте нам знать. Мы стараемся с такими случаями разбираться максимально оперативно.

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

среда, 23 января 2019 г.

[prog] Любопытный момент при реализации решения "обедающих философов" с использованием очереди "обиженных" философов

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

Что пока удивило больше всего. Про саму задачу "обедающих философов" я знаю уже лет 25, если не больше. Даже помню, кто из преподавателей в нашем универе нам про нее на лекции впервые рассказывал. И помню, что за это время раза два мне приходилось ее реализовывать в, так скажем, иллюстративном варианте. Т.е. не находить оптимальное решение, а просто делать реализацию, которая лишена хотя бы проблемы дедлоков. А вот решать ее всерьез, чтобы устранить и дедлоки и голодания, да еще в строгом соответствии с исходной формулировкой... Вот этого не приходилось делать.

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

В исходной статье, которая стала толчком для всей этой истории, реализация с арбитром и очередью называется WaiterFair (исходники этой реализации здесь). Хотя в этой реализации есть ошибка и проверяется там наличие только соседа справа.

Итак, в чем суть этой очереди и почему там нельзя проверять наличие обоих соседей?

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

[prog] И еще раз об обозримости task-based подхода

В докладе "Actors vs CSP vs Tasks..." на C++ CoreHard Autumn 2018 (видео тут, текстовая версия тут) я сказал, что когда код пишется с использованием task-based подхода, то обозримость у этого кода получается так себе. А несколько дней назад на Reddit-е всплыла ссылка на статью под названием "Modern dining philosophers". В которой как раз демонстрируется несколько подходов к решению известной задачи "обедающие философы". Но все эти подходы используют task-и.

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

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

В общем, сходите, почитайте статью. Она не новая, вышла в конце декабря 2018-го, ссылка на нее только недавно на глаза попалась. И не очень маленькая, полчаса времени, минимум, выделить придется. Составьте собственное впечатление. А будет желание -- поделитесь впечатлением в комментариях.

PS. Я думаю написать статью с разбором решения этой же задачи на базе SObjectizer-овских агентов. Кому интересно подобное "сравнение" (хотя это не будет чистой воды сравнением), не пожалейте времени поставить плюсадынку или лайк. Чем больше оных наберется, тем быстрее появится моя статья.

пятница, 18 января 2019 г.

[prog.thoughts] "C++ vs others" через призму "поддерживающих" и "подрывных" технологий

В комментариях к предыдущей заметке "О чем не нужно забывать бросаясь какашками в C++" у меня с Григорием Демченко развернулся спор. Полагаю, что следует обозначить контекст, на который я опирался в этом споре. В противном случае некоторые тезисы (например, о том, что 5 лет -- это небольшой срок для ИТ) выглядят странно, если не сказать больше.

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

вторник, 15 января 2019 г.

[prog.c++] О чем не нужно забывать бросаясь какашками в C++

Конец 2018-го года и начало 2019-го сопровождалось каким-то невиданным количеством критики в адрес языка C++. Что лично у меня, как нехило вложившегося в разработку инструментария для C++, вызвало тяжелые ощущения. Как-то не очень приятно, когда на полянку, которую ты много лет тщательно расчищал и облагораживал, какие-то странные люди вываливают несколько тележек дерьма, а потом еще и начинают радостно разбрасывать его во все стороны.

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

Но позволю себе немного старческого брюзжания и морализаторства на тему того, что современная молодежь (а, временами, и не молодежь), не обладая должным кругозором и опытом, не может или хочет, видеть картину во всем ее многообразии. Посему попробую перечислить несколько важных факторов, которые нужно принимать во внимание, разговаривая о C++ и его проблемах.

пятница, 11 января 2019 г.

[prog.f*ck] Самый унылый релиз SObjectizer-а. И его последствия. Пока непонятные

Намедни мы выпустили очередную версию SObjectizer-а. И, пожалуй, на анонс этой версии была самая унылая реакция. Когда я начинал писать этот пост, на Reddit-е анонс SO-5.5.24 набрал всего 2 очка при 60% upvotes. И там был всего один вопрос про сравнение с CAF-ом, ответ на который изначально заминусовали. Собственно, показатели посещаемости сайта и загрузок в этот раз ничем не лучше.

вторник, 8 января 2019 г.

[prog.flame] Управление памятью в Rust: придумалась хорошая аналогия

Угораздило меня вляпаться на Хабре в комментарии к статье про Rust. Попытки общения с упоротыми растоманами, принципиально не умеющими воспринимать какую-то другую точку зрения, оставляют специфические ощущения. Но больше всего доставило то, что люди всерьез считают, что в Rust-е какой-то другой механизм управления памятью, не такой, как в C и C++.

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

Итак, давайте посмотрим, как эволюционировали носители для письменности. Грубо, не вдаваясь в дебри истории, просто на уровне банальной бытовой эрудиции.

Сперва были глиняные таблички, папирусы. Где-то береста. Потом уже появилась бумага и бумажные свитки.

И все это похоже на то, как мы управляем памятью программируя на ассемблере.

среда, 2 января 2019 г.

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

Начало нового месяца, время публиковать список просмотренных в минувшем месяце фильмов. По традиции, в начале то, что понравилось больше всего, далее по убывающей.

Ничего хорошего в отеле «Эль рояль» (Bad Times at the El Royale, 2018). Мне очень понравился. Пожалуй, однозначно лучший фильм из просмотренных в декабре. Но зайдет не всем, кино на любителя.

Хэллоуин (Halloween, 2018). Вот прям понастольгировал. В духе фильмов 1980-х. Немного динамики и жестокости не хватило, но в целом пахнуло чем-то из эпохи вокзальных видеосалонов.

Тайна дома с часами (The House with a Clock in Its Walls, 2018). Наверное, неплохой мог бы быть фильм для семейного просмотра. Но непонятно, на какую возрастную аудиторию фильм рассчитан: маленьким детям будет страшно, не маленьким -- не интересно.

Братья Систерс (The Sisters Brothers, 2018). Отличных актеров подтянули. Сняли отлично. Вроде бы даже история какая-то в фильме есть. Но вот после просмотра остается вопрос: "А о чем был фильм вообще?"

Лукас (Lukas, 2018). Как по мне, как сильно тягуче и не динамично. Но атмосферно. И далеко не самая худшая попытка ван Дамма сняться в драматической роли.

Землетрясение/Разлом (Skjelvet, 2018). Продолжение вышедшего несколько лет назад норвежского фильма Волна. На протяжении всего фильма меня раздражал истеричный и невнятный главный герой. Но для Норвегии прям неожиданно приличный уровень спецэффектов.

Бои без правил (A Prayer Before Dawn, 2017). Не то, чтобы мне понравился весь фильм. В целом он слабоват. Но пару хороших моментов стоит отметить. Это удачно созданная в фильме атмосфера липкого, навязчевого и неустранимого звиздеца, в которого оказался главный герой. И, на мой личный взгляд, хорошо поставленные сцены боксерских боев. Без показушной хореографии, как в каратековских фильмах. И уж тем более, без того маразма, который можно было увидеть в старых "Рокки".

Простая просьба (A Simple Favor, 2018). Не понял, что это было. Не триллер, не комедия, ни детектив, ни драма. Какая-то странная солянка, в которой сильно чего-то не хватает. За весь фильм был лишь один момент, который понравился.