1

http://happstack.com/docs/crashcourse/HappstackState.html

当我运行服务器时,窥视计数器增加

  • 1当我偷看
  • 2 当我不偷看时

有问题的相关代码是:

handlers :: ServerPart Response
handlers = 
    msum [ dir "peek" $ do c <- query PeekCounter
                       ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c)
         , do c <- update (AddCounter 1)
           ok $ toResponse $ "New count is: " ++ show (unCounter c)
         ]

但是,当我将其修改为

handlers :: ServerPart Response
handlers = 
    msum [ dir "peek" $ do c <- query PeekCounter
                           ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c)
         , do ok $ toResponse $ "Stop here."
         , do c <- update (AddCounter 1)
              ok $ toResponse $ "New count is: " ++ show (unCounter c)
         ]

计数器增加

  • 0 当我偷看
  • 1 当我不偷看时

这是预期的行为吗?即使我偷看,感觉好像 msum 中的第二个 monad 正在“泄漏”。

4

1 回答 1

6

由于浏览器每次加载页面时都会请求 /favicon.ico,因此计数会增加额外的时间。由于最后一个路由是包罗万象的,因此对 /favicon.ico 的请求会导致增量。

最简单的解决方法是添加 nullDir 以便它只对 / 进行增量,

handlers :: ServerPart Response
handlers = 
msum [ dir "peek" $ do c <- query PeekCounter
                   ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c)
     , do nullDir
          c <- update (AddCounter 1)
          ok $ toResponse $ "New count is: " ++ show (unCounter c)
     ]

我已经用该更改更新了教程,以避免进一步混淆。为了确认确实是 /favicon.ico 请求搞砸了,我们可以显式处理对 favicon 的请求:

handlers :: ServerPart Response
handlers = 
    msum [ dir "peek" $ do c <- query PeekCounter
                           ok $ toResponse $ "peeked at the count and saw: " ++ show (unCounter c)
         , dir "favicon.ico" $ notFound (toResponse "sorry, no favicon.ico")
         , do c <- update (AddCounter 1)
              ok $ toResponse $ "New count is: " ++ show (unCounter c)
         ]

现在我们看到了预期的行为。

综上所述,Happstack 没有任何问题。浏览器向不是 /peek 的 url 发出 1 或 2 个请求,因此计数增加了一两次。这是应用程序的预期行为。但是,由于人们并不期待 /favicon.ico 请求,它也会导致令人惊讶的行为。所以现在该应用程序已更改为只有两个有效的 url,/peek 和 /。任何其他结果都会导致 404。

感谢您的报告!

于 2011-05-24T17:53:44.113 回答