#ruby #delayed-job
#ruby #отложенное задание
Вопрос:
Моя отложенная работа не работает. Я пытаюсь создать фоновую задачу для файла rake, используя отложенное задание, которое должно выполняться каждые 15 минут. Я скопировал свои задачи rake в свой файл rake и установил их в своем контроллере в качестве методов. Мне нужно отложенное задание, потому что heroku выполняет cron только каждые 1 час.
Вот мой контроллер приложения:
class ApplicationController < ActionController::Base
require 'delayed_job'
require 'Mechanize'
require 'pp'
protect_from_forgery
def iqmedier
agent = WWW::Mechanize.new
agent.get("http://www.iqmedier.dk")
form = agent.page.forms.first
form.submit
agent.page.link_with(:href => "/Publisher/Stats").click
form = agent.page.forms.first
form.submit
@stats = agent.page.search('//tr')[-2]
@existing = Reklamer.find(:first, :conditions => {:dato => @stats[0]})
if @existing.nil?
Reklamer.create!(:virksomhed => 'Iqmedier', :dato => @stats[0], :unik_klik => @stats[1], :klik => @stats[2], :unik_vis => @stats[3], :vis => @stats[4], :leads => @stats[5], :ordre => @stats[6], :cpc => @stats[7], :earn => @stats[8])
elsif @existing.dato != Date.today
Reklamer.create!(:virksomhed => 'Iqmedier', :dato => Date.today, :unik_klik => 0, :klik => 0, :unik_vis => 0, :vis => 0, :leads => 0, :ordre => 0, :cpc => 0, :earn => 0)
else
@existing.update_attributes!(:unik_klik => @stats[1], :klik => @stats[2].to_i, :unik_vis => @stats[3], :vis => @stats[4], :leads => @stats[5], :ordre => @stats[6], :cpc => @stats[7], :earn => @stats[8])
end
end
def euroads
agent = Mechanize.new { |agent|
agent.user_agent_alias = 'Mac Safari'}
agent.get("http://www.euroads.dk")
form = agent.page.forms.first
form.submit
@month = Date.today.strftime("%m").to_s
agent.get("http://www.euroads.dk/system/index.php?showpage=showstatamp;show=overviewamp;month=#{@month}amp;year0=2011amp;day=1amp;month=#{@month}amp;year=2011amp;day1=31amp;month1=#{@month}amp;year1=2011amp;fk_campaign=amp;fk_survey=amp;fk_track=amp;fk_pool=amp;columns1=1amp;columns2=2amp;columns4=4amp;columns14=14amp;columns5=5amp;columns6=6amp;columns7=7amp;columns8=8amp;columns9=9")
@stats = agent.page.search('table.ea').search('tr')
@existing = Reklamer.find(:first, :conditions => {:dato => @stats[0]})
if @existing.nil?
Reklamer.create!(:virksomhed => 'Euroads', :dato => @stats[0], :unik_klik => @stats[1], :klik => @stats[2].to_i, :unik_vis => @stats[3], :vis => @stats[4], :leads => @stats[5], :ordre => @stats[6], :cpc => @stats[7], :earn => @stats[8])
elsif @existing.dato != Date.today
Reklamer.create!(:virksomhed => 'Euroads', :dato => Date.today, :unik_klik => 0, :klik => 0, :unik_vis => 0, :vis => 0, :leads => 0, :ordre => 0, :cpc => 0, :earn => 0)
else
@existing.update_attributes(:unik_klik => @stats[1], :klik => @stats[2].to_i, :unik_vis => @stats[3], :vis => @stats[4], :leads => @stats[5], :ordre => @stats[6], :cpc => @stats[7], :earn => @stats[8])
end
end
def mikkelsen
agent = Mechanize.new
agent.get("http://affilate.mikkelsenmedia.dk/partnersystem/mylogins.php")
form = agent.page.forms.first
@stats = agent.page.search('//tr')
@existing = Reklamer.find(:first, :conditions => {:dato => @stats[0] })
if @existing.nil?
Reklamer.create!(:virksomhed => 'Mikkelsen', :dato => @stats[0], :unik_klik => @stats[3], :klik => @stats[3].to_i, :unik_vis => @stats[1], :vis => @stats[1], :leads => @stats[4], :ordre => @stats[9], :cpc => @stats[3], :earn => @stats[5])
else
@existing.update_attributes(:virksomhed => 'Mikkelsen', :dato => @stats[0], :unik_klik => @stats[3], :klik => @stats[3].to_i, :unik_vis => @stats[1], :vis => @stats[1], :leads => @stats[4], :ordre => @stats[9], :cpc => @stats[3], :earn => @stats[5])
end
end
def orville
agent = WWW::Mechanize.new
agent.get("https://dk.orvillemedia.com")
form = agent.page.forms.first
form.submit
@dato = Date.today.strftime("%Y-%m-%d").to_s
@month = Date.today.strftime("%m").to_s
@day = Date.today.strftime("%d").to_s
@stats = agent.page.search('//tr')
@existing = Reklamer.find(:first, :conditions => {:dato => @dato})
if @existing.nil?
Reklamer.create!(:virksomhed => 'Orville', :dato => @dato, :unik_klik => @stats[2], :klik => @stats[2].to_i, :unik_vis => @stats[1], :vis => @stats[1], :leads => @stats[3], :ordre => '0', :cpc => (@stats[5] == '-' ? 0 : @stats[3]), :earn => @stats[6])
else
@existing.update_attributes(:virksomhed => 'Orville', :dato => Date.today, :unik_klik => @stats[2], :klik => @stats[2].to_i, :unik_vis => @stats[1], :vis => @stats[1], :leads => @stats[3], :ordre => '0', :cpc => (@stats[5] == '-' ? 0 : @stats[3]), :earn => @stats[6])
end
end
def runall
[:iqmedier, :euroads, :mikkelsen, :orville].each{|a| send(a)}
end
handle_asynchronously :runall, :run_at => Proc.new { 5.minutes.from_now }
Когда я запускаю rake jobs: work, оно запускается, но не выполняет задание runall из
Комментарии:
1. я нигде не вижу задержки вызова @_@
2. Куда должен идти вызов delay?
3. Что вы подразумеваете под GET. Очистка экрана выполняется POST. Запускать все должны быть все методы, iqmedier, euroads, orville и mikkelsen
4. задержка — это та, которая добавляет задание в вашу базу данных jobs
5. Куда должна идти задержка в моем контроллере?
Ответ №1:
Если я правильно понимаю, что вы пытаетесь сделать, то у вас должно быть следующее:
scraper.rb
require 'mechanize'
class Scraper
def perform
[:iqmedier, :euroads, :mikkelsen, :orville].each{|a| send(a)}
end
def iqmedier
# some code
end
def mikkelsen
# some code
end
def orville
# some code
end
end
в вашем контроллере:
require 'delayed_job'
class MyController < ApplicationController
def runall
Delayed::Job.enqueue(Scraper.new, :run_at => 5.minutes.from_now)
end
end
Для добавления заданий извне rails вы можете написать что-то подобное, а затем запустить это с помощью rails runner:
require 'scraper'
Delayed::Job.enqueue Scraper.new
Delayed::Job.enqueue Scraper.new, :run_at => 15.minutes.from_now
Delayed::Job.enqueue Scraper.new, :run_at => 30.minutes.from_now
Delayed::Job.enqueue Scraper.new, :run_at => 45.minutes.from_now
Комментарии:
1. Я поместил runall в свой контроллер приложений, а scraper.rb — в myaproot / lib / jobs. Когда я запускаю rake jobs: work, запускается worker, но, похоже, на самом деле ничего не происходит. Оно просто застряло при запуске worker
2. Просматривали ли вы в своем браузере URL, который должен поставить задание в очередь, например. Что-то / runall?
3. Когда я просматриваю действие runall, я получаю ошибку nameerror: неинициализированную константу ApplicationController::Scraper
4. Вам нужно запросить ‘scraper’.
5. Теперь он говорит, что шаблон отсутствует? Зачем мне нужен view?
Ответ №2:
Если вы просто хотите запускать код каждые X минут / час, то для этого вам не нужно delayed_job. Это было бы своего рода излишеством и чрезмерно разработано. Просто используйте этот код здесь:
until 2 < 1 do
if Time.now.min % 15 == 0
puts "Execute your code here!"
if Time.now.min % 15 == 0
sleep(60)
end
end
end
Поместите код в Rakefile, создайте из него задачу и разверните ее на рабочей платформе heroku. Это сработает. Вот полное руководство для этого:http://robert-reiz.com/2012/06/12/cron-jobs-on-heroku /.
Для этого решения вам даже не нужен Herokus Cron или надстройка планировщика. И вам не нужны никакие дополнительные драгоценные камни, такие как delayed_job. Прагматичное решение. Держите его тонким 😉
Комментарии:
1. Если вам нужен более сложный планировщик для задач cron, обратите внимание на Rufus и clockwork. Я думаю, это лучше подходит для вашего варианта использования, чем delayed_job.