Блог Загирова Рустама

Около-интернетные заметки

Unicorn в Capistrano 3

| Комментарии

Вышла новая версия capistrano под номером 3. Можете прочитать полный анонс от комманды.

Главные изменения:

  • Под капотом теперь SSHKit, и можно использовать разные фишки dsl. В частности появился метод test, которым можно проверить возврат и выполнить в зависимости от этого разные комманды. Что позволило избавится от выполнения такого: “[ -f ] && unicorn; true”
  • Модульность: bundler, rbenv, rvm, maintenance. Даже рельсовые assets и migration развели, можно подключать по отдельности. Идут по пути рельс: подключаешь только то, что тебе нужно.
  • Теперь поддержка multistage из коробки
  • Новые опции linked_files и linked_dirs
  • Сломали —dry-run. К справедливости, это баг SSHKit, но неприятненько

Собственно переписанные правила для unicorn’а:

Capfile:

1
2
3
4
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }

deploy.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
namespace :deploy do

  desc 'Restart application'
  task :restart do
    invoke 'deploy:unicorn:restart'
  end
end

namespace :unicorn do
  pid_path = "#{release_path}/tmp/pids"
  unicorn_pid = "#{pid_path}/unicorn.pid"

  def run_unicorn
    execute "#{fetch(:bundle_binstubs)}/unicorn", "-c #{release_path}/config/unicorn.rb -D -E #{fetch(:stage)}"
  end

  desc 'Start unicorn'
  task :start do
    on roles(:app) do
      run_unicorn
    end
  end

  desc 'Stop unicorn'
  task :stop do
    on roles(:app) do
      if test "[ -f #{unicorn_pid} ]"
        execute :kill, "-QUIT `cat #{unicorn_pid}`"
        #execute :rm, unicorn_pid
      end
    end
  end

  task :force_stop do


  desc 'Restart unicorn'
  task :restart do
    on roles(:app) do
      if test "[ -f #{unicorn_pid} ]"
        execute :kill, "-USR2 `cat #{unicorn_pid}`"
      else
        run_unicorn
      end
    end
  end
end

Софт на Mac OS X

| Комментарии

В информации о блоге есть описание моего окружения 2 годичной давности. Сейчас я уже использую Mac OS X, а не Ubuntu Linux.

Не буду утруждать тут дифирамбами о необходимости прямо сейчас бежать за макбуком в магазин, но поверьте система отлично подходит как для php-разработчика, как и для ruby-разработчика (коим я сейчас и являюсь). Это полноценная мощь юникс-консоли вкупе с красивым интерфейсом.

Итак, поехали.

Бага Thinking-sphinx в Mac OS X

| Комментарии

Возникла ошибка при использовании thinking-sphinx под Mac OS X. Убил полдня на её решение. Надеюсь этот пост поможет быстрей справиться с этим багом таким же как и я программистам, которые используют методику google driven development.

Эта ошибка воспроизводилась на Mac OS X 10.8.4, thinking-sphinx 3.0.5, и sphinx 2.0.9.

Началось всё с этой ошибки:

1
undefined method `inject' for nil:NilClass

И стектрейсом

1
2
3
4
5
6
7
8
9
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/middlewares/inquirer.rb:49:in `call'
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/middlewares/inquirer.rb:14:in `block in call'
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/middlewares/inquirer.rb:13:in `call'
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/middlewares/geographer.rb:11:in `call'
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/middlewares/sphinxql.rb:13:in `call'
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/middlewares/stale_id_filter.rb:10:in `call'
(gem) middleware-0.1.0/lib/middleware/runner.rb:31:in `call'
(gem) middleware-0.1.0/lib/middleware/builder.rb:102:in `call'
(gem) thinking-sphinx-3.0.5/lib/thinking_sphinx/search.rb:65:in `populate'

В логах было только видно, что запрос исполняется.

1
Sphinx Query (36.6ms)  SELECT * FROM `index` WHERE MATCH('телеФон*')

После копаний оказалось, что thinking-sphinx выполняет сразу два запроса: собственно запрос на получение данных из сфинкса и запрос «SHOW META».

Оказалось, что во время второго запроса, сфинкс по неизведанной причине разрывает соединение.

1
Sphinx Retrying query "SELECT * FROM `index` WHERE MATCH('телеФон*'); SHOW META" after error: Lost connection to MySQL server during query

Скачал beta-версию (2.1.1) sphinx’а, причём сайт при загрузке выдал мне сообщение: «Congratulations! It’s official, you’re a Sphinxter!!» =)

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

Обновление Gem Mysql2 на MacOS X при обновлении MySQL до 5.6

| Комментарии

На MacOS X в homebrew появился MySQL 5.6.10.

Поэтому при обновлении MySQL будет выскакивать ошибка о несоответствии библиотек:

1
Incorrect MySQL client library version! This gem was compiled for 5.5.28 but the client library is 5.6.10.

Если ставить так, как написано в readme:

1
gem install mysql2 --with-mysql-config=/usr/local/bin/mysql_config

То возникает ошибка:

1
ERROR: While executing gem ... (OptionParser::InvalidOption) invalid option: --with-mysql-config

Нужно добавить больше тирешек и кавычек

1
gem install mysql2 -- '--with-mysql-config=/usr/local/bin/mysql_config'

UPDATE:

Чтобы bundler всегда использовал данный параметр, выполните команду:

1
bundle config build.mysql2 --with-mysql-config=/usr/local/bin/mysql_config

Как установить Ruby 2.0.0-p0

| Комментарии

Сегодня вышел ruby 2.0.0 и я думаю скоро выйдет rails 4.

Если у вас возникли следующие ошибки, то установка простой коммандой rvm install ruby-2.0.0-p0 не получится:

1
2
Error running 'env CFLAGS=-O3 -march=corei7 -O2 -pipe ./configure --disable-install-doc --prefix=/Users/stamm/.rvm/rubies/ruby-2.0.0-p0 --with-opt-dir=/usr/local/opt/libyaml:/usr/local/opt/readline:/usr/local/opt/libxml2:/usr/local/opt/libxslt:/usr/local/opt/libksba:/usr/local/opt/openssl:/usr/local/opt/curl-ca-bundle:/usr/local/opt/sqlite --disable-shared', please read /Users/stamm/.rvm/log/ruby-2.0.0-p0/configure.log 
There has been an error while running configure. Halting the installation.

Парад ссылок №2

| Комментарии

Yii

  • Вышел плагин для phpstorm, поддерживающий yii. Надеюсь автор не забросит его, и из этого получиться что-то более функциональное.

Тестирование

  • Функиональное тестирования как сервис – поддерживаются почти все популярные языки, все актуальные браузеры. Сам не пробовал, но судя по фичам у сервиса будут свои пользователи.
  • Процент покрытие тестами в ruby on rails. Работает в связке с travis ci. Сейчас процедура такая: пушим на github, travis-ci выполняет тесты, coveralls показывает как изменилось покрытие кода и показывает красивые отчёты об изменениях. При этом не держа у себя сервер и не платя ни копейки.
  • Крутое видео с демо по cucumber. Можно довольно быстро понять как правильно писать свои тесты на cucumber’е (код на github).

Нагрузочное тестирование

Разное

  • Создание бэкапов с помощью ruby – это вам не монструозные конфиги бакулы, тут всё быстро и понятно.
  • Прикольный интерфес для мониторинга показателей, написанные на ruby. Есть несколько предопределённый виджетов для отображения kpi. Добавляется блок очень быстро и приятно. В крайнем случае можно написать свой: ruby + coffee + sass. Работает без ajax-запросов, на основе постоянного соединения.
  • http://runnable.com/ – позволяет выполнить код на скриптовом языке прямо в браузере. Что-то типо сервиса jsfiddle, только для серверных языков. Пока поддерживается nodejs, но обещают поддержку php, ruby.
  • Бесплатный менеджер буфера обмена для MacOS. Теперь работать без неё не могу.
  • Очень интересная новость: гугл запустил маркеры – (видео). В кратце позволяет мне, как администратору сайта кликая и выделяю мышью указывать структуру информации на сайте. Сейчас поддерживаются только мероприятия, но с развитием можно будет указать много другой мета-информации. Но я за то, чтобы использовать микро-форматы. По сути гугл хочет переложить работу с себя на хозяев сайта. Посмотрим что из этого получится.
  • Крутое видео о том, зачем нужен DevOps. Вообще как-то начинает развиваться эта движуха, если кто не знает, советую почитать
  • Cмешная картинка ковёр-самолёт. Это к тому, что все понимают в свою меру понимания. Всегда помнить, когда пишите задачу или ТЗ ;)
  • Забавные гифки, что называется, до слёз: раз, два.

Парад ссылок №1

| Комментарии

Новая рубрика в блоге: парад ссылок. Это что-то наподобие линк-блога, но ориентированного на веб-разработчиков: php, js, администрирование и всё больше о ruby и рельсах. Короче всего, что мне интересно.

Надеюсь, каждый найдёт что-то интересное.

Ускорение скорости работы Grep в Mac OS X

| Комментарии

На монитор попала статья о том, что grep от gnu быстрее стандартного маковского grep’а в 10 раз

Решил проверить у себя. На файле, размером в 720 Мб grep стал быстрей в 36 раз! Неплохо.

1
2
3
4
5
6
7
8
$ brew install grep
$ time /usr/bin/grep "GET /out" nginx-access_log.2 | wc -l
140858
/usr/bin/grep "GET /out" nginx-access_log.2 26.49s user 0.28s system 97% cpu 27.443 total wc -l 0.03s user 0.02s system 0% cpu 27.443 total

$ tmp time grep "GET /out" nginx-access_log.2 | wc -l
140858
grep "GET /out" nginx-access_log.2 0.58s user 0.15s system 98% cpu 0.748 total wc -l 0.03s user 0.01s system 6% cpu 0.747 total

Ограничение прав пользователей в Git

| Комментарии

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

Почему он это сделал — это другой вопрос: просто не переключил ветку или намеряно. Или к джуниору подбежал директор или менеджер и сказал, что нужно быстро исправить. Тут нужно бить такого программиста по рукам, но лучше предупредить болезнь, чем лечить её =)

Удаление данных из коллекции в Mongodb без блокировки

| Комментарии

Задача: удалять устаревшие данные из большой коллекции монги. Можно пойти в лоб и удалять так:

1
2
var time = new Date().getTime() - 2*24*60*60;
db.data.remove({updating_time: {$lte: time}})

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