我在我的控制器中启动一个线程,并希望在此之后立即重定向用户。
class Profile::GeneralController < ProfileController
def update
startTheThread(profile)
#sleep(5)
redirect_to 'selection_controller'
end
end
class ProfileController < ApplicationController
def startTheThread(profile = nil)
$collector_threads[current_user.id][sector] = Thread.new {
Thread.current['collecting_status'] = { a: 1, c: 0, c_id: -1, r: false }
start_threaded_collector(sector)
}
end
end
当我告诉控制器睡觉时 - 让我们说 - 5秒钟,线程完成就像它应该的那样。
一旦用户切换到另一个页面,线程就会死掉 - 为什么这样,我如何在控制器之间保持线程活跃。
答案 0 :(得分:1)
我和@meagar在这里,这是一个严重的麻烦。在完成Web请求后,假定您的进程将被终止,因为当他们正在修复多余的实例时,某些Ruby on Rails流程管理器会发生这种情况。
在控制器实例之间共享数据也应该被认为是不可能的,除非您以某种方式持久保存数据:数据库,会话,cookie或通过GET或POST的参数。
在典型的系统中,您将在M台计算机上拥有N个Ruby进程,如果他们不主动处理任何请求,则会在没有警告的情况下任意启动和停止进程。没有一些外部IPC,就无法在这些数据之间可靠地共享数据。
您可能需要这些控制器可以联系的后台服务器进程以获取他们可能需要的任何信息,或者可以将数据转储到数据库或像Redis这样可以接收的服务的进程。
您可以通过将作业推送到Redis队列,让另一个进程看到该队列工作并弹出作业并对其进行处理来实现这一点。这可以通过Redis中的BLPOP
命令轻松完成,您的线程将阻止等待工作,然后在有事情要做时立即继续。