【问题标题】:Can I stop Sinatra from within a Sinatra application?我可以从 Sinatra 应用程序中停止 Sinatra 吗?
【发布时间】:2013-10-01 04:43:12
【问题描述】:

我想知道如何以编程方式从应用程序本身退出 Sinatra 应用程序。 (还有另一个关于从应用程序外部停止它的 SO 线程。)

我想使用 Sinatra 作为一种接收控制和配置命令的方式,而我的应用程序执行与 Sinatra 无关的事情。我希望控制命令之一是“退出”。 Ruby 的“退出”方法似乎只是导致 Sinatra 恢复和恢复。我在 base.rb 中发现了这一点,我认为这证实了这一点:

at_exit { Application.run! if $!.nil? && Application.run? }

到目前为止,我发现的唯一方法是调用 Ruby 的 exit! 方法,但这绕过了 exit 钩子,并不是一个非常干净的解决方案。

有没有办法以编程方式告诉 Sinatra 停止?

【问题讨论】:

  • 老实说,我不记得 8 年前当我发布这个问题时我需要什么。我想如果满足某些外部条件,我想终止。我认为@bigtunacan 的方法是(不幸的是,因为我不太喜欢猴子补丁)最好的方法。我可以启动一个线程来进行检查并在必要时调用exit!。 (续)
  • ...我猜除了 Sinatra 之外,这将绕过所有退出钩子,我希望避免这种情况。

标签: ruby sinatra exit


【解决方案1】:

Sinatra::Base::quit! 或其别名 ::stop! 是您要查找的内容:

require 'sinatra'

get '/quit' do
  self.class.quit!
end

get '/stop' do
  self.class.stop!
end

【讨论】:

  • 感谢您的建议。正如问题中提到的,我需要从服务器内部调用它,而不是对客户端可用。
【解决方案2】:

为什么不直接抛出异常呢?这意味着 $! 不是 nil,所以 at_exit 处理程序不会重新启动 Sinatra。

一个简单的方法就是运行failraise。也可以发消息,比如fail "Exiting due to x"

【讨论】:

  • 谢谢,这可行,但会导致在启动 Sinatra 的终端中输出错误,并且该输出与实际错误导致的输出区分开来并非易事。
【解决方案3】:

我使用了以下代码:

# Exit 'correctly'
get '/exit' do
  # /exit causes:
  # 15:20:24 web.1  | Damn!
  # 15:20:24 web.1  | exited with code 1
  Process.kill('TERM', Process.pid)
end

# Just terminate
get '/fail' do
  Process.kill('KILL', Process.pid)
end

看看at_exit in config.ru 它适用于 TERM 信号:

at_exit do
  puts 'Damn!'
  exit false
end

完整的例子是here

干杯。

【讨论】:

  • 这与调用exit!的行为是否相同?
【解决方案4】:

这与 Sinatra 的本质背道而驰,但这只是 Ruby,因此您可以通过开放类/猴子补丁轻松地做到这一点。

只需重新打开 base.rb at_exit 方法并覆盖 Application.run! 行为。

【讨论】:

    猜你喜欢
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    相关资源
    最近更新 更多