Hej,
mam aplikacje ktora uzywa gemu Resque i Rails 4. Aplikacja ta wykonuje zapytani do bazy z czestotliwoscia zedfiniowana w crontabie (whenever gem): co godzine, co dzien itd. Jesli w danym czasie jest kilka raportow resque tworzy kolejke jobow oblugiwana przez 2 workery. Przy czym, zanim kolejka ta zostanie stworzona sprawdzam czy baza danych jest up-do-date. Po tym sprawdzeniu tworzona jest kolejka i wszystko dziala jak nalezy. Raporty sa wysylane przez aplikacje.
Problem powstaje gdy to samo chce wykonac z poziomu aplikacji. Kazdy raport jest zapisany w bazie. Dla kazdego raportu jest stworzona metoda w kontrolerze ktora pozwala na wyslanie tego raportu recznie. Problem w tym ze przed wysylaniem i stworzeniem kolejki sprawdzam jednorazowo czy baza danych jest up-to-date. Poniewaz zapytanie to chwilke trwa i czas oczekiwania na rezultat moze byc wiekszy niz 30 sekund aplikacja dostaje timeouty i raport nie jest wysylany. Mozliwym rozwiazaniem byloby dodac to sprawdzenie do kolejki ale w tym przypadku to samo zapytanie byloby uruchamiane przed kazdym raportem podczas uruchomienia cronjoba. Wiec jesli w danym momencie jest 15 raportow sprawdzanie czy baza danych jest up-to-date wykonywane byloby 15 razy co nie ma sensu i nie jest wydajne.
Ponizej kod i klasa:
class ReportMaintenance
def self.process(scripts)
if DB.uptodate? #tutaj aplikacja dostaje timeout
Report.generate(scripts)
else
#send alert email
end
end
end
Klasa Report:
class Report
def self.generate(scripts)
scripts.each do |script|
Resque.enqueue(SendReportJob, script.id)
end
end
end
Kolejka jest tworzona w klasie SendReportJob:
class SendReportJob
def self.queue
:reporting
end
def self.perform(script_id)
script = Script.find(script_id)
work(script)
end
def self.work(script)
content = DB.execute_query(script)
ReportMailer.send_file(content).deliver
end
end
Czy macie jakis pomysl jak to rozwiazac?