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

О блоге

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

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

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

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

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

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

среда, 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.", как по мне, скрыт очень и очень большой смысл.

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

[prog.c++] Как много одна простая строчка может рассказать об эволюции С++

Вот в этой строке с декларацией простейшего метода:

[[nodiscard]] bool empty() const noexcept;

можно отследить насколько много C++ вобрал в себя за время своей эволюции:

  • изначально, насколько я помню, в C++ не было контантности для методов, она была добавлена уже после публичного релиза C++ в 1985-ом году. И очень выгодно отличала C++ времен 1990-х годов от первых версий Java (да и от последующих тоже);
  • специальный булевский тип bool, которого так же изначально не было, но который был добавлен на основании опыта хождения по доставшимся в наследство граблям языка Си;
  • noexcept как результат эволюции отношения к исключениям. Не то, чтобы это был уже тот результат, который хотелось бы. Но уже сильно лучше, чем выпиленный, к счастью спецификатор throw();
  • аттрибут nodiscard. Во-первых, просто само понятие аттрибута, чего на протяжении многих лет в C++ не было. Но которое появилось под влиянием опыта других языков программирования. И, во-вторых, собственно nodiscard, т.е. явное указание того, что возвращаемое значение нельзя просто так проигнорировать. Опять же, на основании опыта хождения по граблям.

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

Если дать себе время остановиться и порефлексировать на эту тему, то это внушаить :)

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

[prog.c++] В SObjectizer-овском select() появляется send_case()

В черновой ветке SObjectizer-а появилась возможность делать select() не только для чтения входящих сообщений из нескольких каналов, но и для отсылки сообщений в канал. Так что совсем скоро SObjectizer-овский select() станет еще более близок к Go-шному. Естественно, с поправкой на то, что в SObjectizer-е все это сделано средствами библиотеки, а не вшито в язык намертво с оптимально причесанным под это дело синтаксисом.

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

Примечательна история появления send_case для SObjectizer-овского select-а.

Сам select() в SObjectizer-е появился чуть менее четырех лет назад, в марте 2016-го. После чего я пытался сделать несколько подходов к реализации в select-е не только receive_case, но и send_case. Но каждый раз эти подходы завершались неудачей из-за отсутствия хороших идей по интеграции send_case в уже имеющуюся реализацию select-а.

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

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