gpt4 book ai didi

sockets - 使用 ResourceT 清理资源的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-04 11:24:18 26 4
gpt4 key购买 nike

我一直在玩conduit-extra的 UNIX 包,它基本上允许使用 UNIX 域套接字轻松创建服务器,特别是使用 runUnixServer funciton .

问题是该函数存在后并没有清理套接字文件,这意味着它需要手动清理。这是一个简单的示例,它基本上创建了一个回显服务器。

main :: IO ()
main = do
let settings = serverSettings "foobar.sock"
runUnixServer settings (\ad -> (appSource ad) $$ (appSink ad))

我google了一下,发现这里处理资源的正确方法是使用 resourcet 。包裹。虽然问题是资源中的大多数 API 都希望我自己分配资源,但 runUnixSever 的情况并非如此。 ,它不会返回任何东西。

起初我以为我可以使用 register , 注册一个删除文件的函数,比如下面
main :: IO ()
main = runResourceT $ do
register $ removeLink "foobar.sock"
let settings = serverSettings "foobar.sock"
liftIO $ runUnixServer settings (\ad -> (appSource ad) $$ (appSink ad))

但是,这种方法存在一个问题,至少就 allocate 的文档而言。说:

This is almost identical to calling the allocation and then registering the release action, but this properly handles masking of asynchronous exceptions.



这是否意味着 register本身不处理异步异常?如果是这样,当 runUnixServer 产生的处理程序之一时,这可能是个问题吗? (文档说它为每个客户端生成一个线程)引发错误?

我想出的第三个也是最后一个解决方案是使用 allocate ,以确保正确处理异步异常(我不确定在这种情况下是否真的有必要)。
main :: IO ()
main = runResourceT $ do
allocate (return 1) (const $ removeLink "foobar.sock")
let settings = serverSettings "foobar.sock"
liftIO $ runUnixServer settings (\ad -> (appSource ad) $$ (appSink ad))

但这真的是最好的解决方案吗?因为我正在创造一个我永远不会使用的值(value) (return 1)然后使用 const函数在终结器中忽略该值。

最佳答案

在解决 resourcet 之前问题:

  • resourcet在这种情况下不需要。您可以使用 finally类似这样的功能,例如runUnixServer settings (\ad -> ...)终于 removeLink "foobar.sock" .
  • 这实际上看起来像是有问题的行为。管道中普遍接受的模式是,如果您分配资源,则您负责清理它。 unix socket 代码不是我写的,所以作者在这里做的不同可能是有原因的。但值得打开一个错误报告。

  • 也就是说,您的初始代码为 register很好。我看到的唯一问题是是否在 foobar.sock 之前抛出异常已创建,尽管我的 finally解决方案也容易受到影响。

    关于 allocate vs register 的注释与如下所示的代码有关:
    handle <- openFile fp ReadMode
    register $ hClose handle

    此代码容易受到 openFile 之间引发的异步异常的影响。和 register来电。由于您没有像这样分配资源, register很好。

    关于sockets - 使用 ResourceT 清理资源的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23795650/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com