【问题标题】:Shutdown hook for RailsRails 的关闭钩子
【发布时间】:2009-10-22 23:24:16
【问题描述】:

我想在 Rails 关闭时运行一些清理代码 - 这可能吗?我的情况是我在后台有一些线程(我正在使用 jruby 并调用 java),这些线程在进程的生命周期中存在,我需要让他们知道自己关闭

谢谢!

【问题讨论】:

    标签: ruby-on-rails jruby


    【解决方案1】:

    可能应该只使用 Ruby 退出处理程序,它是一个内核方法:

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

    【讨论】:

    • 只要 JRuby 本身有一个对应于底层应用服务器的生命周期,那么你可以把它放在任何可以运行至少一次的地方。一个好的地方是在任何一段 Ruby 代码首先触发这些后台线程时注册退出处理程序。
    • (如果它被多次调用,那么退出处理程序将运行多次,所以不要调用它 30,000 次。:-)
    • @Stuart:你有没有实现过这个?如果是这样,它是怎么去的?你把它放在哪里了?
    • 感谢 DigitalRoss 的代码提示和 Radar 的正确文件。 @efleming 在提供解决方案 10 年并询问了 8 年之后,我实现了这一点:-P
    【解决方案2】:

    在 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?
    

    【讨论】:

      【解决方案3】:

      请注意,您不得使用 Signal.trap,因为它确实重新定义了设置。调用前一个陷阱有一个技巧:

      $prev_trap = Signal.trap("TERM") do
        $prev_trap&.call
        graceful_shutdown
      end
      

      但是 Rails 初始化器在应用服务器启动之前执行,例如Puma 重新定义了大多数信号陷阱,抛弃了定义的内容。 因此不要使用它,它可能适用于 webrick 但不适用于生产环境ální。

      所以唯一合理的选择是人们已经推荐的:at_exit in a initializer。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-27
        • 1970-01-01
        • 2023-03-19
        • 2019-10-22
        • 1970-01-01
        • 2020-04-24
        • 2012-10-10
        • 2020-03-31
        相关资源
        最近更新 更多