我设计了一个用户界面,用于上传用户列表(电子邮件,姓名等),在此过程结束时,每个用户都插入了我的数据库并收到了一封电子邮件
处理此任务的后端api是在rails上的ruby中构建的。
目前对输入的大小没有限制,因此我想为UI用户提供一种在整个上传过程中取消剩余作业的方法,而不取消已经发送的作业。
我还希望在GUI上提供正在处理作业的实时状态,已经完成。
此外,我想确保生成的同时处理作业的作业数量有限,以便服务器上的其他用户不会受到影响。
有了这个......并且我的有限的后端/ javascript知识,我想我会做的是为每个用户(或者可能是几个用户的分组)产生单独的ajax调用,使用java来限制任何用户时间只有X ajax调用可以同时运行(我希望这是可能的),当每次调用返回时,我将更新UI以反映作业的状态,然后为下一组作业生成另一个,直到整件事情都完成了。如果UI用户希望取消,他们可以使完成的作业保持完整。
这是可取的还是有更好的方法来做到这一点。
提前致谢
答案 0 :(得分:0)
我使用sidekiq来完成这样的任务。它完全符合您的需求。
您设置了许多工作程序,这些工作程序是服务器上的线程。然后,当POST或其他请求从UI进入时,您将每个请求排队作为sidekiq中的作业,并立即将状态返回到浏览器,因此他们不必等待,想知道是否会发生某些事情成功,永远挂起,或通过网络服务器获得超时。
稍后,作业将异步处理。它可以更新数据库中的状态以进行报告。
以下是在sidekiq下运行的worker的示例:
class PageFetcher
include Sidekiq::Worker
def perform page_id
page = Page.find(page_id)
path = Page.absolute_path
# Do some big, long, error-prone thing with external depencies:
File.binwrite(path, open(page.source_url).read)
saved_size = File.size(path)
if page.expected_file_size != saved_size.to_s
bad_path = path + '.bad'
File.rename(path, bad_path)
# Raise an error, and sidekiq will automatically wait a while and try again later:
raise IOError, "Could not cache #{page.source_url} to #{path}. " +
"File size is #{saved_size}, expected #{page.file_size}. "
end
# update some status field, so this success can be reported:
page.make_status_cached!
# do something else that depends on this success:
page.notify_page_indexer
end
end
当您收到新请求时,请创建一个新页面,然后将其处理排队如下:
Page.perform_async(self.id)
瞧!那就是它。