Rails的关闭挂钩

17
我希望在Rails关闭时运行一些清理代码,这可能吗? 我有几个后台线程(我正在使用jruby并调用java),它们的寿命与进程相同,并且我需要让它们知道如何关闭自己。
谢谢!
3个回答

21

最好使用Ruby的退出处理器,它是一个核心方法:

$ irb
>> at_exit do
?>   puts 'bye...'
>> end
=> #<Proc:0xb79a87e4@(irb):1>
>> exit
bye...
$ 

只要 JRuby 本身具有与底层应用服务器相对应的生命周期,那么您可以将它放在任何至少运行一次的地方。一个好的位置是在最初触发这些后台线程的任何 Ruby 代码片段中注册退出处理程序。 - DigitalRoss
如果它被调用超过一次,退出处理程序将运行超过一次,因此不要调用它30,000次。 :-) - DigitalRoss
@Stuart:你之前有实现过这个吗?如果有,进展如何,放在哪里了? - efleming
感谢DigitalRoss提供的代码提示和Radar提供的正确文件。@efleming在10年的解决方案实施和8年的询问之后,我终于实现了这个功能 :-P - SriramK89

11

在Rails应用程序的上下文中,放置这样一个文件的最佳位置是 config/initializers。在我的应用程序中,我需要在开发或测试环境关闭时刷新Redis / Sidekiq队列。这完美地实现了功能。

config/initializers/at_exit.rb

at_exit do
  begin
    puts 'Flushing Redis...'
    Redis.new.flushall
  rescue => e
    puts "There was an #{e.to_s} while flushing redis..."
  ensure
    puts 'Done Flushing Redis!'
  end
end unless Rails.env.production?

0
请注意,您不能使用Signal.trap,因为它会重新定义已设置的内容。有一个技巧可以调用先前的陷阱:
$prev_trap = Signal.trap("TERM") do
  $prev_trap&.call
  graceful_shutdown
end

然而,Rails 初始化程序在应用服务器启动之前执行,例如,Puma 重新定义了大部分的信号捕获器,丢弃了先前定义的内容。 因此不要使用这种方法,它可能对 webrick 有效,但不适用于生产环境。

因此,唯一合理的选项是已经被推荐的:在初始化程序中使用 at_exit


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接