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

О блоге

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

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

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

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

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

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

пятница, 27 мая 2016 г.

[prog.c++] Тяпничное по поводу современного C++

Последние пару месяцев плотно работаю с C++14 (на том уровне, который поддерживается в GCC-5.2 и 5.3). Конечно же C++14 -- это небольшое улучшение над C++11, но в общем и целом, если сравнивать с C++03, современный C++ является совершенно другим языком. Уж не знаю, как C++14 ощущается в задачах, где нужно выжимать такты из битов и наоборот. Но вот у меня сейчас C++ что-то вроде клеевого языка, основная задача которого экономить ресурсы, коих на целевых машинах не то, чтобы уж много. И ощущается C++14 в таком контексте практически так же, как какой-нибудь Ruby или Python. С приблизительно такими отличиями:

  • для C++ не так уж много хороших и живых библиотек, а те, что есть, нужно подключать в свой проект сильно по разному (впрочем, здесь MxxRu::externals ну очень сильно упрощает жизнь);
  • проходит гораздо больше времени между внесениями изменений в код и первым запуском измененного кода. В Ruby, например, не нужно ждать, пока проект с туевой хучей шаблонов из header-only библиотек скомпилируется и слинкуется;
  • но уж если C++ный код скомпилировался, то не приходится ожидать вылета ошибки из-за несовпадения типов переменных или еще какой-нибудь мелочевки, которая в языках со статической компиляцией вылавливается на стадии компиляции, а в динамических языка -- в run-time;
  • если уж твой C++ный код тормозит, то только из-за тебя :)

В общем, если затащить в свой проект качественные библиотеки и есть возможность пользоваться нормальным компилятором, то жить с C++11/14 легко и весело. Особенно если увлечься шаблонами и auto, то C++ный код по читабельности для меня оказывается ну очень похожим на Ruby-новый код: точно так же сначала все просто и очевидно, а через пару недель чешешь голову стараясь понять, какой же тип у этого выражения ;) В качестве демонстрации покажу ниже небольшой фрагментик (что называется, "из недавнего").

Но к чему я это все? А к тому, что оглядываясь по сторона возникает некоторое недоумение. Иногда задумываешься: куда же катится этот мир? Взять, например, русскоязычные профильные форумы. Мало того, что активность вокруг C++ там не такая уж и активная. Так еще и вопросы такие всплывают, что невольно задаешься вопросом: а вменяемые C++ники вообще остались? Глядя на вот такое (или такое, или такое) напрашивается вывод о том, что нас практически-то и не осталось. Если же задуматься еще и о том, что за такие художества кому-то еще и деньги платят, то как-то совсем грустно...

А еще давеча в почтовом ящике письмо из Boost-announce нашел, с темой "Rebooting Boost: Call for Lightning Talks @ CppCon". Вот, процитирую оттуда:

Recent and recurrent boost-dev discussions have raised the lack of cmake based tooling; lack of ABI management and the consequent ODR violation when mixing Boost versions in the same process; the anti-social behaviour of Boost towards library end users, new ideas, new blood and the wider C++ community; and the chronic lack of maintenance of up to half the Boost libraries.

One question which needs to be answered is whether a clean reboot of Boost from the first principles of proving high quality C++ libraries well suited for use with the latest C++ standard is viable. This new collection of C++ libraries would be started completely from scratch (even if some existing libraries were ported into the new organisation), so ANYTHING is possible.

Т.е. у Boost-а куча проблем, поэтому давайте-ка подумаем, как начать все заново.

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

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

Уже неоднократно говорил о том, что C++у нужно брать на вооружение идеи из других языков. RubyGems из Ruby или Cargo и Rust-а. Вот что нужно C++ сейчас, а не монстроузный Boost. Но, к сожалению, только у Boost-а достаточный авторитет, чтобы сделать какую-то систему управления зависимостями для C++ де-факто стандартом.

В общем, несколько досадно, что в кои-то веки C++ стал действительно хорошим и удобным языком. А вот инфраструктура вокруг него как была болотом, так и осталась.

Ну а теперь обещанные слайды :)

вторник, 24 мая 2016 г.

[prog.c++] Тот же самый трюк с таймерами, но уже без агентов

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

PS. К сожалению, работает только под Linux-ом, т.к. под FreeBSD и procxx обнаружились какие-то проблемы, а разбираться с ними совершенно нет времени. Утилита же ping была выбрана в качестве удобного подопытного кролика: очень просто ограничивать ее время работы, плюс легко читать ее stdout.

PPS. Заодно можно посмотреть на MxxRu::extrenals в действии. Все зависимости подтягиваются через MxxRu::externals (описание зависимостей лежит в externals.rb).

понедельник, 23 мая 2016 г.

[prog.c++11] SObjectizer-5.5.16.1 with bug fixes and backport to GCC-4.8

The version 5.5.16.1 of SObjectizer core is released!

Although version 5.5.16.1 has only minor changes this release is very important for us due to the following reason. We have changed our attitude to compiler versions required for building and using SObjectizer.

Before release 5.5.16.1 the minimal version of GCC required was 4.9. Since there are a lot of developers who are forced to use older GCC versions (for example, Ubuntu 14.04 LTS has GCC 4.8 by default), it means they simply can't use SObjectizer out of the box.

We decided that it is not appropriate. SObjectizer is not an experimental project and it has never been. SObjectizer was created to help to develop real-world software and had always been used for that purposes. So it is not good that SObjectizer cannot be used with some three or two years old compilers. Especially if there exist some political or commercial reasons which prohibit compiler upgrade.

So we have backported SObjectizer to GCC 4.8 and decided to keep GCC 4.8 compatibility for the whole lifetime of Ubuntu 14.04 LTS. It means that since v.5.5.16.1 and for all future versions of v.5.5 the minimal GCC version required for SObjectizer-5.5 will be GCC 4.8 until April 2019 (the last year of Ubuntu 14.04 LTS). Also It means that if we start v.5.6 in the near future it will also require GCC 4.8 as minimal compiler version.

As lifetime of Ubuntu 14.04 LTS ends we will switch to GCC 5.3 as minimal version. But it will happen only after 3 years from now :)

What about clang? Minimal clang version we are using for SObjectizer testing is 3.4.1. It works perfectly so we will probably stay with clang-3.4 or clang-3.5 for the same time as with GCC-4.8.

More information about SObjectizer and its capabilities can be found in this serie of presentations.

The v.5.5.16.1 can be downloaded from the corresponding [Files section] or can be checked out from [Subversion repository] and from [mirror on GitHub].

The Files section has the following archives:

  • so-5.5.16.1 ([zip], [tar.gz], [tar.xz]) -- the source code of SObjectizer core (with samples sources and tests);
  • so-5.5.16.1--bin-msvs2015-x86 ([zip]) -- the full source code with 32-bit binaries for Windows (compiled using MS Visual Studio 2015 Community Update2);
  • so-5.5.16.1--bin-msvs2015-x86_amd64 ([zip]) -- the full source code with 64-bit binaries for Windows (compiled using MS Visual Studio 2015 Community Update2).

Please note that since v.5.5.10 there are no archives with Doxygen-generated docs and binaries created using MS Visual Studio 2013. Such kind of archives can be created and uploaded by request.

четверг, 19 мая 2016 г.

[prog.c++] Еще один real-world пример из SObjectizer: трюки с таймерами

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

Есть такая маленькая, но хорошая библиотечка procxx для запуска дочерних процессов в Unix-ах (я ее слегка доработал напильником, но мой pull request пока не приняли). Запуск какой-нибудь внешней программы и чтение ее выхлопа посредством procxx -- это не просто, а очень просто:

procxx::process some_tool( "some_tool", key, value, key2, value2, ... );
some_tool.exec();

std::string line;
while( std::getline(some_tool.output(), line) )
   handle_line(line);

some_tool.wait();

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

Сделать это дедлайн в SO-5 не сложнее, чем запустить внешний процесс с помощью procxx ;)

среда, 18 мая 2016 г.

[prog.unix] Нужен совет бывалых Unix-оидов

Столкнулся с задачкой, которая не кажется слишком сложной, но почему-то вводит меня в ступор. Может потому, что я не настоящий сварщик Unix-оид :)

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

Есть один параметр, который должен быть уникален для каждой машины. Фактически, это идентификатор этой машины (небольшой длины строка с заранее заданным значением).

После развертывания программулина должна стартовать, взять откуда-то этот идентификатор и затем, во всех коммуникациях с внешним миром должна использовать этот идентификатор. Программулина стартует не под root-ом, а под отдельным пользователем, у которого, по хорошему, вместо шелла будет /usr/sbin/nologin. Ну и, если это важно, запускаться программулина будет посредством runit и егоного chpst (при этом вносить какую-то уникальную информацию в соответствующий run файл не есть хорошо, т.к. хотелось бы, чтобы run-файлы, как и другие исполнимые файлы, были идентичны для всех машин).

Для отладки всего этого дела удобно использовать переменные среды. Т.е. в разных ssh/telnet-сессиях задаю для переменной MY_NODE_ID разные значения и запускаю одну и ту же программу в нескольких копиях. Было бы здорово и при развертывании на реальные машины использовать что-то такое: чтобы идентификатор машины можно было считывать из окружения, а не из файликов в /etc или в /home.

Буду признателен, если кто-нибудь подскажет, в какую сторону копать.

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