我正在尝试使用ActiveJob
诸如电子邮件调度之类的队列作业,但我得到了一个
NotImplementedError (Use a queueing backend to enqueue jobs in the future.
错误
将更新提交到数据库后,在我的model.rb
文件中
class Article < ActiveRecord::Base
include ActiveModel::Dirty
require './app/jobs/email_scheduler_job'
def send_approved_mail
if self.approved_was == false && self.approved
ArticleMailer.article_approved(self.owner).deliver_later
EmailSchedulerJob.set(wait: 2.weeks).perform_later(owner)
end
end
end
Run Code Online (Sandbox Code Playgroud)
并在我的EmailSchedulerJob
class EmailSchedulerJob < ActiveJob::Base
queue_as :default
def perform(*args)
# Do something later
end
end
Run Code Online (Sandbox Code Playgroud) 我有一个简单的模型 ,Payments
它有两个字段amount
和running_balance
。payment
创建新记录时,我们会查找running_balance
其先前付款的 ,例如last_running_balance
并保存last_running_balance+amount
为running_balance
当前付款的 。
以下是我们实现该Payments
模型的三个失败尝试。为简单起见,假设先前的付款始终存在,id
并且随着付款的创建而增加。
尝试 1:
class Payments < ActiveRecord::Base
before_validation :calculate_running_balance
private
def calculate_running_balance
p = Payment.last
self.running_balance = p.running_balance + amount
end
end
Run Code Online (Sandbox Code Playgroud)
尝试 2:
class Payments < ActiveRecord::Base
after_create :calculate_running_balance
private
def calculate_running_balance
p = Payment.where("id < ?", id).last
update!(running_balance: p.running_balance + amount)
end
end
Run Code Online (Sandbox Code Playgroud)
尝试 3:
class Payments < ActiveRecord::Base
after_commit :calculate_running_balance
private
def calculate_running_balance …
Run Code Online (Sandbox Code Playgroud) 有什么方法可以让我看到队列中还有多少(甚至可能检查每个作业?)作业?
我的工作中有以下片段:
before_enqueue do |job|
# do something
@car = create_car
end
before_perform do |job|
# do something
@car.update(type: 'broken')
end
Run Code Online (Sandbox Code Playgroud)
但当工作执行时@car
是nil
. 是否可以以某种方式将实例变量从一个回调传递到第二个回调?哪怕只是ID
也好。干杯。
我正在运行 Rails 4.2.8,我想让我的工作只在某些条件下运行。目前我正在检查调用作业的代码,但在作业类中包含逻辑会更清晰。有没有人这样做过?
class MyJob < ApplicationJob
before_enqueue do |job|
# check and stop job from being enqueued under certain conditions
end
def perform(args*)
# code here
end
end
Run Code Online (Sandbox Code Playgroud)
我使用 Sidekiq 4.2.10 作为后台作业适配器。
使用 Rails 5.2.4,我尝试在后台(在作业内)生成 pdf,然后将其附加到模型,如下所示:
pdf_contents = ApplicationController.render(
pdf: "name",
template: 'mytemplate.html.erb',
layout: 'pdf_layout.html',
disposition: 'attachment'
)
@user.attach(io: StringIO.new(pdf_contents), filename: "file.pdf", content_type: "application/pdf")
Run Code Online (Sandbox Code Playgroud)
但我得到:
WARN: ActionView::Template::Error: private method `format' called for nil:NilClass
Run Code Online (Sandbox Code Playgroud)
使用
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
Run Code Online (Sandbox Code Playgroud) 我使用Rails 4.2和delayed_job 4.0.6作为我的ActiveJob后端.
我有一份工作,我只想在队列中允许一次.有问题的工作需要一分钟才能运行.它通过模型上的回调排队.回调将比工作完成时更频繁地发生.这项工作将来不必排队多次.
这是我想要完成的一些伪代码.
# app/jobs/refresh_account_cache_job.rb
class RefreshAccountCacheJob < ActiveJob::Base
def before_enqueue
skip if job_already_enqueued
end
def perform
Account.write_to_cache
end
def job_already_enqueued
# ?
end
end
Run Code Online (Sandbox Code Playgroud)
如果作业的实例在再次调用时正在运行,则它应该仍然排队以备将来使用.我正在寻找一种方法让这项工作最终入组,最多可以运行1次.
我假设答案必须特定于delayed_job,但如果它可以推广到ActiveJob,那将更好.
我有几个有很多孩子的模特.依赖性破坏变得非常沉重.任何人都知道如何将依赖性破坏与活跃的工作联系起来?或者,我唯一的选择是通过父模型上的回调删除依赖的销毁和角色我自己的工作?
我正在尝试使用Sidekiq来完成以下工作.
未排队时执行该作业(perform_now),但在使用Sidekiq调用(perform_later)时失败.
AddEmployeesToRoomJob.perform_now room ## works fine
AddEmployeesToRoomJob.perform_later room ## breaks in Sidekiq
Run Code Online (Sandbox Code Playgroud)
错误:
AddEmployeesToRoomJob JID-da24b13f405b1ece1212bbd5 INFO: fail: 0.003 sec
2016-08-20T14:57:16.645Z 19456 TID-owmym5fbk WARN: {"class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped" :"AddEmployeesToRoomJob","queue":"default","args": [{"job_class":"AddEmployeesToRoomJob","job_id":"0ba5bd30-e281-49a7-a93f- 6e50445183ac","queue_name":"default","priority":null,"arguments": [{"_aj_globalid":"gid://dragonfly/Room/1"}],"locale":"en"}],"retry":true, "jid":"da24b13f405b1ece1212bbd5","created_at":1471704675.739077,"enqueued _at":1471705036.6406531,"error_message":"Error while trying to deserialize arguments: Couldn't find Room with 'id'=1","error_class":"ActiveJob::DeserializationError","failed_at":14717 04675.946183,"retry_count":4,"retried_at":1471705036.644416}
2016-08-20T14:57:16.645Z 19456 TID-owmym5fbk WARN: ActiveJob::DeserializationError: Error while trying to deserialize arguments: Couldn't find Room with 'id'=1
2016-08-20T14:57:16.645Z 19456 TID-owmym5fbk WARN: /Users/tamlyn/.rvm/gems/ruby-2.2.3/gems/activerecord- 5.0.0.1/lib/active_record/relation/finder_methods.rb:357:in `raise_record_not_found_exception!'
Run Code Online (Sandbox Code Playgroud)
我的Job 类AddEmployeesToRoomJob <ApplicationJob queue_as:default
def perform(room)
employees = Employee.all
if employees.length > 0
employees.each do …
Run Code Online (Sandbox Code Playgroud) 在将作业放入队列之前,我想检查队列,看看队列中是否已经存在具有完全相同的参数的作业,在这种情况下,不将作业放入队列。但是我不知道该怎么做。可能吗?
我知道我可以使用TestHelper在测试中轻松做到这一点。TestHelper依赖于我们当然不会在生产环境中使用的TestAdapter。
多一点背景。在我们的API中,我们在每个请求中检索客户端版本号。我们使用对讲机作为支持,并希望在对讲中显示应用程序版本,以便我们可以看到客户在解决支持问题时使用的版本。但是为了限制打通对讲机的次数,我将每次发给对讲机的时间都延迟了几分钟,而在发帖排队时,我不想用相同的数据排队。
我的问题与使用ActiveJob AsyncAdapter列出队列中的任务有关,但该问题仅涉及排队作业的数量。
有效地重新计划ActiveJob(resque / sidekiq)表明这是不可能的,我将需要单独实现该解决方案。
我可以使用ActiveJobs以某种方式检查队列及其中的作业,还是需要跟踪已排队的内容和执行的操作?