LE Blog

Инженер с поэтической душой

24.10.2010 firtree_right Снова

Внезапно прервал виртуальную жизнь на три месяца. :) Даже не знаю, с чем это связано. Не помню, писал ли я уже об этом, но когда я в 2007-ом ушёл с работы, то для меня был довольно актуален вопрос: «чем же я хочу заниматься по жизни?» Нутро на вопросы не отвечало, поэтому я просто сел и выписал на бумагу то, чем я занимался в разные периоды своей жизни, начиная с 3 класса школы. И оказалось, что единственным, что присутствовало во все эти периоды, и сохранило мой интерес, было программирование. Это был забавный опыт, когда беспристрастный анализ на бумаге выявляет совсем не то, что ты привык про себя думать. Какое-то время ушло на то, чтобы сжиться с мыслью о себе-ещё-и-программисте (так, или иначе, около года), и тогда эта ипостась попёрла из меня со страшной силой. Сейчас всё стало заметно спокойнее. По крайней мере, я могу посвящать программированию один блог, а не два :)

Возможно, перерыв связан с тем, что когда интенсивно идут съёмки, то основная работа не в создании и придумывании нового, а в поддержке старого. Это кажется монотонным и недостойным внимания читателей. Или наоборот, придумывание нового было на такой зародышной стадии, что состояло в основном из тупки, а поддержка старого было единственной не-тупкой. Но в любом случае поддержка скучна [или не так весела].

Так или иначе, я написал про то, как определить, запущен ли демон.

♯♯♯

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

Но не суть. В общем, один из героев его статей был Цезарь Миллан  — в нашем переводе его шоу называется «переводчик с собачьего». В общем, мне стало очень любопытно, что он такое делает с собаками. А потом я поехал к родителям и увидел, что по Энимал Плэнет идёт как раз это шоу (я смотрю телевизор только у родителей). Потом приехал домой, и скачал ещё. Я не любитель собак или животных вообще. Но по какой-то причине я смотрел и смотрел это шоу, серия за серией.

Так вот, я вспомнил, что раньше читал (это было буквально одно предложение у Лазарева), что «человек — это животное плюс что-то ещё». И чем больше я смотрел, тем больше мне казалось, что мне понятно, где примерно проходит эта граница. Это, отчасти, игрушка для разума, но человека можно представить (для некоторых целей), как хозяин + собака.

Практические выводы такие:

  1. Для первого, наверное, нужно быть мной, чтобы понять, о чём я. Но нервозность, тревожность и прочие нежелательные состояния собаки происходят от того, что она считает себя главной, а значит ответственной за стаю. И если что-то случается неожиданное (другая собака, звук пылесоса, кто-то пришёл), то ей нужно иметь с этим дело, защищать стаю, контролировать ситуацию, но она не умеет этого делать в случае с пылесосом и микроволновкой, а в случае с гостем или другой собакой может только атаковать или отпугивать. Это как бы про то, что можно иметь с событиями дело тем или не тем местом :)

  2. Простые вещи работают круче интеллекта. Важно, в каком состоянии просыпаюсь, о чём первом думаю, в каком состоянии ложусь спать. Что делаю перед [или за] едой. Что делаю регулярно. Если проснуться и сходить прогуляться в магазин за завтраком до того, как его есть, то это меняет весь день. Нежелательные состояния легче переключать пока они не набрали интенсивность. Если регулярно возвращать себя в определённое состояние, это имеет ошеломляющий эффект. Вообще, заиметь или бросить привычку — это очень масштабное изменение жизни.

Такие дела. А что у вас?

20.10.2010 firtree_right Определение, запущен ли процесс

Пролог

Ого! Уже три месяца я ничего не писал в этот блог! Лето выдалось жаркое не только на погоду. Поскольку летом погода лучше, а световой день длиннее, было много работы. Причём работы связанной с поддержкой того, что уже и так нормально функционировало в прошлом сезоне. Ничего серьёзно нового не писалось активно, а значит и захватывающих сюжетов для статей не находилось.

Но теперь у меня появилась возможность писать кое-что новое. Поэтому есть, что рассказать.

to feed or not to feed

Введение

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

Баш в помощь

Предположим, что у нас есть простейший демон. Хорошо бы имя у него было уникальное, чтобы можно его потом было отыскать. Файл uniq_name_simple_daemon:

#!/usr/bin/env ruby

pid = fork do
  begin
    running = true
    Signal.trap("TERM") do
      running = false
    end
    while running
      sleep 0.01
    end
  rescue Exception => e
    puts e.to_s
    puts e.backtrace.join "\n"
  ensure
    exit!
  end
end

Мы всегда можем запускать с помощью другого скрипта, например на баше (simple_daemon_runner.sh):

#!/bin/bash

if ps ax | grep uniq_name_simple_daemon | grep -vq grep
then
  echo "uniq_name_simple_daemon is already running"
else
  echo "starting uniq_name_simple_daemon"
  ./uniq_name_simple_daemon
fi

На подобной команде будут базироваться все наши последующие методы. Тут, если кто не понял, мы фильтруем вывод ps ax сначала ища там имя нашего скрипта, а затем исключая из списка сам процесс поиска (команду grep). Ключ _q_ позволяет нам получить код выхода, не выводя ничего на экран. То есть если строчка найдена, то запускаем первый блок, если нет, то второй.

Можно сделать такой же скрипт для остановки процесса (simple_daemon_stopper.sh):

#!/bin/bash

pid=$(ps ax | grep uniq_name_simple_daemon | grep -v grep | awk '{ print $1; }')

if [[ -n $pid ]]
then
  echo "stopping uniq_name_simple_daemon"
  kill -TERM $pid
else
  echo "nothing to stop"
fi

Конечно же, при таком раскладе всегда есть возможность запустить нашего демона без помощи скриптов. И тогда проверка делаться не будет. В таком случае полезно проверять, запущен ли процесс уже внутри самого руби, перед тем, как отпочковать дочерний процесс.

Сам себе хозяин

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

#!/usr/bin/env ruby

ps_ax = `ps ax | grep #{File.basename(__FILE__)} | grep -v grep`.split("\n").map{ |l| l.strip.split(/\s+/) }.reject{ |l| l[0].to_i == Process.pid }

if ps_ax.any?
  case ARGV[0]
    when /stop/i
      ps_ax.each do |l|
        system "kill -TERM #{l[0]}"
      end
    when /kill/i
      ps_ax.each do |l|
        system "kill -KILL #{l[0]}"
      end
    else
      puts "#{File.basename(__FILE__)} is already running. If you want to stop it, run './#{File.basename(__FILE__)} stop|kill'"
  end
else
  pid = fork do
    begin
      running = true
      Signal.trap("TERM") do
        running = false
      end
      while running
        sleep 0.01
      end
    rescue Exception => e
      puts e.to_s
      puts e.backtrace.join "\n"
    ensure
      exit!
    end
  end
end

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

Оффтопик

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

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

Что же делать? :)

Материалы для самостоятельного изучения

Полный код статьи на гитхабе.

02.08.2010 firtree_right Rien de rien

Если вы, как и я, смотрели «La vie en rose», и вам, как и мне, понравилось, то от просмотра Inception вы получите дополнительные грани удовольствия.

Хотя Афиша-киноблог говорит, что это вышло случайно.

27.07.2010 firtree_right Водичка

Как-то я постепенно перестроился и привык к этой погоде. Главное, что я обнаружил, важно пить побольше воды. Раньше я мог вообще выпить в день три чашки чая (по одной на завтрак, обед и ужин) и больше не пить жидкости вообще. В жару особенно быстро голова наполняется всякими липкими мыслями. У меня есть даже теория, почему. А водичка довольно хорошо её [голову] освобождает.

На освободившееся место приходят мысли более пространные и обобщающие.

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

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

А ещё, что реализовавшееся желание начать писать третье поколение съёмочной программы вылилось в то, что я думаю[туплю] большую часть дня, а непосредственно пишу — меньшую. Думать, всё таки, тяжелее, чем программировать. Спасают мелкие дела.

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

А какие у вас мысли, когда вы попьёте водички?

21.07.2010 firtree_right Управление LEGO NXT Mindstorms с помощью телефона HTC Desire на Android

summer in the city

Введение

Лето в этом году выдалось жаркое, но пока ни о каких отпусках речи не идёт. Пока солнечно, тепло и сухо — самое время снимать панорамы улиц (или ГрадоГлядъ, как я это называю). Однако, не смотря на хорошую плотность работы, ничего принципиально нового, о чём интересно было бы рассказать, не произошло. Поэтому я покажу концепт, над которым работаю уже какое-то время, и который лежит в стороне от моих основных языков программирования.

Дистанционное управление

Итак, у меня уже давно есть конструктор LEGO Mindstorms, который довольно бодро взаимодействует через bluetooth с компьютером или с таким же конструктором.

А в апреле я обновил телефон на HTC Desire под управлением операционной системы Андроид, которая уже давно привлекла моё внимание, но всё руки не доходили.

В итоге появились повод, возможность и желание «пощупать» Андроид. И вот, что из этого получилось:

Секреты?

Для тех, кто соберётся заниматься чем-то подобным, могу поделиться небольшим секретом. Стандартный метод получения BluetoothSocket, рекомендованный командой Гугла, не работает, а нужен небольшой хак:

/* Не работает:
 * socket = device.createRfcommSocketToServiceRecord(MY_UUID)
 */

Method m = device.getClass().getMethod("createRfcommSocket",
            new Class[] { int.class });
socket = (BluetoothSocket)m.invoke(device, Integer.valueOf(1));

Вот и всё, что я могу рассказать :) Если я ещё буду писать про Андроид, то придётся сделать подсветку кода для него.

Материалы для самостоятельного изучения

Руководство для разработчиков под Андроид на тему bluetooth

08.07.2010 firtree_right Ассорти

В такую жару клёво делать что-нибудь новое и интересное. Пробовать что-нибудь в первый раз и проектировать с нуля. А писать документацию или дорабатывать наследие прошлого в такую жару лениво. Я нашёл программиста на си и очень им доволен. Он аккуратен, оперативен и такой же аут, как и я. Это будет уже третье поколение съёмочной программы. То есть я писал эту штуку два раза с чистого листа и мне всё мало.

Посмотрели сегодня «Девушка с татуировкой дракона». Я люблю скандинавское кино. У него всегда прекрасный, ни на что не похожий ритм. Вроде бы ничего не происходит, но невозможно глаз оторвать. Однако, я бы не смог посмотреть два скандинавских фильма с перерывом меньше чем в неделю. Вот такая любовь.

Нет более приятного собеседника за обедом, чем Маша.

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

А как у вас дела?

23.06.2010 firtree_right Пеар

Вот и вышел в свет ещё один портфолио-блог как у меня с Ирой. :) Сделал я его для наших с Ирой друзей, а именно Маши Красновой-Шабаевой. После того, как Маша и Тимур нарисовали дизайн, я долго тянул кота за хвост, чтобы не верстать, а потом впервые в своей практике применил метод: «Купи вёрстку у Мистера Вудмана и спи спокойно».

Заодно проверим на вшивость отечественных поставщиков хостинга, о которых недавно упоминал.

19.06.2010 firtree_right Деплой

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

В связи с чем попробовал отечественный продукт: хостинг locum.ru. Не знаю, правда, как он под нагрузкой, но первые впечатления от настройки приятные. С тех пор, как я пользуюсь capistrano, залить что-то на хостинг — легко и быстро. Самое трудное, обычно — это первый деплой. Тут как раз всё прошло быстро и не меняя привычек. Недостаток инструкций, конечно, имеется, но не страшный.

Я бы даже написал им инструкцию, как залить свой проект на Ruby on Rails на их хостинг, но я всё время стесняюсь, что не умею пользоваться ssh-agent. Может кто-то научит меня пользоваться ssh-agent, чтобы мне не добавлять дополнительный deploy-ключ в список пользователей репозитория?

18.06.2010 firtree_right Машинка!

Вот, чем я занимаюсь после работы:

17.06.2010 firtree_right Ещё два сценария работы с git: git stash и git bisect

library

Введение

Моя любимая система контроля версий имеет огромное количество инструментов. Как-то раз я участвовал в опросе, после которого выяснилось, что даже из самых популярных инструментов я использую от силы 10%.

Но иногда возникают ситуации, единственно продуктивным выходом из которых бывает изучение и использование нового для себя инструмента. О двух таких случаях я сегодня и расскажу.

Внезапные просьбы: git stash

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

Итак, я нахожусь в середине правок на ветке _extremely_experimental_, а мне необходимо внести правки в ветку master. Вот, как это делается:

git stash save
git checkout master

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

Но скорее всего все или некоторые из сделанных изменений понадобятся нам в нашей экспериментальной ветке. После перехода на неё:

git checkout extremely_experimental

Если нам нужны все изменения, то:

git merge master

Если только некоторые, то:

git cherry-pick ...

После этого вернём наши правки:

git stash pop

Если возникли конфликты, то правим их и делаем:

git stash drop
git reset --mixed

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

Конечно же таких незавершённых правок может быть несколько, но это я оставлю на самостоятельное изучение пытливому читателю.

Неизвестно, когда сломалось: git bisect

Бывает так, что вдруг обнаруживается ошибка, про которую точно известно, что давным давно её не было. Так бывает в больших проектах, в непокрытых тестами областях. Бывает так, что обнаружить, в чём же дело, быстро не удаётся.

Хорошая новость в том, что это и не обязательно. Нужно просто начать процесс:

git bisect start
git bisect bad

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

git bisect good v2.3.1

или

git checkout ...
git bisect good

После этого за нас всё будет делать git. Он будет перемещать нас по истории, а мы будем проверять, есть эта ошибка или нет, и сообщать об этом:

git bisect good

или

git bisect bad

В конце концов нам сообщат, какой именно коммит всё поломал. Название инструмента подсказывает нам, что на тестирование нам всегда предоставляется коммит, который находится посередине между плохим и хорошим. Таким образом, мы просматриваем не все _N_ коммитов в истории ошибки, а всего лишь log2N.

После того, как мы выяснили, в чём причина, убрать следы, которые оставил после себя git bisect можно так:

git bisect reset

А какими инструментами git пользуетесь вы?

Материалы для самостоятельного изучения

  1. Документация по git
  2. git stash
  3. git bisect