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

О блоге

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

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

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

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

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

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

пятница, 30 сентября 2016 г.

[prog.flame] portfile.cmake из Vcpkg супротив рецепта для MxxRu::externals

Попробовал представить, как сделать адаптацию SO-5 под новую волшебную пилюлю от Microsoft под названием Vcpkg. Проблевался. Какую только херню, пардон май френч, народ готов жрать только потому, что эта херня от MS или от Google. Поразительно.

Суть Vcpkg в том, что под каждый проект, который хочется затянуть в этот самый Vcpkg, нужно создать файлик portfile.cmake, в котором будут находится инструкции по доставанию исходников этого проекта и по его сборке (если проект нуждается в сборке). Для примера покажу, как выглядит portfile.cmake для библиотеки Range-V3. И как это же самое выглядит в виде рецепта для MxxRu::externals.

Итак, portfile.cmake для Vcpkg:

include(vcpkg_common_functions)
set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/Range-V3-VS2015-ede9ad367fd5ec764fecb039c874614bd908e6b6)
vcpkg_download_distfile(ARCHIVE
    URLS "https://github.com/Microsoft/Range-V3-VS2015/archive/ede9ad367fd5ec764fecb039c874614bd908e6b6.zip"
    FILENAME "range-v3-ede9ad367fd5ec764fecb039c874614bd908e6b6.zip"
    SHA512 e978c7694471d8616c248647b77689f377b3e2517347abde8629b140e5994de8bf686565a24cdd7dd222f325d43b775f5e478c91220dce75313985499b134637
)
vcpkg_extract_source_archive(${ARCHIVE})

file(COPY ${SOURCE_PATH}/LICENSE.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/range-v3)
file(RENAME ${CURRENT_PACKAGES_DIR}/share/range-v3/LICENSE.txt ${CURRENT_PACKAGES_DIR}/share/range-v3/copyright)
file(INSTALL ${SOURCE_PATH}/include DESTINATION ${CURRENT_PACKAGES_DIR} FILES_MATCHING PATTERN "*.hpp")
vcpkg_copy_pdbs()

Тоже самое для MxxRu::externals:

MxxRu::arch_externals :range_v3_vs2015 do |e|
  e.url 'https://github.com/Microsoft/Range-V3-VS2015/archive/ede9ad367fd5ec764fecb039c874614bd908e6b6.zip'
  e.sha512 'e978c7694471d8616c248647b77689f377b3e2517347abde8629b140e5994de8bf686565a24cdd7dd222f325d43b775f5e478c91220dce75313985499b134637'

  e.map_dir 'include/*' => 'dev/range-v3'
  e.map_file 'LICENSE.txt' => 'dev/range-v3/*'
end

Резюмируя. Если кому-то действительно нужно, чтобы SO-5 был доступен из портов Vcpkg, то дайте знать. Мы сделаем. Но только если это кому-то действительно нужно. Ибо Vcpkg выглядит как говно и пахнет как говно. А посему вмазываться в говно и сопровождать потом это говно просто так не хочется, только если на то будут причины.

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

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

Любой ценой (Hell or High Water, 2016). Понравилось, посмотрел с большим удовольствием.

Мистериум. Тьма в бутылке (Flaskepost fra P, 2016). Понравилось. Очень достойная серия криминальных фильмов получилась (если кто не видел, то советую начать с двух первых частей: Мистериум. Начало (Kvinden i buret, 2013) и Убийцы фазана (Fasandræberne, 2014), тогда будет лучше понятно, откуда взялись главные герои-следователи.

Торо (Toro, 2016). Неплохо. Европейцы все-таки снимают криминальные драмы как-то не так, как американцы.

Заклятие 2 (The Conjuring 2, 2016). Если первое "Заклятие" понравилось, то нужно смотреть и второе. Как по мне, так достойное продолжение.

Джейсон Борн (Jason Bourne, 2016). Ждал от фильма сильно большего. Если бы не погоня на автомобилях в конце, так вообще бы разочаровался бы.

Великолепная семерка (The Magnificent Seven, 2016). Постреляли в фильме от души, но, что странно, ни за кого из героев переживать не хотелось. Так что фильм смотрится просто как тщательно сделанный аттракцион с весьма предсказуемым финалом.

Транс-Пекос (Transpecos, 2016). Если бы не излишняя затянутость, то могла бы получиться вполне добротная криминальная драма.

Поезд в Пусан (Busanhaeng, 2016). Корейское кино про зомби. Причем, про весьма шустрых и злобных зомби. Если корейское кино нравится, то можно смотреть. Хотя бы для того, чтобы увидеть, как корейцы к этой теме подходят.

Такой же предатель, как и мы (Our Kind of Traitor, 2016). Несмотря на наличие хороших актеров какого-то хорошего впечатления фильм на меня не произвел.

Отмель (The Shallows, 2016). Так себе. Финал вообще сказочный.

Безбашенный Ник (Tschiller: Off Duty, 2016). Редкая муть. Доставил разве что фрагмент с проездом на комбайне по центральным улицам Москвы под "Нас не догонят".

Спарта (2016). Не понял ни что это было, ни зачем я это смотрел. Но хотя бы сцены поединков были сняты более-менее нормально.

понедельник, 26 сентября 2016 г.

[prog.thoughts] Эпоха бородатых проектов уже наступила?

Программирование сейчас -- это слишком уж сегментированная область, чтобы говорить о программировании вообще. В каком-нибудь фронтэнде, где все меняется с калейдоскопической быстротой, наверняка дела обстоят совсем не так, как в мире хардкорного эбедеда для специализированных компьютеров с 16K RAM на борту. Однако, если брать ниши таких языков программирования, как C, С++, Java, C# и, может быть, даже Haskell/OCaml/Scala, то в этих нишах библиотеки с историей развития в 10+ лет уже не редкость. Ну, например, Boost в C++ или Hibernate в Java -- это же самое начало 2000-х.

Причем Boost -- это чрезвычайно любопытный пример. Т.к. Boost, появившись более 15 лет назад, позиционировал себя как площадка для новых C++ных библиотек, специально созданных для современного C++ и которые двигают C++ вперед. Т.е. даже понятию "современный C++" уже очень прилично лет. Посему даже библиотеки, которые сразу стартовали с "современного C++", на данный момент уже имеют "лохматую историю" (см., например, Crypto++ и Botan). Что уж говорить про те библиотеки, которые появились на свет еще до стандартизации C++ (MFC, Qt, ACE).

Посему кажется, что мы уже живем в эпоху, когда нас окружают "бородатые" проекты с очень длительной историей развития. И с каждым годом это будет все более и более актуально. Пройдет лет пять-десять и, смешно сказать, 20-летние senior-разработчики и 25-летние solution-архитекторы будут собирать проекты из компонентов, которые будут постарше этих самых разработчиков и архитекторов :) А может где-то и сейчас уже так. Скажем, если речь идет об использовании СУБД Oracle или DB2.

PS. Но еще с большим интересом я лично жду времен, когда нынешняя братия молодых разработчиков постареет лет так на десять. Говорят, что сегодня средний возраст ИТ-шников у нас в РБ меньше 30 лет. Что, в принципе, понятно. Народ массово пошел в профессию где-то после 2004-го года, когда офшор в наших Палестинах стал всасывать все имеющиеся ресурсы как пылесос. Отсюда, полагаю, и засилье малолетних дебилов на профильных форумах. Тем интереснее станет, когда лет через 5-10 этот самый средний возраст существенно превзойдет 30 лет. Но это уже совсем другая история...

суббота, 24 сентября 2016 г.

[prog.c++] Переполенные mchains и доставка отложенных/периодических сообщений

Пока готовил очередную статью для Хабра, выяснил, что в SObjectizer при добавлении message chains (это нечто вроде CSP-шных каналов) был допущен серьезный просчет. Дело вот в чем: mchain-ы могут использоваться для отсылки отложенных и периодических сообщений. Т.е. можно вызывать send_delayed или send_periodic, а в качестве адресата указать mchain. И сообщение "упадет" в этот mchain спустя указанное время.

При этом mchain-ы могут быть с ограниченниями на максимальную длину. Если ограничение задано, то должно быть задано и поведение SObjectizer-а при попытке добавить еще одно сообщение в уже полный mchain. Тут возможны следующие варианты:

  • можно подождать какое-то время на send-е. Если за это время место в mchain-е освободилось, то просто добавить сообщение в mchain и все. А вот если мы подождали, но места не нашлось, тогда идем к следующему пункту. Впрочем, можно сконфигурировать mchain так, чтобы ожидания вообще не было. Тогда мы сразу же идем к следующему пункту;
  • т.к. места в mchain-е нет, то SObjectizer смотрит на параметр overflow_reaction для mchain и:
    • в случае drop_newest просто игнорирует новое сообщение, которые мы пытаемся добавить в mchain;
    • в случае remove_oldest выбрасывает самое старое сообщение из mchain-а, а новое -- добавляет в mchain;
    • в случае throw_exception выбрасывает самое новое сообщение и генерирует исключение;
    • в случае abort_app просто вызывает std::abort.

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

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

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

Во-вторых, на нити таймера нельзя бросать исключения. В этом нет смысла, т.к. таймер понятия не имеет, что делать с исключением о переполнении какого-то mchain-а. Любое такое исключение просто приведет к вызову std::abort.

Тем не менее, все версии SO-5 с поддержкой mchain-ов, включая последнюю стабильную 5.5.17.1, не учитывают этих ограничений для контекста таймерной нити. И, если пользователь вызывает send_delayed для ограниченного по размеру mchain-а с ожиданием на переполнении и с реакций throw_exception, то когда время доставки сообщения наступит, а mchain будет полон, то сперва нить таймера заснет на этом mchain-е, затем будет брошено исключение, от которого все приложение упадет из-за вызова std::abort.

Такой вот недосмотр.

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

  • если нить таймера обнаруживает, что отложенное/периодическое сообщение идет в переполненный mchain, то ожидание на этом mchain-е не производится, даже если такое ожидание предписано в параметрах mchain-а. Нить таймера просто сразу начнет обрабатывать overflow_reaction. Без каких-либо задержек и ожиданий;
  • вместо throw_exceptio нить таймера выполняет реакцию drop_newest, т.е. простое выбрасывание сообщения, как будто его и не было.

Эти исправления уже реализованы и протестированы. Но в основную ветку я их пока не включил. Хочу послушать другие мнения. Может есть какие-то другие подходы к решению проблемы выполнения overflow_reaction на контексте нити таймера?

пятница, 23 сентября 2016 г.

[business.thoughts] Не понятные для меня вещи в бизнес-стратегии продавцов PVS-Studio

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

Стратегия продвижения PVS-Studio через ресурсы, вроде Habr-а, LOR-а и RSDN, по словам главного разработчика PVS-Studio рассчитана на то, что обычные программисты будут узнавать о такой штуке, как статический анализ и будут проникаться его мощью и полезностью. После чего, проникшись, побегут к своим менеджерам с просьбами прикупить PVS-Studio дабы...

И вот тут начинаются вопросы.

Во-первых, "дабы что?" Какую пользу PVS-Studio принесет проекту? Как измерить эту пользу? Как, в последствии, оценить, окупились ли вложения в PVS-Studio или нет? (А ведь оценка окупаемости вложений в случае с PVS-Studio не праздный, т.к. после оплаченного срока действия купленное когда-то ПО тупо превращается в тыкву и нужно платить снова и снова).

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

Прошу не думать, что я противник статического анализа кода. Речь про другое: вот программист прочитал несколько статей о том, какие баги PVS-Studio выловил в том или ином открытом проекте. Как на основании этой информации сделать вывод о том, что для проекта масштаба N килобаксов с такими-то требованиями к качеству ПО покупка PVS-Studio принесет ощутимый результат?

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

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

Второй момент, который так же имеет отношение к вопросу "дабы что?", связан с отсутствием легкодоступной информации о стоимости PVS-Studio. Полагаю, разработчики PVS-Studio смотрят на мир так:

Вот некий разработчик узнал о выгодах статического анализа вообще и PVS-Studio в частности. Радостный побежал к своему менеджеру: "Надо брать!". А менеджер спрашивает: "И во сколько нам обойдется сие счастье?" А разработчик: "Я не знаю, у них цену нужно отдельно уточнять". И менеджер такой: "Нет проблем. Спасибо, что рассказал про PVS-Studio, я с ними сам свяжусь и все выясню".

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

В общем, если бы цена была указана сразу на сайте, то продвижение PVS-Studio "снизу-вверх", как об этом мечтают продавцы сего продукта, было бы проще. Например, цены на Visual Studio, CLion, TBB, Qt, gSOAP или на техподдержку для POCO свободно доступны. Что, по-моему, сильно облегчает разговоры о необходимости их покупки.

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


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