Skip to content

Instantly share code, notes, and snippets.

@bopm
Created April 29, 2011 21:08
Show Gist options
  • Save bopm/949049 to your computer and use it in GitHub Desktop.
Save bopm/949049 to your computer and use it in GitHub Desktop.
Batch processing in rails
class Book < ActiveRecord::Base
has_many :pages
belongs_to :p2fline
belongs_to :print_profile
belongs_to :publish_profile
acts_as_audited :except => [:name, :file_name]
include AASM
aasm_column :state
aasm_initial_state :loaded
aasm_state :loaded, :enter => :reset_retry_count, :exit=>:apply_total_pages
aasm_state :in_abbyy, :enter => :copy_to_abbyy
aasm_state :p2f_queue, :enter=>:apply_pages_count
aasm_state :in_p2fline, :enter => :copy_to_p2fline
aasm_state :p2f_printing, :enter => :p2f_print
aasm_state :print_failed, :enter => :free_p2fline
aasm_state :wait_for_confirm, :enter => :free_p2fline
aasm_state :confirmed
aasm_state :confirmed_non_full
aasm_state :on_server
aasm_state :on_server_non_full
aasm_state :published
aasm_state :published_non_full
aasm_state :hold
aasm_state :mycop
aasm_state :restarting, :after_enter => :check_avail_pdf
aasm_state :restarting_full, :exit=>:restart_full
def restart
if @book.restartable?
Audit.as_user current_user do
@book.restart_production!
end
flash[:notice] = 'Обработка перезапущена.'
else
flash[:error] = 'Перезапуск невозможен.'
end
redirect_to request.referer
end
namespace :munin do
task :config do
puts <<-CONFIG
graph_title Produced pages in last 5 minutes
graph_args -l 0
graph_vlabel pages amount
graph_category App
graph_info This graph shows amount of pages produced
texts.label Text files
docs.label Doc files
views.label View files
quotes.label Quote files
CONFIG
exit 0
end
task :run => :environment do
res = ActiveRecord::Base.connection.execute("select count(nullif(text_ready_time>(now()-'5 minutes'::interval),false)) as c0,count(nullif(doc_ready_time>(now()-'5 minutes'::interval),false)) as c1,count(nullif(view_ready_time>(now()-'5 minutes'::interval),false)) as c2,count(nullif(quote_ready_time>(now()-'5 minutes'::interval),false)) as c3 from pages where updated_at > (now()-'5 minutes'::interval);")
if res
puts "texts.value #{res[0]['c0']}"
puts "docs.value #{res[0]['c1']}"
puts "views.value #{res[0]['c2']}"
puts "quotes.value #{res[0]['c3']}"
end
exit 0
end
end
namespace :nagios do
task :abbyy_activity, [:warn, :crit] => :environment do |t, args|
if args.warn and args.crit
states_list = ["loaded", "in_abbyy", "p2f_queue"]
warn_level = args.warn.to_i
crit_level = args.crit.to_i
warn_events = Audit.find(:all, :conditions=>["auditable_type = 'Book' and (username is null or username ilike 'rake:%') and action = 'update' and created_at > ?", warn_level.minutes.ago])
crit_events = Audit.find(:all, :conditions=>["auditable_type = 'Book' and (username is null or username ilike 'rake:%') and action = 'update' and created_at > ?", crit_level.minutes.ago])
if (crit_count = crit_events.select{|a| a['changes']['state'] and (a['changes']['state'] & states_list).size > 1 }).empty?
puts "CRITICAL No state changes at abbyy for #{crit_level} minutes"
exit 2
end
if (warn_count = warn_events.select{|a| a['changes']['state'] and (a['changes']['state'] & states_list).size > 1 }).empty?
puts "WARNING No state changes at abbyy for #{warn_level} minutes"
exit 1
end
puts "OK Abbyy: state changes #{warn_count.size} for #{warn_level} minutes; state changes #{crit_count.size} for #{crit_level} minutes."
exit 0
else
exit 3
end
end
task :p2f_activity, [:warn, :crit] => :environment do |t, args|
if args.warn and args.crit
states_list = ["p2f_queue", "in_p2fline", "p2f_view_printing", "p2f_quote_printing", "print_failed", "wait_for_confirm"]
warn_level = args.warn.to_i
crit_level = args.crit.to_i
warn_events = Audit.find(:all, :conditions=>["auditable_type = 'Book' and (username is null or username ilike 'rake:%') and action = 'update' and created_at > ?", warn_level.minutes.ago])
crit_events = Audit.find(:all, :conditions=>["auditable_type = 'Book' and (username is null or username ilike 'rake:%') and action = 'update' and created_at > ?", crit_level.minutes.ago])
if (crit_count = crit_events.select{|a| a['changes']['state'] and (a['changes']['state'] & states_list).size > 1 }).empty?
puts "CRITICAL No state changes in print2flash for #{crit_level} minutes"
exit 2
end
if (warn_count = warn_events.select{|a| a['changes']['state'] and (a['changes']['state'] & states_list).size > 1 }).empty?
puts "WARNING No state changes in print2flash for #{warn_level} minutes"
exit 1
end
puts "OK Print2Flash: state changes #{warn_count.size} for #{warn_level} minutes; state changes #{crit_count.size} for #{crit_level} minutes."
exit 0
else
exit 3
end
end
end
namespace :production do
desc "Loads files into Production line"
task :process_batch => :environment do
Audit.as_user("rake:process_batch") do
Book.getFromBatch unless running?("process_batch")
end
end
desc "Print2Flash print task, RUN ONLY ON WINDOWS"
task :p2f_print => :environment do
(puts "non Windows" and return) unless RUBY_PLATFORM =~ /mswin/
(puts "line_id undefined" and return) unless LINE_ID
(puts "line busy" and return) if P2fline.find(LINE_ID).busy?
RAILS_DEFAULT_LOGGER.auto_flushing = true
RAILS_DEFAULT_LOGGER.info ":p2f_print running"
Audit.as_user("rake:p2f_print:#{LINE_ID}") do
p2f_view_print() unless running?("p2f_print")
end
end
def p2f_view_print()
book = Book.scoped_by_p2fline_id(LINE_ID).find_in_state(:first, :p2f_printing)
book = Book.scoped_by_p2fline_id(LINE_ID).find_in_state(:first, :in_p2fline) unless book
if book
puts "#{book.id} #{book.state} print"
book.p2f_print!
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment