【问题标题】:Handling container stop/reload event处理容器停止/重新加载事件
【发布时间】:2012-02-21 18:55:28
【问题描述】:

一个在 Boot.scala 中启动 ssh 守护程序的 Lift 应用程序。 这是问题所在:当我在 sbt 会话中运行 container:restart / 时,我得到 Address alread in use 异常。 现在有两个问题:

  1. 在 Boot.scala 中启动依赖服务是否正确?
  2. 无论如何如何处理 container:stop 事件?

【问题讨论】:

    标签: scala lift sbt xsbt-web-plugin


    【解决方案1】:

    我不熟悉 Lift,但这个建议应该适用于任何基于 Servlet 的 Web 应用程序。

    web.xml 中注册一个ServletContextListener,并在contextDestroyed 方法中释放所有资源。 (启动应该在contextCreated方法中完成。)

    您可以使用setAttribute / getAttribute 来存储和稍后检索服务器。

    把这一切放在一起:

    import javax.servlet.{ServletContextEvent, ServletContextListener}
    
    
    final class SshListener extends ServletContextListener{
      val attributeKey = "sshServer"
    
      def contextInitialized(sce: ServletContextEvent) {
        val server = new Server()
        server.start()
        sce.getServletContext.setAttribute(attributeKey, server)
      }
    
      def contextDestroyed(sce: ServletContextEvent) {
        Option(sce.getServletContext.getAttribute(attributeKey)).foreach(_.asInstanceOf[Server].stop())
      }
    }
    
    class Server {
      def start()
      def stop()
    }
    

    【讨论】:

      【解决方案2】:

      我认为 Lift-y 的做法是使用 LiftRules.unloadHooks

      没有很好的文档记录 (AFAIK),但是如果您查看 Lift 源代码,您会发现当 LiftServletdestroy()ed 时,会执行 LiftRules.unloadHooks 中定义的函数。

      您可以使用appendprepend 方法将函数添加到unloadHooks RulesSeq,具体取决于您希望它们执行的顺序。因此,在您的bootstrap.liftweb.Boot.boot 方法中,您可能会执行类似的操作这个:

      sshDaemon.start()
      LiftRules.unloadHooks.append( () => sshDaemon.stop() )
      

      (假设这就是您启动和停止 SSH 守护程序的方式。)

      我不能 100% 确定在 sbt web-plugin 的 container:restart 命令运行时会调用 LiftServlet.destroy() 方法 - 这是由插件及其与 Jetty 的交互决定的,而不是由 Lift - 而是 container:stop命令绝对可以解决问题。

      【讨论】:

        猜你喜欢
        • 2013-12-29
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-26
        • 1970-01-01
        相关资源
        最近更新 更多