(This question is a follow-up to How do I handle long requests for a Rails App so other users are not delayed too much? )
(这个问题是如何处理Rails应用程序的长请求以便其他用户不会延迟过多的后续问题?)
A user submits an answer to my Rails app and it gets checked in the back-end for up to 10 seconds. This would cause delays for all other users, so I'm trying out the delayed_job gem to move the checking to a Worker process. The Worker code returns the results back to the controller. However, the controller doesn't realize it's supposed to wait patiently for the results, so it causes an error.
用户向我的Rails应用程序提交答案,并在后端检查最多10秒。这会导致所有其他用户的延迟,所以我正在尝试使用delayed_job gem将检查移动到Worker进程。 Worker代码将结果返回给控制器。但是,控制器没有意识到应该耐心等待结果,因此会导致错误。
How do I get the controller to wait for the results and let the rest of the app handle simple requests meanwhile?
In Javascript, one would use callbacks to call the function instead of returning a value. Should I do the same thing in Ruby and call back the controller from the Worker?
如何让控制器等待结果并让应用程序的其余部分同时处理简单的请求?在Javascript中,可以使用回调来调用函数而不是返回值。我应该在Ruby中做同样的事情并从Worker回调控制器吗?
Update:
Alternatively, how can I call a controller method from the Worker? Then I could just call the relevant actions when its done.
更新:或者,如何从Worker调用控制器方法?然后我可以在完成后调用相关的操作。
This is the relevant code:
这是相关代码:
Controller:
def submit
question = Question.find params[:question]
user_answer = params[:user_answer]
@result, @other_stuff = SubmitWorker.new.check(question, user_answer)
render_ajax
end
submit_worker.rb :
class SubmitWorker
def check
#lots of code...
end
handle_asynchronously :check
end
2 个解决方案
#1
3
Using DJ to offload the work is absolutely fine and normal, but making the controller wait for the response rather defeats the point.
使用DJ卸载工作绝对正常,但是让控制器等待响应而不是失败。
You can add some form of callback to the end of your check
method so that when the job finishes your user can be notified.
您可以在检查方法的末尾添加某种形式的回调,以便在作业完成时可以通知您的用户。
You can find some discussion on performing notifications in this question: push-style notifications simliar to Facebook with Rails and jQuery
您可以在此问题中找到关于执行通知的一些讨论:推送式通知与使用Rails和jQuery的Facebook相似
Alternatively you can have your browser periodically call a controller action that checks for the results of the job - the results would ideally be an ActiveRecord object. Again you can find discussion on periodic javascript in this question: Rails 3 equivalent for periodically_call_remote
或者,您可以让浏览器定期调用控制器操作来检查作业的结果 - 结果理想情况下是ActiveRecord对象。您可以在这个问题中找到关于定期javascript的讨论:Rails 3等效于periodic_call_remote
#2
0
I think what you are trying to do here is little contradicting, because you use delayed_job
when do done want to interrupt the control flow (so your users don't want to want until the request completes).
我认为你在这里尝试做的事情几乎没有矛盾,因为你在完成时使用delayed_job想要中断控制流(所以你的用户在请求完成之前不想要)。
But if you want your controller to want until you get the results, then you don't want to use background processes like delayed_job
.
但是如果你希望你的控制器想要得到结果,那么你不想使用像delayed_job这样的后台进程。
You might want to think of different way of notifying the user, after you have done your checking, while keeping the background process as it is.
在完成检查后,您可能想要考虑通知用户的不同方式,同时保持后台进程不变。
#1
3
Using DJ to offload the work is absolutely fine and normal, but making the controller wait for the response rather defeats the point.
使用DJ卸载工作绝对正常,但是让控制器等待响应而不是失败。
You can add some form of callback to the end of your check
method so that when the job finishes your user can be notified.
您可以在检查方法的末尾添加某种形式的回调,以便在作业完成时可以通知您的用户。
You can find some discussion on performing notifications in this question: push-style notifications simliar to Facebook with Rails and jQuery
您可以在此问题中找到关于执行通知的一些讨论:推送式通知与使用Rails和jQuery的Facebook相似
Alternatively you can have your browser periodically call a controller action that checks for the results of the job - the results would ideally be an ActiveRecord object. Again you can find discussion on periodic javascript in this question: Rails 3 equivalent for periodically_call_remote
或者,您可以让浏览器定期调用控制器操作来检查作业的结果 - 结果理想情况下是ActiveRecord对象。您可以在这个问题中找到关于定期javascript的讨论:Rails 3等效于periodic_call_remote
#2
0
I think what you are trying to do here is little contradicting, because you use delayed_job
when do done want to interrupt the control flow (so your users don't want to want until the request completes).
我认为你在这里尝试做的事情几乎没有矛盾,因为你在完成时使用delayed_job想要中断控制流(所以你的用户在请求完成之前不想要)。
But if you want your controller to want until you get the results, then you don't want to use background processes like delayed_job
.
但是如果你希望你的控制器想要得到结果,那么你不想使用像delayed_job这样的后台进程。
You might want to think of different way of notifying the user, after you have done your checking, while keeping the background process as it is.
在完成检查后,您可能想要考虑通知用户的不同方式,同时保持后台进程不变。