背景工作者在轨道app观看通信

pku*_*rek 8 ruby views background-process resque

让我们说我有一个博客应用程序与帖子.创建帖子后,将创建一个工作程序来处理某些后台操作.我的情况是,在提交帖子表单后,我想显示某种加载消息(gif加载器等),当工作人员完成时,我想隐藏加载消息并显示工作人员提供的一些数据.我的问题是,工人完成工作并将其显示在用户前端的最佳沟通方式是什么.工人回调看起来像这样

def worker_finish
  #message the user
end
Run Code Online (Sandbox Code Playgroud)

小智 13

我认为你可能会忽略了拥有背景工作者这一点,基本上,你试图做的就是弄巧成拙. - 如果用户提交表单并在控制器中排队作业,只是让用户等待工作人员开始和结束,你不仅要完成控制器自己完成的工作,而且你已经完成了使这个过程变得更加复杂(并且这种类型的功能不是内置于resque或sidekiq).

卸载要由队列处理的作业时,您希望立即向客户端返回响应,即

class PostsController < ApplicationController
  def create
    @post = Post.create(params[:post])
    BackgroundBlogOperation.enque(@post.id)
    respond_with(@post)
  end
end
Run Code Online (Sandbox Code Playgroud)

然后将BackgroundBlogOperation类放入队列中,供工作人员完成并处理.如果您需要BackgroundBlogOperation工作程序在完成之后执行其他操作,则可以执行此操作,但这应该在作业本身内进行,以便工作人员可以对此负责.

如果您只是在创建帖子后尝试显示和隐藏微调器,而不重新加载页面,只需在单击提交按钮之前显示javascript微调器,并确保请求类型为js(add:remote => true to form ).然后创建一个javascript视图响应,如下所示:

class PostsController < ApplicationController
  respond_to :js, :only => [:create]
  def create
    @post = Post.create(params[:post])
    BackgroundBlogOperation.enque(@post.id)
    respond_with(@post)
  end
end
Run Code Online (Sandbox Code Playgroud)

而create.js.erb也可以附加一条消息,告诉他们你在后台做的任何事情都已排队,如果它比创建帖子或其他更复杂.

$("#spinner").hide();
Run Code Online (Sandbox Code Playgroud)

现在 - 虽然你最初要求doesent用于任何目的(因为在完成工作时显示和隐藏微调器需要等待控制器完成操作) - 有些情况下向客户端显示该工作已经完成处理是有用的.

首先,我们定义一个后台处理实际有用的场景.假设您有一个按钮,当单击时,将从某些外部API中提取数据,并在从外部站点获取数据后,您正在根据响应执行数据库操作.这将是何时使用后台进程的一个很好的例子.基本上在控制器中,您可以执行以下操作:

class ApiController < ApplicationController
  respond_to :js, :only => [:create]

  def sync_tweets
    TwitterApiJob.enque(current_user.twitter_username)
    respond_with(message: 'Syncing Tweets')
  end

end
Run Code Online (Sandbox Code Playgroud)

现在,告诉用户推文完成同步的时间有点复杂,你有3个基本选项:

1)通过电子邮件通知用户(通常最糟糕的选择imo)2)使用某种html5或支持websocket的rails服务器来运行rails,并通过websocket发送一个推送到客户端,虽然非常酷,但在大多数情况下是矫枉过正的超出此回复的范围.如果你想看到你的选择,谷歌会推动websocket推送.3)对于大多数情况,IMO最佳选择,创建一个通知模型来处理各种用户通知,并在工作中,在工作完成后,执行类似的操作

Notification.create(:user_id => user.id, :message => 'Sync has finished', type => 'sync_complete')
Run Code Online (Sandbox Code Playgroud)

然后,用户请求的下一页,在标题工具栏或任何地方,我会注意到用户有未读通知,提醒用户点击它.

---我想在你提到的帖子中你使用的是resque.我尝试了resque并且它很不错,但是我发现它在生产中调试过于复杂,并且它使用了疯狂的内存 - 我建议你查看sidekiq如果你还没有,它使用redis也可以更快,因为它使用主题:

https://github.com/mperham/sidekiq

它更快,更清洁,更容易安装,imho.