Англоязычные подкасты про ruby и rails
Так сложилось, что я управляю транспортным средством больше, чем час в день (на работу, на тренировку, домой). И я давно уже хотел слушать английские тексты в это время, потому что музыка часто надоедает.
Я пробовал слушать «обычные» тексты, но потом подумал, что гораздо интереснее слушать то, что тебя волнует. Поэтому я порылся в дебрях интернета и нашел следующие подкасты, которые я регулярно слушаю.
The Ruby Show — выходит по вторникам, длится минут 15-20. Две веселых чувака рассказывают про новости в мире ruby и rails, при этом периодически достаточно весело шутят.
Переопределение Rails.logger и проблемы с ним
Часто один и тот же rails-проект используется и для web-части, и для каких-то других задач, выполняемых по расписанию или для создания демонов. В таких случаях иногда хочется, чтобы логи разных частей писались в разные файлы.
Готового способа для этого я не нашел. Например, посмотрим на такой пример:
$ ./script/console
Loading development environment (Rails 2.3.5)
>> ActiveRecord::Base.logger = Logger.new(STDOUT)
=> #<Logger:0xb192594 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0xb19255c @datetime_format=nil>, formatternil, logdev#<Logger::LogDevice:0xb19247c @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDOUT>, mutex#<Logger::LogDevice::LogDeviceMutex:0xb192444 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0xb19240c>
>> User.first
=> #<User id: 1, email: "seeduser@scalaxy.ru" ...>
>>
И где же логи, спросите вы?
Автоматизация vim с помощью pathogen
Извечная проблема о том, как добавлять и обновлять плагины в vim решилась благодаря легендарному Tim Pope.
Сегодня утром узнал от Ярослава Маркина о существовании pathogen.
Статья на английском о том, как им пользоваться, лежит здесь. Правда, я потратил полчаса, чтобы
догадаться, что надо добавить call pathogen#runtime_append_all_bundles()
в файл ~/.vimrc
.
После установки pathogen.vim в
можно хранить все плагины в папке /.vim/autoload/.vim/bundle
, причем каждый в своей папке.
А еще огромный плюс - в конце этой статьи код, который позволяет обновлять все плагины одной командой.
Использование ruby-debug
Использование дебаггера при разработке — это плохой тон. Это значит, что вы не понимаете, как работает ваша программа. Но иногда жизнь без дебаггера становится невыносимой.
Есть отличный плагин vim-ruby-debugger для редактора vim. Но он пока сыроват и не все возможности в нем есть. По крайней мере в моем случае, чтобы понять, что происходить внутри спека, он не помог.
Тогда я воспользовался старым дедовским способом:
require 'ruby-debug'
Debugger.start
И вставил вызов debugger в том месте, где мне это необходимо.
PgQ и Londiste
Хотя я так и не написал толком, как пользоваться PgQ и Londiste, но уже написал плагин, который облегчает его использование вместе с рельсами.
http://github.com/evtuhovich/pgq/tree/master
В README всё написано на плохом английском (с хорошим английским у меня плохо).
Совсем скоро я добавлю туда возможность прогонять миграции на master и slave базах данных одновременно. Тогда при очередной выкатке необходимо будет сделать только rake londiste:update в самом конце, после того, как все миграции прогонятся.
Проблема с проверкой уникальности какого-то поля в rails
Пусть в модели User у нас описана валидация для поля email
validates_uniqueness_of :email, :case_sensitive => false,
:message => i18n_proxy(:email_already_registered)
Следующий код генерирует вот такой запрос к базе данных:
SELECT * FROM users WHERE lower(email) = 'thmth' LIMIT 1
А на таблице users у нас индекс по полю email. В postgresql запрос, что вверху, не будет использовать индекс. Представьте, что будет, когда в таблице users десятки тысяч записей, а на каждое изменение любого поля в users вызывается такой запрос.
Именно это я наблюдал совсем недавно на нашей живой базе. Проблема решается
просто, например, убрать :case_sensetive
, а email всегда
предварительно переводить в нижние буквы.
Перенос таблицы в другую базу данных postgres без простоя приложения
В продолжении темы о нескольких базах данных в одном rails-приложении расскажу о том, как изящно перенести одну большую таблицу в другую БД postgresql.
Пусть у нас есть таблица messages с большим количеством данных (10 миллионов записей), которые мы решили перенести на другой сервер. Мы сделали, как написано в статье, указанной выше, а также создали в новой БД таблицу messages с такой же структурой.
Теперь с помощью londiste настраиваем репликацию из первой БД во вторую для таблицы messages (об этом я напишу подробнее попозже, пока же можно прочитать об этом у Андрея Стихеева в рассылке ror2ru).
Несколько баз данных
В некоторых ситуациях необходимо использовать более чем одну базу данных в проекте. Например, статистику и большие таблицы хранить на другом сервере, у которого большой и медленный диск, а данные, которые нужны постоянно, хранить на основном сервере с маленьким и быстрым диском.
В нашем случае хотелось унести большие таблицы на другой сервер, чтобы в дисковом кэше (а у главного сервера БД 32 Гб оперативной памяти) хранились все рабочие таблицы и никогда оттуда не убегали.
Рекурсивные особенности to_yaml
Если необходимо сериализовать/десериализовать какой-то объект, то yaml формат хорошо для этого подходит.
В моем проекте мы записывали объекты в очередь, использую yaml-сериализацию. На тестах все было хорошо. Но на живом эта самая сериализация стала выполняться очень долго.
Оказалось, что если у объекта есть связные объекты, то он их тоже засовывает в yaml, а если таких объектов очень много, то это будет сложная операция. Понятно, что в примитивных тестах этого было не видно, а подумать хорошо головой в тот раз не получилось.
Конкурентное пересоздание индексов в postgresql
На таблице postgresql с большим количеством данных невозможно быстро создать либо пересоздать индекс. При создании индекса таблица блокируется для операций INSERT, UPDATE и DELETE. В таких случаях может помочь конкурентное создание индекса. Иногда на postgresql стоит пересоздавать индексы, чтобы уменьшить их фрагментацию (и увеличить скорость). Создание конкурентного индекса будет частным случаем его пересоздания.
Пусть имеется таблица orders с 1 миллионом записей (приблизительно) в которой хранятся заказы. И в этой таблице есть поля country_id, region_id, city_id, на которых создан индекс.