Нестройные рубиновые мысли

Рассказ о серых трудовых буднях Ruby on Rails разработчика

Странное поведение создателей Paperclip

| Comments

Вчера я разворачивал наше приложение в системе CI Jenkins, и обнаружил, что bundler не находит gem paperclip. В Gemfile была явно прописана версия 3.0.1. Зайдя на rubygems, я увидел, что эту версию гема его создатели удалили, а версия 3.0.2 и старше не поставилась, выругавшись на то, что ей нужен ruby 1.9.2 и старше.

Изменение формата сессии при переходе с Rails 3.0 на 3.2

| Comments

Групон сейчас активно переводится с rails 3.0 на rails 3.2. Самая досадная неожиданность, которая встретилась в процессе переезда — это изменение формата хранения flash сообщений в сессии. Если бы при этом flash сообщение пропадало, то это было бы не страшно, но при декодировании сессии происходит исключение, и пользователь видит 500 ошибку до тех пор, пока не почистит куки. Конечно, пользователей, у которых в сессии будет flash сообщение в момент переключения с версии 3.0 на 3.2 будет не так и много, но это пользователи, потерянные навсегда.

Быстрое удаление старых ошибок из Airbrake через API

| Comments

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

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

Ниже привожу код на ruby, который вытаскивает список ошибок через API и закрывает их. Я отформатировал их для красоты, в реальности я запускал однострочные команды, чтобы удобнее было их повторять в irb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require 'rubygems'
require 'nokogiri'
require 'rest-client'

auth_token = "your_token" # взять на страничке "My Settings" 
                          # https://your_account.airbrake.io/users/your_id/edit

project_id = 123456       # взять из урла в airbrake, иначе выводится 
                          # список ошибок из всех проектов

ids = (4..8).to_a.map { |page|
  Nokogiri::XML(RestClient.get "https://your_account.airbrake.io/errors.xml" +
      "?auth_token=#{auth_token}&page=#{page}&project_id=#{project_id}").
    search('group/id').map(&:text)
}.flatten

ids.each { |id|
  # чтобы не ждать, пока дофига запросов выполнится последовательно
  Thread.new {
    RestClient.put("https://your_account.airbrake.io/errors/#{id}?auth_token=#{auth_token}",
      :group => {:resolved => true})
  }
}

Буду выступать на CodeFest

| Comments

31 марта буду выступать на конференции CodeFest. Мой доклад «Как мы делали Групон» будет в 17:05 во втором зале. А второго апреля я проведу мастер-класс «Устройство и оптимизация Postgresql».

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

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

Обновление на Rails3 и проблемы, связанные с этим

| Comments

На «Групоне» мы давно уже переходим с Rails 2.3 на Rails 3.0. На этой неделе перешли — полет нормальный. Но поскольку сразу переход у нас не получился, то мы переходили по частям. И тут возникла проблема, что в rails3 нужен новый devise (1.5.3), которому нужен warden (1.1.1). А в rails2 используется devise (1.0.9), которому нужен warden (0.10.7). И вот этот вот warden стал по-другому сериализовать сессию. А devise стал хранить remember_token в подписанной (signed) cookie. Более того, из самих рельс пропал класс ActionController::Flash::FlashHash, поэтому при десериализации сессии происходило неуловимое исключение в Marshal.load.

Все эти проблемы решены были кодом, которые приведен ниже. И еще похожий код был в rails2-ветке, который конвертил сессию третьих рельс во вторую. Пользуйтесь с осторожностью.

Поддержка JSON в PostgreSql 9.2

| Comments

В третьем квартале 2012 должна выйти версия PostgreSQL 9.2, в которой добавят много интересных возможностей. Среди них — базовая поддержка так полюбившегося всем web-разработчикам формата JSON. На данном этапе появится только возможность проверять JSON на валидность, но судя по списку рассылки, к версии 9.3 будет добавлена возможность строить индексы на JSON объектах подобно тому, как это можно сделать на hstore. Конечно, JSON объекты гораздо сложнее hstore, и как именно и в каком объеме будет реализована поддержка индексов в JSON — пока не ясно.

Postgres развивается, а это не может не радовать.

Фильтрация данных на клиенте

| Comments

Давече у нас на Групоне возникла следующая проблема — начала тормозить одна страница в админке. Причем до того сильно, что ее sql запрос стал регулярно появляться в списке медленных запросов в newrelic. Для большей понятности я поменяю название моделей на книги (Book) и авторы (Author), при этом, очевидно, «авторы имеют много книг», то есть связь один ко многим.

PgBouncer

| Comments

Удивительное дело, что я до сих пор не написал про PgBouncer. Как написано на сайте — это «Lightweight connection pooler for PostgreSQL». Я бы первел это следующим образом. PgBouncer — это легкий менеджер соединений для PostgreSQL.

RubyNoName подкаст

| Comments

Сегодня я выложил наш первый совместный с Иваном Самсоновым эпизод RubyNoName подкаста (плюсуйте анонс на Хабре).

Хочу сразу сказать, что дело это оказалось далеко не такое простое, как я думал раньше. Начиная с того, что непринужденно рассказывать о новостях в ruby-мире без мыканья, эканья, запинок, фраз «ну» и «как бы» получается у нас гораздо хуже, чем писать код на ruby. И заканчивая тем, что свести две дорожки в редакторе, а потом сделать из этого что-то, что хорошо слушается, вообще для меня пока что очень сложная задача, которая к тому же занимает очень много времени.

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

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

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