我有一个延迟工作的应用程序。我想在操作完成后(成功或完成)使用回调并在客户端通知用户。我有这样的事情:
class ScannerJob < ApplicationJob
queue_as :default
def perform(links, count = 0)
links do |url|
broadcast_it(url.to_s, count +=1)
end
after
end
def after
respond_to do |format|
format.js { render :js => "alert('Congratulations');" }
end
end
我有这样的事情:未终止的字符串遇到结束。我发现这个消息来源说不可能这样做。
处理此问题的最佳方法是什么?为什么我不能简单地调用回复js?
谢谢!
答案 0 :(得分:1)
是的,这是不可能的。让我们找出原因。
我很肯定你HTTP
请求循环工作的正常程度。
传统方式Client
要求Server
填写他的请求。它是否查询数据或者是否将数据发送到服务器上。服务器处理客户端的请求并将响应发送给客户端。在服务器完全填满客户端请求之后,除非客户端再次请求/请求,否则服务器无法与客户端通信。所以基本上客户端请求服务器和服务器响应该请求并等待下一个请求。
不要放弃延迟的工作。 你知道为什么我们在项目中添加延迟工作。如果我们同步处理它们,可能会有一些性能匮乏或花时间执行任务会延迟用户响应。我是
假设我想根据用户的要求分别向100个人发送电子邮件,每封电子邮件需要5秒钟才能发送。因此,需要500秒(大约9分钟)来完成所有这些。
我们无法以同步方式执行此操作,因为这对用户来说是一次糟糕的体验。用户请求将超时,即使没有超时,用户也会将其视为无响应请求并离开网站。
因此,我们将处理这些电子邮件发送任务作为背景。每当用户请求向100个人发送电子邮件时,我们立即将响应发送回用户并告诉他们成功消息。我们要求延迟工作在后台处理此任务。
class MyController < ApplicationController
def process_heavy_requestion
EmailerSender.delay.send_email_in_backgroun(params) #We are delegating email sending task to delayed job. And we assume it will be done.
render text: "Email sent Successfully"
end
end
在此操作中,我们向用户回复了一条消息。并在后台发送电子邮件。
因此,如果我们将其映射到上面的讨论,那么Server已通过成功消息响应客户端。 因此,如果我们想要向用户发送回复,那么它就不可能。除非用户再次问我们。
现在让我们来解决你的问题。
您想通知使用后台任务的实际进度,这是一种方法。 每当在后台执行任务时,您可以在用户表/或任何其他表中设置标志。该任务的状态是什么。甚至您可以在自定义工作器中添加另一列。
在调用后台任务之前,您需要将该列的值更改为&#39; pending&#39;。在延迟的工作工作者中,您将相应地设置该列的值i-e(失败或完成)
基本上,任务输出将存储在数据库中的某个位置,甚至可以将其存储在用户会话中。
因此,每当用户要求处理该请求时,您将在后台处理tak,并使用javascript添加响应脚本,该脚本将在固定时间i-e(5秒)后检查该任务的结果。因此,使用javascript,您将在每X
秒后将请求发送到服务器,这是我上一个任务的状态。如果服务器响应它已完成,那么您向用户显示成功消息,或者如果失败则向用户显示错误消息。
我希望它能清除你的困惑