使用delayed_job增加
每当创建投资
时,我都会尝试将列 (yest_shareholder_count
) 的增量延迟一天,以便记录拥有投资的用户数量一天前对一家企业
进行了投资
(因此我可以使用这些数据来生成跟踪投资者数量随时间变化的图表)。
我认为最简单的方法是使用delayed_job,但这不起作用。 Delayed_job 在一个单独的表中创建,根据 SQLite DB 浏览器,它会在一天后运行。 但是 yest_shareholder_count 列没有增加。
Venture
模型:
def yest_increment
self.increment!(:yest_shareholder_count)
end
handle_asynchronously :yest_increment, :run_at => Proc.new {1.minute.from_now}
投资
控制器:
def create
@venture = Venture.find(params[:share_id])
@venture_increment= @venture.increment(:shareholder_count)
@venture_yest_increment= @venture.yest_increment
@investment = current_user.invest!(@venture)
if @venture_increment.save and @venture_yest_increment.save
respond_to do |format|
format.html {redirect_to @venture}
end
end
end
直接的增量按其应有的方式发生,但延迟的增量永远不会发生。
这些是delayed_jobs表中“handler”列的内容,以防万一它们有用:
--- !ruby/struct:Delayed::PerformableMethod
object: !ruby/ActiveRecord:Venture
attributes:
created_at: 2011-06-21 07:00:12.252808
onemth_shareholder_count: 0
updated_at: 2011-08-09 16:50:36.864354
onewk_shareholder_count: 0
shareholder_count: 4
id: 49
user_id: 40
yest_shareholder_count: 0
method_name: :yest_increment_without_delay
args: []
我不确定“yest_increment_without_delay”来自哪里,或者为什么“args”为空......
非常感谢任何帮助。
编辑:我有“1.month.from_now”而不是“1.day.from_now”只是为了测试代码。
I'm trying to delay the increment on a column (yest_shareholder_count
) by one day whenever an investment
is created in order to keep a record of the number of users that had an investment
in a venture
one day ago (so I can use this data to produce graphs tracking the number of investors over time).
I figured the simplest way to do this would be to use delayed_job
, but this isn't working. The delayed_job is created in a separate table and, according to the SQLite DB Browser, it is run one day later. But the yest_shareholder_count column is not being incremented.
Venture
Model:
def yest_increment
self.increment!(:yest_shareholder_count)
end
handle_asynchronously :yest_increment, :run_at => Proc.new {1.minute.from_now}
Investments
Controller:
def create
@venture = Venture.find(params[:share_id])
@venture_increment= @venture.increment(:shareholder_count)
@venture_yest_increment= @venture.yest_increment
@investment = current_user.invest!(@venture)
if @venture_increment.save and @venture_yest_increment.save
respond_to do |format|
format.html {redirect_to @venture}
end
end
end
The straightforward increment happens as it should, but the delayed increment never does.
These are the contents of the "handler" column in the delayed_jobs table, just in case they are useful:
--- !ruby/struct:Delayed::PerformableMethod
object: !ruby/ActiveRecord:Venture
attributes:
created_at: 2011-06-21 07:00:12.252808
onemth_shareholder_count: 0
updated_at: 2011-08-09 16:50:36.864354
onewk_shareholder_count: 0
shareholder_count: 4
id: 49
user_id: 40
yest_shareholder_count: 0
method_name: :yest_increment_without_delay
args: []
I'm not sure where the "yest_increment_without_delay" is coming from, or why "args" is blank...
Any help much appreciated.
EDIT: I have "1.minute.from_now" rather than "1.day.from_now" just to test the code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您定义要使用延迟作业异步处理的方法时,延迟作业会创建一个别名方法链(我对此不太熟悉)。它导致调用由延迟作业处理的原始方法名称,并且当延迟作业到达它时,它调用original_method_name_without_delay,这是实际对象方法的别名。
没有参数,因为您没有将任何参数传递给
yest_increment
。如果您将任何参数传递给yest_increment,它们将与作业一起保存,以便在延迟作业调用它时传递给实际方法。表中的对象是delayed_job存储在db中的对象的序列化版本。当作业需要运行时,它将通过反序列化创建一个对象,并使用给定的参数调用该方法。由于该对象是 ActiveRecord 对象,因此反序列化涉及从序列化对象中检索 id 并从数据库中查找该对象。
根据您的实际问题,它不起作用,不清楚什么不起作用。延迟的作业是否没有被调用,或者值没有增加,或者是否太快调用了elasted_job。如果是最后一个,将代码更改为以下内容可能会有所帮助:
When you define a method to be handled asynchronously using delayed job, delayed job creates an alias method chain(which I am not very familiar with). It leads to calls original method name handled by delayed job, and when delayed job gets around to it, it calls the original_method_name_without_delay, which is the actual objects method aliased.
There are no arguments as you didn't pass any arguments to
yest_increment
. If you pass any arguments toyest_increment
they will be saved along with the job, to be passed on to actual method when delayed job calls it.The object in the table is the serialized version of the object, delayed_job stores in db. When job needs to be run, it will create a object by deserializing this and call the method with given arguments on it. As the object is an ActiveRecord object, de-serialization involves, retrieving id from serialized object and finding the object from database.
As per your actual problem, that it is not working, it is not clear what is not working. Does the delayed job is not getting called or the value is not getting incremented or the delayed_job gets called too soon. If its the last one, changing your code to following might help: