【发布时间】:2015-01-15 10:39:40
【问题描述】:
我想使用 Snap 服务器实现大数据流(双向)。为了探索可能性,我创建了一个示例程序,它有两个端点——阅读和写作。有一个非常简单的内部缓冲区,其中包含一个ByteString,写入到写入端点的任何内容都会出现在读取端点中。 (目前还没有办法终止流,但这对这个目的来说很好。)
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Control.Concurrent.MVar.Lifted
import Control.Monad
import Data.ByteString (ByteString)
import Blaze.ByteString.Builder (Builder, fromByteString)
import Data.Enumerator
import qualified Data.Enumerator.List as E
import Data.Enumerator.Binary (enumFile, iterHandle)
import Snap.Core
import Snap.Http.Server
main :: IO ()
main = do
buf <- newEmptyMVar
quickHttpServe (site buf)
site :: MVar ByteString -> Snap ()
site buf =
route [ ("read", modifyResponse (setBufferingMode False
. setResponseBody (fromBuf buf)))
, ("write", runRequestBody (toBuf buf))
]
fromBuf :: MVar ByteString -> Enumerator Builder IO a
fromBuf buf = E.repeatM (liftM fromByteString $ takeMVar buf)
toBuf :: MVar ByteString -> Iteratee ByteString IO ()
toBuf buf = E.mapM_ (putMVar buf)
然后我在不同的终端运行
curl http://localhost:8000/read >/dev/nul
和
dd if=/dev/zero bs=1M count=100 | \
curl --data-binary @- http://localhost:8000/write
但是写入部分失败,异常逃到顶层:读取的字节太多。这显然是TooManyBytesReadException 的一个实例,但我找不到它被抛出的位置。写入 1MB 之类的较小数据量可以按预期工作。
我的问题是:
- 在哪里/如何修复阅读限制?
- 这种流式传输数据,无需在内存中加载整个 POST 请求吗?如果不是,如何解决?
【问题讨论】:
标签: haskell streaming haskell-snap-framework