【问题标题】:How do I cause a WARP server to terminate?如何使 WARP 服务器终止?
【发布时间】:2017-09-05 10:33:10
【问题描述】:

我有一个 HTTP 应用程序服务器,在某些条件下处理某个请求时需要退出(以便由主管重新启动)。

给定一个主要的喜欢:

import Network.Wai.Handler.Warp (run)

main :: IO ()
main = do
  config <- readConfig
  run (portNumber config) (makeApp config)

还有一个类似的处理程序:

livenessServer1 :: UTCTime -> FilePath -> Server LivenessProbeAPI1
livenessServer1 initialModificationTime monitorPath = do
  mtime <- liftIO $ getModificationTime monitorPath
  case mtime == initialModificationTime of
    True  -> return $ Liveness initialModificationTime mtime
    False -> throwError $ err500 { errBody = "File modified." }

在发送 500 响应后如何使流程结束?

【问题讨论】:

  • 使用 error "Oops!" 之类的东西来抛出错误,因为默认情况下 Warp 不处理错误。

标签: haskell haskell-warp


【解决方案1】:

我现在正在使用手机,因此无法为您输入确切的代码。但是基本的想法是给你的 Warp 线程一个异步异常。这听起来可能很复杂,但最简单的方法是使用异步库中的竞赛函数。像这样的:

toExitVar <- newEmptyMVar
race warp (takeMVar toExitVar)

然后在您的处理程序中,当您希望 Warp 退出时:

putMVar toExitVar ()

编辑一天后,我又回到了我的电脑前,这是一个完整的示例:

#!/usr/bin/env stack
-- stack --resolver lts-9.0 script
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types
import Control.Concurrent.Async
import Control.Concurrent.MVar

main :: IO ()
main = do
toDie <- newEmptyMVar
race_ (takeMVar toDie) $ run 3000 $ \req send ->
    if pathInfo req == ["die"]
    then do
        putMVar toDie ()
        send $ responseLBS status200 [] "Goodbye!"
    else send $ responseLBS status200 [] "Still alive!"

【讨论】:

  • 谢谢。这看起来很有趣,但我的 Haskell 能力太有限,无法真正理解它的含义或如何将它集成到我的应用程序中。
  • 我已经添加了一个完整的示例,因为我回到了我的电脑前。
  • 如果race_warp 线程到达send 之前杀死它会发生什么? warp 是否保证在这种情况下仍会发送响应?
  • 不,没有这样的保证。如果你想要优雅的关闭,你可以自己创建监听套接字然后关闭它,但你仍然需要弄清楚何时是退出进程的正确时间。
  • 您如何确定合适的时间?显然,不能绝对保证对等方已收到发送的数据——但至少可以等待本地发送缓冲区清空。 Wai/Warp 会公开这些信息吗?
猜你喜欢
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 2022-07-30
相关资源
最近更新 更多