2

根据 GET 请求,我的 Scotty webapp 将运行一些计算并将其结果存储在一个临时文件中,它使用file.

现在我想在文件发送进行一些清理(即删除临时文件) 。Scotty 似乎没有包含这样做的方法。

WAI 中是否有任何功能可以实现这一点?

4

1 回答 1

1

wai 给了我们一个函数responseStream

responseStream :: Status -> ResponseHeaders -> StreamingBody -> Response

构造 a Responseout of a StreamingBody,这实际上是一个函数

type StreamingBody = (Builder -> IO ()) -> IO () -> IO ()

给定一个“写入”动作和一个“刷新”动作,它会在某处找到一些字节并执行所有写入和刷新。

wai 还为我们提供了一个现成的responseFile功能:

responseFile :: Status -> ResponseHeaders -> FilePath -> Maybe FilePart -> Response

但它不会在最后删除文件。我们可以通过某种方式对其进行修改吗?看来我们可以,借助responseToStream辅助函数

responseToStream :: Response -> (Status, ResponseHeaders, (StreamingBody -> IO a) -> IO a)

这“打开”了一个已经构建的Response,允许我们调整一些东西。

像这样:

import Network.Wai
import Network.HTTP.Types.Status (status200)
import System.Directory (removeFile)

responseFileDeleting' :: FilePath -> Response
responseFileDeleting' filepath = 
    let (status,header,streamer) = 
            responseToStream $ responseFile status200 [] filepath Nothing
     in responseStream status header (\write flush ->
             -- this would be a good place to put a bracket, if needed
             do streamer (\body -> body write flush)
                removeFile filepath)

(注意:streamer由于所有的高阶,类型有点令人费解。)

该解决方案的缺点是请求必须等到文件被删除才能完成。另一种选择可能是将文件路径发送到某种并发 队列,该队列在另一个线程中执行删除。

于 2020-08-08T11:41:27.867 回答