在 Scotty / WAI 中完全发送响应后如何 运行 执行操作
How to run an action after response has been fully sent in Scotty / WAI
根据 GET 请求,我的 Scotty 网络应用程序将 运行 进行一些计算并将其结果存储在一个临时文件中,它使用 file
.
作为响应发送
现在我想运行一些清理工作(即删除临时文件)在文件发送后。 Scotty 似乎没有提供这样做的方法。
WAI 中是否有任何功能可以实现这一点?
wai 给了我们一个函数 responseStream
responseStream :: Status -> ResponseHeaders -> StreamingBody -> Response
即构造了一个Response
out of a StreamingBody
,其实就是一个函数
type StreamingBody = (Builder -> IO ()) -> IO () -> IO ()
给定“写入”操作和“刷新”操作,在某处找到一些字节并执行所有写入和刷新操作。
wai还为我们提供了一个ready-maderesponseFile
功能:
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
的类型有点mind-twisting,因为全部都是higher-orderness。)
此解决方案的缺点是请求必须等到文件被删除才能完成。另一种选择是将文件路径发送到某种 concurrent queue 在另一个线程中执行删除操作。
根据 GET 请求,我的 Scotty 网络应用程序将 运行 进行一些计算并将其结果存储在一个临时文件中,它使用 file
.
现在我想运行一些清理工作(即删除临时文件)在文件发送后。 Scotty 似乎没有提供这样做的方法。
WAI 中是否有任何功能可以实现这一点?
wai 给了我们一个函数 responseStream
responseStream :: Status -> ResponseHeaders -> StreamingBody -> Response
即构造了一个Response
out of a StreamingBody
,其实就是一个函数
type StreamingBody = (Builder -> IO ()) -> IO () -> IO ()
给定“写入”操作和“刷新”操作,在某处找到一些字节并执行所有写入和刷新操作。
wai还为我们提供了一个ready-maderesponseFile
功能:
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
的类型有点mind-twisting,因为全部都是higher-orderness。)
此解决方案的缺点是请求必须等到文件被删除才能完成。另一种选择是将文件路径发送到某种 concurrent queue 在另一个线程中执行删除操作。