我正在使用Sinatra设计一个web服务,我需要在服务启动时执行某些操作,并在服务器停止时执行其他一些操作。
如何注册这些操作以与sinatra完全集成?
谢谢。
发布于 2012-10-04 19:03:20
答案取决于您需要如何执行操作。它们是否需要为每个ruby进程运行,还是只需要为服务运行一次。我认为这是所有服务的一次,在最新的情况下:
您可能想在Sinatra应用程序启动之前运行一些代码,但这并不是您所期望的行为。稍后我会解释为什么。解决方法是在sinatra类之前添加代码,如
require "sinatra"
puts "Starting"
get "/" do
...
end你也可以在你的config.ru中添加一些代码,顺便说一句,也会有同样的效果,但我不知道哪一个更丑。
为什么这是错误的?因为当您托管您的web服务时,许多web服务器实例将被触发,并且每个实例都将执行puts方法或您的“启动”代码。这是正确的,当你想初始化你的应用程序实例本地的东西,比如数据库连接,而不是初始化所有共享的东西。
关于代码在其末尾触发,你不能(或者你可以用一些非常丑陋的变通方法,但你会以与开始时相同的问题结束)。
因此,处理on和off操作的最好方法是将其包装在触发服务的任务中。
为了阻止它
你可以直接从ruby启动你的应用服务器,就像我在https://github.com/TactilizeTeam/photograph/blob/master/bin/photograph中做的那样,你可以把这些打包到一个rake任务中。
通过这种方式,您可以轻松地在启动服务之前添加一些要运行的代码,同时仍然将其保留在单个任务中。通过一些管道,我猜你可以启动多个瘦实例,然后允许你启动你的瘦实例集群,并且仍然有一个任务可以依赖。
我想说的是,向SIGINT信号添加一个处理程序可以让您在退出之前运行一些代码。有关如何做到这一点,请参阅http://www.ruby-doc.org/core-1.9.3/Signal.html。您可能想检查Thin是否已经为该信号注册了一个陷阱,我不确定这是在库中还是在用于启动thin ($PATH中的"thin“可执行文件)的脚本中处理的。
另一种处理退出的方法是有一个看门狗进程,该进程检查集群是否正在运行,如果没有更多的实例正在运行,则可以确保停止代码正在运行。
https://stackoverflow.com/questions/12724066
复制相似问题