суббота, 1 февраля 2020 г.

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

За минувший месяц накопился более-менее объемный список просмотренных фильмов, которым не стыдно поделиться. Что и делаю :)

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

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

Ford против Ferrari (Ford v Ferrari, 2019). Не смотря на то, что тема "производственной драмы" мне не близка, да еще и к автомобилям я совершенно равнодушен, фильм все равно доставил массу удовольствия. Особенно некоторые моменты, связанные с корпоративными дрязгами в большой компании. Наверное лучший фильм из вышедших в 2019-ом.

Идеальный пациент (The Perfect Patient, 2019). Мне понравилось. И история сама по себе интересная, и рассказана хорошо, и европейцы кино как-то по своему снимают, не так как в Голливуде. Так что посмотрел с удовольствием.

Мистер Олимпия (Bigger, 2018). Очень незамысловатый, простой, прямолинейный, но почему-то отлично зашедший мне фильм. Наткнулся случайно и посмотрел потому, что ничего другого на глаза не попалось. Был приятно удивлен. Но, вполне возможно, подобное кино на любителя и понравится далеко не всем. Мне же понравилось как актер, игравший главного героя, сумел передать образ фанатично увлеченного своим делом человека. Из тех, кто слегка "не от мира сего".

Коррупционер (The Corrupted, 2019). В общем неплохо. Но мне не понравился финал. Такое ощущение, что его специально сделали помягче, чтобы не превратить фильм в совсем уж мрачную криминальную драму.

Мидуэй (Midway, 2019). Красочно, мощно, известных актеров подтянули. Однако воспринимается все это как не очень дорогой аттракцион. И картинка на экране видно, что нарисована, и некоторые персонажи раздражают, и повествование какое-то поверхностное. В общем, явно хотели переплюнуть "Перл-Харбор" от 2001-го года, но не смогли.

Решала. Нулевые (2019). Простенько, недорого. Но можно посмотреть. Хотя несколько лет назад выходил другой фильм "Решала" из двух частей. Так вот как по мне, так лучше посмотреть первую часть именно того "Решалы".

Девятая (2019). Снято дорого и красиво. Но не цепляет.

Роман Израэл, Esq. (Roman J. Israel, Esq., 2017). После просмотра трейлера ожидал совсем другого. Поэтому был разочарован. Как по мне, так фильм скучный и неинтересный.

Безумный куш (Danger One, 2018). Фильм разочарование. Первая половина зашла просто отлично. Казалось, что за небольшие деньги сняли что-то стоящее и цепляющее. Но бездарно слитый финал все напрочь испортил.

Последняя пуля (Disturbing the Peace, 2020). Дешевый отстой. Смело можно не смотреть.

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

Как ни странно, но в этом "Терминаторе" мне понравились две вещи:

среда, 29 января 2020 г.

[prog.c++] Почему люди выбирают RESTinio

Давеча мы внезапно получили неплохую реакламу на reddit-е в виде комментария от ned14 (известного, например, как автор Boost.Outcome). Позволю себе процитировать этот комментарий здесь полностью:

I recently had to choose a lightweight modern C++ web framework, and the choices came down to oatpp or https://github.com/Stiffstream/restinio.

I ended up choosing restinio because:

  1. Writing C++ for restinio is much more C++ idiomatic - no macros, one uses {fmt} to append to responses, string views and zero copy are pervasive, it leverages as much of C++ 20 including proposed standard feature reference libraries as possible. This makes sorting out dependencies messy, but it's a once off investment, and https://github.com/cpp-pm/hunter hand waves away the dependency problem in any case.
  2. restinio exposes the ASIO it wraps, which makes the rest of the team feel much more comfortable. ASIO is widely understood, whereas custom internal async i/o frameworks are often sources of surprise. Also, we know how to hook and extend ASIO to do custom stuff, that's team embedded knowledge.
  3. There were recent comparative benchmarks for restinio not written by the author https://github.com/ngrodzitski/test20171219 which showed restinio can be class leading in performance for the thing tested, even marginally edging out Beast for that test.

I don't want any of this to diss oatpp. I just wanted to explain what motivated me to not choose it, which may aid its authors in telling a better story to improve adoption.

For the record, restinio adoption has gone okay so far, a bit of resistance from some team members about some of its design choices, but everybody is just loving {fmt} for efficiently generating responses. The team is literally benchmarking our REST server for production right now, so far looks promising, it definitely can max out a 1Gb NIC, still awaiting the 10Gb and 40Gb NIC results.

Т.е., если не дословно, но по сути:

  1. Работа с RESTinio происходит в более идиоматическом для C++ стиле, нет макросов, применяются fmt, string_view и вообще сделан упор на библиотеки, которые должны стать частью будущих стандартов C++.
  2. RESTinio дает доступ к ASIO, а у команды есть большущий опыт правильного приготовления ASIO, и это как-то безопаснее, чем иметь дело с самодельным фреймворком для асинхронного I/O.
  3. Были найдены сравнительные бенчмарки, которые показывают, что у RESTinio вполне себе конкуретноспособная производительность.
  4. Пока что RESTinio более-менее хорошо зашла проектной команде. Были недовольные теми или иными проектными решениями в RESTinio, но всем нравится применять fmt для формирования ответов на запросы. И прямо сейчас проводятся бенчмарки разрабатываемого командой REST-сервера. Пока что результаты выглядят обнадеживающими.

Было очень приятно получить такой отзыв. Значит не зря мы над RESTinio работаем. Ну а может кому-то этот отзыв поможет сделать правильный выбор ;)

От себя добавлю, что в случае с RESTinio мы еще более открыты к предложениям, чем с SObjectizer. Поскольку RESTinio еще совсем молодой проект, который даже до версии 1.0 пока не добрался, то мы с удовольствием прислушаемся к пожеланиям пользователей для того, чтобы наполнить RESTinio той функциональностью, которая сделает разработку RESTful приложений на C++ простой и приятной.

вторник, 28 января 2020 г.

[prog.c++] Перевел демо-проект so5-dining-philosophers на свежие версии SObjectizer, so5extra, fmtlib

Год назад на Хабре была опубликована большая статья "«Современные» обедающие философы на C++ посредством акторов и CSP", в которой рассматривалось несколько реализаций решения задачи "Обедающих философов" на SObjectizer (как на базе агентов, так и на базе голых нитей с mchain-ами).

За прошедшее время многое поменялось: вышли новые версии SObjectizer-а (5.6 и 5.7) несовместимые с SO-5.5, на котором были написаны примеры для статьи. А Atlassian принял решение удалить в 2020-ом году с BitBucket-а все Mercurial репозитории. Эта участь ожидает и исходный репозиторий, в котором были собраны примеры кода для статьи.

Так что этот демо-проект подвергся модернизации. Во-первых, он переехал на GitHub: so5-dining-philosophers. Во-вторых, код был переведен на свежие версии зависимостей: SObjectizer-5.7.0, so5extra-1.4.0 и fmtlib-6.1.2.

Поэтому теперь для so5-dining-philosophers нужен C++17. Старая версия под C++14 и SO-5.5 доступа под тегом 20190129.

Несколько слов про адаптацию старых решений под новый SObjectizer:

  • потребовалось исправить сигнатуру метода state_watcher_t::changed. Этот метод в SO-5.6/5.7 должен быть noexcept. В данном демо-примере noexcept означает не то, что changed() не будет бросать исключений, а то, что нет возможности продолжить работу, если исключение все-таки выскочило, поэтому нужно грохнуть все через std::terminate;
  • потребовалось исправить сигнатуру метода do_deliver_message в собственном типе mbox-а. В SO-5.6/5.7 этот метод уже не помечен как const, а в SO-5.5 эта отметка долго сохранялась по соображениям совместимости;
  • пришлось изменить подписку у некоторых агентов. Ранее использовалась нотация state.event<Signal>([]{...}), теперь она не поддерживается и нужно использовать унифицированный вариант: state.event([](mhood_t<Signal>){...}). Это было одним из ломающих совместимость изменений в SO-5.6;
  • в нескольких вызовах receive для чтения входящих сообщений из mchain-ов потребовалось указать handle_all(), поскольку SO-5.6/5.7 требуют, чтобы для receive/select было указано количество обрабатываемых сообщений (т.е. нужно вызывать handle_n/handle_all/extract_n явным образом). Контролируется это во время компиляции. О том, как этого удалось достичь была отдельная статья на Habr-е;
  • потребовалось поменять создание диспетчеров. Вместо вызовов вида create_private_disp(env)->binder() начиная с SO-5.6 нужно писать make_dispatcher(env).binder(). Собственно, это одно из принципиальных отличий SO-5.6 от SO-5.5.

В общем, перевод не занял много времени. И не потребовал каких-то серьезных усилий. Компилятор сам бил по рукам в местах, которые нужно поправить. После правок все ожидаемо завелось и поехало :)

Но важность сохранения совместимости все равно осознал. Постараюсь больше ломающих нововведений в SObjectizer не вносить и держать совместимость в рамках SO-5.7 как можно дольше.