Rails,如何知道某个特定请求是否仍然 运行
Rails, how to know if a particular request is still running
如何检测特定 request
是否仍然有效?
例如我有这个请求uuid:
# my_controller.rb
def my_action
request.uuid # -> ABC1233
end
从另一个请求中,我如何知道带有 uuid ABC1233
的请求是否仍在工作?
好奇者:
正在执行 beanstalk directives 我是 运行 使用 URL 请求的 cron 作业。
如果上一个迭代仍然是 运行,我不想开始下一个迭代。我不能只传递由请求更新的 ini/end
标志,因为请求有时会在完成之前死亡。
使用正常的 cron 任务,我使用进程的 PID 正确地管理了它。
但我认为我不能再使用 PID,因为 Web 服务器中的进程可以在不同的请求之间重用。
我不认为 Rails(或更准确地说,Rack)对此有支持,因为(据我所知)每个 Rails 请求都不知道任何其他请求.您可能会尝试访问所有 运行 线程(甚至进程),但这种实现(如果可能的话)对我来说似乎很难看
.
自己实现怎么样?
class ApplicationController < ActionController::Base
before_filter :register_request
after_filter :unregister_request
def register_request
$redis.set request.uuid
end
def unregister_request
$redis.unset request.uuid
end
end
你仍然需要弄清楚如何处理异常,因为 after_filters 被跳过(也许将整个代码移动到中间件:在中间件的前阶段,它将 uuid 写入 redis 和在之后的阶段,它删除了密钥)。我敢肯定,还有很多其他方法可以实现这一目标,并且显然可以用您最喜欢的持久性选择替代 redis。
终于恢复了之前基于PID的方法
我实现了这样的东西:
# The Main Process
module MyProcess
def self.run_forked
Process.fork do
SynchProcess.run
end
Process.wait
end
def self.run
RedisClient.set Process.pid # store the PID
... my long process code is here
end
def self.still_alive?(pid)
!!Process.kill(0, pid) rescue false
end
end
# In one thread I can do
MyProcess.run_forked
# In another thread I can do
pid = RedisClient.get
MyProcess.still_alive?(pid) # -> true if the process still running
我可以从 Rails 请求中调用此代码,即使请求进程被重用,子进程也不会被重用,我可以监视子进程的 PID 以查看 Ruby进程还在运行.
如何检测特定 request
是否仍然有效?
例如我有这个请求uuid:
# my_controller.rb
def my_action
request.uuid # -> ABC1233
end
从另一个请求中,我如何知道带有 uuid ABC1233
的请求是否仍在工作?
好奇者:
正在执行 beanstalk directives 我是 运行 使用 URL 请求的 cron 作业。
如果上一个迭代仍然是 运行,我不想开始下一个迭代。我不能只传递由请求更新的 ini/end
标志,因为请求有时会在完成之前死亡。
使用正常的 cron 任务,我使用进程的 PID 正确地管理了它。 但我认为我不能再使用 PID,因为 Web 服务器中的进程可以在不同的请求之间重用。
我不认为 Rails(或更准确地说,Rack)对此有支持,因为(据我所知)每个 Rails 请求都不知道任何其他请求.您可能会尝试访问所有 运行 线程(甚至进程),但这种实现(如果可能的话)对我来说似乎很难看 .
自己实现怎么样?
class ApplicationController < ActionController::Base
before_filter :register_request
after_filter :unregister_request
def register_request
$redis.set request.uuid
end
def unregister_request
$redis.unset request.uuid
end
end
你仍然需要弄清楚如何处理异常,因为 after_filters 被跳过(也许将整个代码移动到中间件:在中间件的前阶段,它将 uuid 写入 redis 和在之后的阶段,它删除了密钥)。我敢肯定,还有很多其他方法可以实现这一目标,并且显然可以用您最喜欢的持久性选择替代 redis。
终于恢复了之前基于PID的方法
我实现了这样的东西:
# The Main Process
module MyProcess
def self.run_forked
Process.fork do
SynchProcess.run
end
Process.wait
end
def self.run
RedisClient.set Process.pid # store the PID
... my long process code is here
end
def self.still_alive?(pid)
!!Process.kill(0, pid) rescue false
end
end
# In one thread I can do
MyProcess.run_forked
# In another thread I can do
pid = RedisClient.get
MyProcess.still_alive?(pid) # -> true if the process still running
我可以从 Rails 请求中调用此代码,即使请求进程被重用,子进程也不会被重用,我可以监视子进程的 PID 以查看 Ruby进程还在运行.