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 の 2 番目のモナドが「漏れている」ように感じます。

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 つのリクエストを行っていたため、カウントが 1 つまたは 2 つ増加しました。これは、アプリケーションの意図した動作でした。しかし、人々は /favicon.ico リクエストを期待していないため、驚くべき動作にもつながります。そのため、アプリは /peek と / の 2 つの有効な URL のみを持つように変更されました。それ以外は 404 になります。

ご報告ありがとうございます!

于 2011-05-24T17:53:44.113 に答える