1

我对以正确顺序开始的 scotty web 应用程序和 mongodb 服务有一个愚蠢的问题。我先使用 systemd 启动 mongodb,然后再启动 scotty web 应用程序。由于某种原因它不起作用。该应用程序从 mongodb 驱动程序中出错,connect: does not exist (Connection refused)这意味着连接尚未准备好。

所以我的问题。如何以 0.5 秒的间隔测试连接可用性 3 次,然后才出错?

这是应用程序的主要功能

main :: IO ()
main = do
  pool <- createPool (runIOE $ connect $ host "127.0.0.1") close 1 300 5
  clearSessions pool
  let r = \x -> runReaderT x pool
  scottyT 3000 r r basal

basal :: ScottyD ()
basal = do
  middleware $ staticPolicy (noDots >-> addBase "static")
  notFound $ runSession
  routes

尽管应用服务是在 mongodb 服务之后排序的,但在应用启动期间与 mongodb 的连接仍然不可用。所以我得到了上面提到的错误。这是 systemd 服务文件,以避免有关正确服务顺序的问题。

[Unit]
Description=Basal Web Application
Requires=mongodb.service
After=mongodb.service iptables.service network-online.target

[Service]
User=http
Group=http
WorkingDirectory=/srv/http/basal/
ExecStart=/srv/http/basal/bin/basal
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

我不知道为什么在正确的服务顺序下无法连接到 mongodb。所以我想用 0.5 秒的延迟用 haskell 代码探测连接可用性三次,然后出错。我该怎么做?

谢谢。

4

1 回答 1

3

我猜从您正在使用的功能来看,您正在使用类似mongoDB 1.5.0.

在这里,在monad 中connect返回一些东西,它是.IOEErrorTIOErrorIO

所以最好的方法是使用ErrorT提供的重试机制。由于它是 的一个实例,如果我们不关心检查特定错误MonadPlus,我们可以使用:mplus

retryConnect :: Int -> Int -> Host -> IOE Pipe
retryConnect retries delayInMicroseconds host
    | retries > 0 =
            connect host `mplus`
                (liftIO (threadDelay delayInMicroseconds) >>
                   retryConnect (retries - 1) delayInMicroseconds host)
    | otherwise = connect host

threadDelay来自Control.Concurrent)。

然后替换connectretryConnect 2 500000,它会在第一次失败后重试两次,间隔为 500,000 微秒(即 0.5 秒)。

如果您确实想检查特定错误,请catchError改用并检查错误以决定是吞下它还是重新抛出它。

于 2014-07-10T19:31:29.393 回答