Haskell仆人和流媒体 [英] Haskell Servant and streaming
问题描述
我试图向我的 servant
服务器添加一项功能,该服务器将从Amazon S3获取文件并将其传回给用户。
由于文件可能很大,我不想在本地下载它们,然后将它们提供给客户端,我宁愿将它们直接从S3传输到客户端。
我使用 Amazonka
来处理S3所做的事情,并且我可以将S3文件的流作为 Conduit
汇。
但现在我不知道如何从 Sink
到 EitherT ServantErr IO a
。
任何人都可以向我解释如何做或者向我展示如何完成它的一些示例?
仆人中没有任何东西可以做到这一点,但所有需要的部分都可用。
$ b
在我们开始之前,我猜如果你可以流到一个宿,这意味着你有一个源( gorsBody
of < a href =http://haddock.stackage.org/lts-4.2/amazonka-s3-1.3 .7 / Network-AWS-S3-GetObject.html#t:GetObjectResponserel =nofollow noreferrer> GetObjectResponse
是 RsBody
,这是一个来源)
首先,Servant为我们提供了添加对新返回类型支持的可能性,创建一个新的 HasServer
,所以我们可以为 EitherT ServantErr IO(Source ...)
提供服务stream。
要创建该实例,我们必须实现 route :: Proxy layout - >服务器布局 - > RoutingApplication
。 服务器布局
,在这种情况下,仅表示 EitherT ServantErr IO布局
,布局
是我们想要服务的源,所以它是返回一个源的函数(并且可能会因HTTP错误而失败)。
我们必须返回一个 RoutingApplication
,它是(继续样式)一个函数,它接受 Request
并返回一个 RouteResult Response
,这意味着无法匹配的路由错误或响应。
Request 和
Response
都是标准wai,而不是Servant,因此我们现在可以查看生态系统的其余部分以查找如何实现它。
幸运的是,我们不必走得太远: Network.Wai.Conduit
包含我们需要的内容要实现 route
函数: responseSource
需要一个状态值,一些响应头文件和源文件,并给你一个 Response
。
所以,这是相当多的工作要做,但我们需要的东西就在那里。查看实例源代码 HasServer *(Get ...)
可能会有所帮助。
I am trying to add a functionality to my servant
server that would get a file from Amazon S3 and stream it back to the user.
Because files can be big I don't want to download them locally and then serve them to clients, I'd rather prefer to stream them directly from S3 to clients.
I use Amazonka
for what I do with S3 and I can get a stream for an S3 file as a Conduit
sink.
But now I don't know how to get from Sink
to EitherT ServantErr IO a
.
Can anyone explain me how to do it or show me some example of how it can be done?
The is nothing in Servant to do this out of the box, however all the needed parts are available.
Before we begin, I guess that if you can stream to a Sink, that means you have a source (the gorsBody
of GetObjectResponse
is a RsBody
, which is a Source)
First of all, Servant provides us with the possibility to add support for new return types, by creating a new instance of HasServer
, so we could serve a EitherT ServantErr IO (Source ...)
and have it stream.
To create that instance, we must implement route :: Proxy layout -> Server layout -> RoutingApplication
. Server layout
, in this case, just means EitherT ServantErr IO layout
, layout
being the source we want to server, so it's the function that returns a source (and may fail with an HTTP error).
We have to return a RoutingApplication
, which is (in continuation style) a function that takes a Request
and returns a RouteResult Response
, which means either an unmatched route error, or a response. Both Request
and Response
are standard wai, not Servant, so we can now look at the rest of the ecosystem to find how to implement it.
Fortunately, we don't have to go far: Network.Wai.Conduit
contains just what we need to implement the route
function: responseSource
takes a status value, some response headers and your source and gives you a Response
.
So, that is quite a lot of work to do, but everything we need is there. Looking a the source of the instance HasServer * (Get ...)
might help.
这篇关于Haskell仆人和流媒体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!