简体   繁体   English

在 Scotty / WAI 中完全发送响应后如何运行操作

[英]How to run an action after response has been fully sent in Scotty / WAI

Upon a GET request, my Scotty webapp will run some computation and store its result in a temporary file, which it sends as the response using file .根据 GET 请求,我的 Scotty webapp 将运行一些计算并将其结果存储在一个临时文件中,它使用file作为响应发送。

Now I would like to run some cleanup (ie delete the temporary file) after the file has been sent.现在我想在文件发送进行一些清理(即删除临时文件)。 Scotty does not seem to include a way for doing so. Scotty 似乎没有包含这样做的方法。

Is there is any functionality in WAI for achieving this? WAI 中是否有任何功能可以实现这一点?

wai gives us a function responseStream wai 给了我们一个 function responseStream

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

that constructs a Response out of a StreamingBody , which is actually a functionStreamingBody构造一个Response ,它实际上是一个 function

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

that, given a "write" action, and a "flush" action, finds some bytes somewhere and performs all the writing and flushing.给定一个“写入”动作和一个“刷新”动作,它会在某处找到一些字节并执行所有写入和刷新。

wai also provides us with a ready-made responseFile function: wai 还为我们提供了一个现成的responseFile function:

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

but it doesn't delete the file at the end.但它不会在最后删除文件。 Could we modify it in some way?我们可以通过某种方式对其进行修改吗? It seems that we can, with the help of the responseToStream auxiliary function看来我们可以,借助responseToStream辅助 function

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

that "opens up" an already constructed Response , allowing us to tweak things.这“打开”了一个已经构建的Response ,允许我们调整一些东西。

Like this:像这样:

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)

(Note: the type of streamer is a bit mind-twisting because of all the higher-orderness.) (注意:由于所有的高阶, streamer的类型有点令人费解。)

This solution has the disadvantage that requests have to wait until the file is deleted in order to complete.该解决方案的缺点是请求必须等到文件被删除才能完成。 Another option could be to send filepaths to some kind of concurrent queue that performed the deletions in another thread.另一种选择可能是将文件路径发送到某种并发队列,该队列在另一个线程中执行删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM