Обработка события остановки / перезагрузки контейнера
Есть лифт приложение, запускающее демон ssh в Boot.scala. Вот проблема: когда я бегу container:restart /
в сеансе sbt я получаю адрес в порядке исключения. Теперь два вопроса:
- Это правильный способ запустить зависимый сервис в Boot.scala?
- В любом случае, как можно обработать контейнер: событие остановки?
2 ответа
Я думаю, что Лифт-й способ сделать это с LiftRules.unloadHooks
,
Это не очень хорошо документировано (AFAIK), но если вы посмотрите на исходный код Lift, вы увидите, что когда LiftServlet
является destroy()
ed, функции, определенные в LiftRules.unloadHooks
выполнены.
Вы можете добавить функции к unloadHooks
RulesSeq
с append
или же prepend
метод, в зависимости от того, в каком порядке вы хотите их выполнить. Итак, в вашем bootstrap.liftweb.Boot.boot
метод, вы можете сделать что-то вроде этого:
sshDaemon.start()
LiftRules.unloadHooks.append( () => sshDaemon.stop() )
(Предполагая, что именно так вы начали и остановили своего демона SSH.)
Я не уверен на 100% LiftServlet.destroy()
метод вызывается, когда веб-плагин sbt container:restart
команда запускается - это определяется плагином и его взаимодействием с Jetty, а не Lift - но container:stop
Команда определенно должна сделать свое дело.
Я не знаком с Lift, но этот совет должен работать для любого веб-приложения на основе сервлетов.
Зарегистрировать ServletContextListener
в вашем web.xml
и освободить любые ресурсы в 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()
}