4

/を使用してその状態をStateモナドに格納するWebサーバーを作成したいと思います。このようなもの:waiwarp

{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.Wai.Handler.Warp
import Network.HTTP.Types
import Control.Monad.State
import Data.ByteString.Lazy.Char8

main = run 3000 app

text x = responseLBS
        status200
        [("Content-Type", "text/plain")]
    x

app req = return $ text "Hello World"

app1 req = modify (+1) >>= return . text . pack . show

-- main1 = runStateT (run 3000 app1) 0

もちろん、コメント行は機能しません。目的は、カウンターを状態モナドに格納し、要求ごとにその増加する値を表示することです。

また、スレッドセーフを取得するにはどうすればよいですか?ワープはミドルウェアを順次または並行して実行しますか?

IORef州で利用できるオプションは何ですか?このシナリオで使用できる以外に何かありますか?

州が安全を提供していることは理解していますが、ワイは州を許可していないようです。

必要なのは、他の場所から呼び出すことができる非常に単純なシングルスレッドRPCだけです。Haxrパッケージには別のWebサーバーが必要ですが、これはやり過ぎです。Node.JSからのHaskellの呼び出しを参照してください-提案がなかったので、Wai/WarpとAesonを使用して単純なサーバーを作成しました。しかし、WAIは同時実装をサポートするように設計されているため、事態は複雑になっているようです。

4

2 に答える 2

5

モナド内にある場合は、State設計上スレッドセーフです。可能な共有状態への同時IOアクションはありません。スレッドセーフであるか、コンパイルされません。

デザインの一部として共有状態に真に並列アクセスできる場合(つまり、グローバルカウンターを更新する個別のforkIOスレッド)、アトミック性を確保するためにモナドMVar(またはその他のトランザクションバリア)を使用する必要があります。TVarSTM

于 2012-05-04T13:37:52.660 に答える
3

状態との相互作用をへの1回の呼び出しで表現できるatomicModifyIORef場合は、それを使用でき、状態へのアクセスを明示的にシリアル化する必要はありません。

import Data.IORef

main = do state <- newIORef 42
          run 3000 (app' state)

app' :: IORef Int -> Application
app' ref req
   = return . text . pack . show `liftM` atomicModifyIORef ref (\st -> (st + 1, st + 1))

対話がより複雑で、要求の完全なシリアル化を強制する必要がある場合は、MVarをと組み合わせて使用​​できますStateT

import Control.Concurrent.MVar
import Control.Monad.State.Strict

main = do state <- newMVar 42
          run 3000 (app' state)

app' :: MVar Int -> Application
app' ref request
   = do state <- takeMVar ref
        (response, newState) <- runStateT (application request) state
        putMVar newState --TODO: ensure putMVar happens even if an exception is thrown
        return response

application :: Request -> StateT Int (ResourceT IO) Response
application request = modify (+1) >>= return . text . pack . show
于 2012-05-04T15:47:44.823 に答える