При работе с Rails мы постоянно пользуемся rake-задачами. Я, например, стараюсь вообще все процессы обработки данных, которые обычно выносят в миграции, выносить в виде отдельных rake-задач вида app:maintenance:*. Это очень удобно при разработке, так как позволяет запускать задачи независимо от миграций. А в миграциях задачи можно просто вызывать вот таким образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class MyMigration < ActiveRecord::Migration
def self.up
# ... DB Schema modifications ...
Rake::Task["app:maintenance:my_migration:up"].execute
# ... DB Schema modifications ...
end
def self.down
# ... DB Schema modifications ...
Rake::Task["app:maintenance:my_migration:down"].execute
# ... DB Schema modifications ...
end
end
|
Сами понимаете, некоторые задачи могут занимать довольно существенное время, вплоть до нескольких минут. В таких случаях я обычно переключаюсь на что-нибудь другое и возвращаюсь к задаче чуть позже. Однако, мне постоянно очень не хватало элементарной вещи – уведомления об окончании работы задачи. Сегодня я собрался с духом и таки сделал простейший алгоритм для уведомления об окончании работы rake-задач.
По ходу копания в иходниках gem’а rake я выяснил неприятную вещь – никаких средств для разширения в нем на данный момент не предусмотрено. В irb, например, можно добавлять расширения через файл .irbrc. С rake такой номер не пройдет. Поэтому есть два пути – расширять функционал и делать собственный форк, либо перекрывать существующий функционал. Я выбрал второй путь как наименее трудозатратный (хоть это и не труъ).
Итак, для того, чтобы добавить уведомления, нам нужно сделать собственный исполняемый файл rake. Изначально я хотел просто положить его в ~/.bash/rake, но обнаружил, что RVM прописывает свои пути перед всеми ранее заданными, то есть стандарнтый исполняемый файл rake выполняется в первую очередь. Поэтому я добавил новую запись в ~/.bash_aliases:
1 | alias rake='~/.bash/rake.rb'
|
Теперь при вызове команды rake будет вызываться мой ruby-файл. Сам файл я сделал исполняемым:
1 | chmod +x ~/.bash/rake.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 48 49 50 | #!/usr/bin/env ruby
begin
require 'rake'
rescue LoadError
require 'rubygems'
require 'rake'
end
class Rake::Application
def task_list
top_level_tasks.join(' ')
end
def notify(message, body, urgency, icon = :info)
system("notify-send --urgency=#{urgency} --icon=#{icon} '#{message}' '#{body}'")
end
def after_run
notify('Rake Tasks: Finished', task_list, :low) unless task_list == 'default'
end
def after_fail
notify('Rake Tasks: Failed', task_list, :normal, :error)
end
def top_level_with_callbacks
top_level_without_callbacks
after_run
end
alias_method :top_level_without_callbacks, :top_level
alias_method :top_level, :top_level_with_callbacks
def run_with_callbacks
begin
run_without_callbacks
rescue SystemExit => e
after_fail
exit(falses)
end
end
alias_method :run_without_callbacks, :run
alias_method :run, :run_with_callbacks
end
Rake.application.run
|
Так как я работаю под Ubuntu, то уведомления я отправляю через notify-send. Вариантов уведомлений два – при успешном выполнении и при ошибке. Единственное, чего мне пока что не удалось добиться – это регулирования времени отображения уведомлений. Но этот момент целиком обусловлен особенностями дизайна убунтовского NotifyOSD, который игнорирует переданное время жизни уведомления.
Эффект от этого маленького трюка у меня выглядит вот так:
rake notes

rake three undefined tasks

Теперь для полного счастья теперь нужно сделать уведомления для Capistrano :) Если знаете какой-нибудь готовый плагин – дайте знать.