суббота, 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 как можно дольше.

четверг, 23 января 2020 г.

[prog.c++] Стали доступны SObjectizer-5.7.0 и so5extra-1.4.0

Главное нововведение в SObjectizer-5.7.0 -- это поддержка send_case в функции select(). Т.е. теперь select() может не только читать сообщения из нескольких каналов, но и отправлять сообщения в каналы как только целевой канал оказывается готов для приема нового сообщения. Увидеть это можно в новом примере mchain_fibonacci, сделанного по мотивам аналогичного кода из A Tour of Go.

Фичу эту хотелось добавить в SObjectizer уже давно. Но вот только сейчас сошлись звезды. И по этому поводу я даже решился пойти на то, чтобы поломать совместимость с не так давно выпущенной версией 5.6. Поломка, правда, не такая уж и серьезная, старая функция case_, которая ранее использовалась для чтения входящих сообщений из канала в select(), теперь называется receive_case. Так что перейти с SO-5.6 на SO-5.7 можно посредсвом банального Search-and-Replace. Но формально совместимость сломали, да.

А в so5extra-1.4.0 самое важное -- это смена лицензии. Если предыдущие версии распространялись под двойной лицензией и для использования в закрытом коммерческом ПО нужно было покупать лицензию, то теперь so5extra распространяется под BSD-3-CLAUSE лицензией и может использоваться бесплатно.

Полный список изменений для SO-5.7.0 можно увидеть здесь, для so5extra-1.4.0 -- здесь.

Думаю, что нужно специально подчеркнуть то, что разработка SO-5 и so5extra окончательно перехала на GitHub. Вскоре на BitBucket поудаляют Mercurial-репозитории, так что жить приходится с git-ом на GitHub-е. Я, хоть и плююсь постоянно от git-а и отдыхаю душой и телом, когда представляется случай воспользоваться Hg, но вынужден смирится :(

Отдельно пару слов о будущем SObjectizer-а.

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

А вот вопрос о том, когда будут выходить новые версии SObjectizer-а является открытым. Большие фичи, которые хотелось сделать в SO-5 лично мне, уже сделаны. Поэтому больших релизов на горизонте не предвидится. Мелкие корректирующие релизы будут выходить по мере надобности.

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

В завершении скажу немного про свои ощущения от применимости SObjectizer-а.

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

Так что не на правах рекламы, а просто в порядке "поделится опытом": если у вас есть необходимость работать с многопоточностью в C++, то возьмите что-нибудь типа SObjectizer-а. Не обязательно SObjectizer. QP/C++, CAF, Boost.fibers, да что угодно, что может дать вам акторов и/или CSP-шные каналы... Но лучше, конечно же, SObjectizer ;)

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

[prog.c++] Шаблоны, но уже не против копипасты.

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

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

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

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

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

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

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

struct testing_traits_t {
   using client_type = testing_client_info_t;

   static first_property_type get_first_property(const client_type * cln) {...}
   static second_property_type get_second_property(const client_type * cln) {...}
   ...
};

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

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

Вот такое вот немного нестандартное применение шаблонов. Не столько для написания обобщенного кода, сколько для абстрагирования от реального окружения, в котором затем шаблону нужно было работать.

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

PS. Желающим поговорить про то, почему все это неправильно и что правильнее было бы разделить приложение на отдельные модули со строго определенными интерфейсами, что позволило бы использовать mocking при тестировании и пр. правильные вещи, могу сказать одно: добро пожаловать в реальный мир.

PPS. Если вы сами владеете старым C++ным или C-шным проектом и испытываете сложности с его поддержкой/развитием, то вам сюда. Возможно, мы сможем помочь ;)

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

[prog.rust.flame] "Говорил я вам. Не прислушались. Так и получилось. Как говорил я вам..."

На выходных, лениво пожевывая попкорн почитывал срачик на Habr-е, в котором светлые рыцари ордена safe Rust-а громко доказывали, что писать код так, как сделал автор Actix-Web, ни в коем случае нельзя. Занимательное чтиво, аж душа пела.

Пела потому, что когда лет 5-6 назад первые упоротые в своей воинственности Rust-оманы начали бегать по профильным форумам и убеждать всех тех, кому Rust вообще не был интересен, что Rust -- это самое лучше, что произошло с софтостроением после изобретения перфокарт, некоторые скептически настроенные старпёры сердито ворчали: "Ну подождите пару-тройку лет, в этот ваш Rust обязательно придут люди, которые начнут использовать unsafe, скажем так, весьма творчески. Вот тогда и посмотрим, насколько Rust окажется safe в реальной-то жизни".

Ну вот и дождались.

Вполне ожидаемо оказалось, что это во влажных мечтах оторванных от реальности фанатов в боевом коде на Rust-е unsafe либо не будет вообще, либо он будет локализован, тщательно оттестирован и аналь огорожен.

Просто одно дело, когда ты в свободное время пишешь pet project на своем любимом языке для души. Совсем другое -- когда у тебя есть жесткие цели, сроки, бюджеты, конкретные люди со своими проблемами и куча других факторов, которые и отличают настоящую разработку от экспериментов с перспективной технологией. Вот автор Actix-Web-а столкнулся с задачей выжать из своего Web-сервера максимум производительсти и был вынужден прибегнуть к unsafe. И это еще был весьма квалифицированный и мотивированный разработчик. Что уж говорить об писателях индусокода (всех национальностей), которые неизбежно будут пихать unsafe в код, потому что дедлайн, а времени ублажать компилятор нету.

PS. А для всех свято верующих в то, что в реальной жизни unsafe в Rust будут использовать исключительно правильно, а прецидент Actix-Web-а -- это досадное исключение, ВИА "Громыка" исполняет свой незабвенный шлягер, строчка из которого была вынесена в заголовок заметки.

суббота, 18 января 2020 г.

[prog.open-source] Автор Rust-ового фреймворка Actix-Web: "I am done with open source."

На HackerNews разгорелся один из самых больших срачей, который попадался мне там на глаза: A Sad Day for Rust (steveklabnik.com). Этот срач посвящен блог-посту "A sad day for Rust" (как я понимаю, за авторством кого-то из именитых Rust-евангелистов). В свою очередь этот блог-пост посвящен эмоциональному решению автора Rust-ового фреймворка Actix-Web закрыть свой проект. На GitHub-е по адресу https://github.com/actix/actix-web сейчас размешен только относительно небольшой README-файл, озаглавленный как "Actix project postmortem".

В "Actix project postmorten" автор пишет о том, как он задолбался бороться с борцунами с unsafe. Что работа над Actix-Web перестала приносить удовольствие. И что он решил послать все и всех куда подальше:

It’s been three years since I started actix project (time flies). I learnt a lot, i meet new people, I found language that I really like and want to use it fulltime, I found fun job. But damage to the project's reputation is done and I don’t think it is possible to recover. Actix always will be “shit full of UB” and “benchmark cheater”. (Btw, with tfb benchmark I just wanted to push rust to the limits, I wanted it to be on the top, I didn’t want to push other rust frameworks down.) Everything started with actix, then actix-web and then actix-net. It took a lot of time to design api and architecture. Each of this projects was rewritten from scratch at least 4-5 time. I hope I expanded some boundaries and found few new patterns, I hope other developers will check source code and find inspiration to move even further. Nowadays supporting actix project is not fun, and be part of rust community is not fun as well.

I am done with open source.

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

Любой проект может сдохнуть в любой момент.

Итак, первое впечатление, как это ни странно -- это вспомнившаяся откуда-то "мудрость": если долго сидеть на берегу, то можно увидеть, как мимо проплывает труп твоего врага. Так уж вышло, что мы так же пилим свой "типа Web-фреймворк", но для C++. Поэтому в какой-то мере RESTinio и Actix-Web конкуренты. В небольшой степени, но все-таки.

И вот один конкурент сходит с дистанции (по крайней мере в своем первоначальном виде). А мы остаемся. Мы живы, движемся вперед и это не может не радовать.

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

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

Се ля ви. Ничего не поделаешь.

Все вокруг все знают гораздо лучше тебя...

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

Собственно, то что эмоционально рассказал в "Actix project postmortem" Николай Ким -- это оно и есть. В чистом виде.

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

Rust-сообщество зачастую напоминает стадо упоротых разрушителей старого мира во имя новой религии, имя которой "safe во все поля".

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

Причем отдельным фетишем для упоротых Rust-оманов является safe. Который должен быть во все поля.

А если safe во все поля нет, то это ай-ай-ай, это все старый мир, который должен быть до основания... И далее по тексту.

Просто иначе я не могу себе представить причин происхождения тех волн агрессии на Actix-Web от сторонников safe Rust. Ну реально: вот есть проект, он сделан, он работает, он показывает крутые результаты. Ну есть там unsafe. Ну так не просто же так он там оказался. Да и если проект работает, покрыт тестами, новый функционал добавляется, баги правятся, так не все ли равно, есть там unsafe внутри или нет? Вам шашечки или ехать, в конце-концов?

Но вот оказывается, что шашечки важнее. <img src="СергейЛавров.jpg">

Так за чей счет сей банкет?

И, пожалуй, главное впечатление -- это актуальность моих недавних заметок про OpenSource и заработок на OpenSource (раз и два).

Отлично понимаю вот эти слова Николая Кима в его "Actix project postmortem": "Seems everyone believes there is large team behind actix with unlimited time and budget."

Как мне представляется, сейчас к OpenSource сложилось исключительно потребительское отношение. Т.е. все привыкли к тому, что используемые ими инструменты должны быть открыты. И не просто открыты, но и бесплаты. Более того, начинают звучать голоса, которые говорят о том, что пермиссивные лицензии, которые требуют указания факта использования OpenSource проекта (как это обязывает делать, например, BSD-3-CLAUSE лицензия), не есть хорошо. Что следует использовать лицензии типа Boost Software License, которые позволяют задействовать открытый проект и даже не упоминать об этом...

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

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

Так что за словами "I am done with open source.", как по мне, скрыт очень и очень большой смысл.