четверг, 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-а. Поэтому интересны и способы, которые бы могли засовывать что-то уникальное при построение образов, предназначенных для разных машин.