首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Warp/WAI实现线程安全状态

使用Warp/WAI实现线程安全状态
EN

Stack Overflow用户
提问于 2012-05-04 21:28:44
回答 2查看 1.3K关注 0票数 4

我想写一个web服务器,用wai/warpState monad中存储它的状态。如下所示:

代码语言:javascript
复制
{-# 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

当然,注释行不起作用。其目的是在monad状态中存储一个计数器,并在每次请求时显示其递增的值。

另外,如何获得线程安全性?warp是按顺序还是并行运行我的中间件?

状态有哪些可用选项-除了IORef之外,我还可以在此场景中使用其他选项吗?

我知道State提供了安全性,但似乎wai不允许State。

我只需要一个非常简单的单线程RPC,我可以从其他地方调用它。Haxr包需要单独的web服务器,这是一种过度的杀伤力。查看Calling Haskell from Node.JS -它没有任何建议,所以我使用Wai/Warp和伊森编写了一个简单的服务器。但似乎WAI是为支持并发实现而设计的,所以它使事情变得复杂。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-04 23:47:45

如果您与状态的交互可以通过一个对atomicModifyIORef的调用来表示,那么您就可以使用它,并且不需要显式地序列化对状态的访问。

代码语言:javascript
复制
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))

如果您的交互比较复杂,并且需要强制执行请求的完全序列化,则可以将MVarStateT结合使用。

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2012-05-04 21:37:53

如果它在State monad中,那么它在设计上是线程安全的。不可能对共享状态执行并发IO操作。它要么是threadsafe,要么不能编译。

如果你有真正的并行访问共享状态作为设计的一部分(例如,独立的forkIO线程更新全局计数器),那么你将需要在STM monad (或其他事务屏障)中使用和MVarTVar来确保原子性。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10449819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档