Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 使用ResourceT清理资源的正确方法是什么?_Sockets_Haskell_Resources_Conduit - Fatal编程技术网

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

Sockets 使用ResourceT清理资源的正确方法是什么?,sockets,haskell,resources,conduit,Sockets,Haskell,Resources,Conduit,我一直在玩conductextra的UNIX包,它基本上允许使用UNIX域套接字轻松创建服务器,特别是使用 问题是,函数存在后,它不会清理套接字文件,这意味着需要手动清理。下面是一个简单的示例,它基本上创建了一个echo服务器 main :: IO () main = do let settings = serverSettings "foobar.sock" runUnixServer settings (\ad -> (appSource ad) $$ (appSink ad)

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

问题是,函数存在后,它不会清理套接字文件,这意味着需要手动清理。下面是一个简单的示例,它基本上创建了一个echo服务器

main :: IO ()
main = do
  let settings = serverSettings "foobar.sock"
  runUnixServer settings (\ad -> (appSource ad) $$ (appSink ad))
我在谷歌上搜索了一下,发现处理资源的正确方法是使用包。尽管问题是资源中的大多数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))
不过,这种方法存在一个问题,至少就
分配
的文档所述:

这与调用分配然后注册释放操作几乎相同,但这可以正确处理异步异常的屏蔽

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

我提出的第三个也是最后一个解决方案是使用
allocate
,以确保异步异常得到正确处理(我不确定在这种情况下是否真的有必要)


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

在解决
resourcet
问题之前:

  • 在这种情况下不需要
    resourcet
    。您可以使用
    finally
    函数进行类似操作,例如
    runUnixServer设置(\ad->…)
    finally
    removeLink“foobar.sock”
  • 这实际上看起来像是有问题的行为。导管中普遍接受的模式是,如果您分配了一个资源,您负责清理它。我没有编写unix套接字代码,因此作者可能有理由在这里采用不同的方式。但是值得打开一个bug报告
  • 也就是说,您使用
    寄存器
    的初始代码很好。我看到的唯一问题是,如果在创建
    foobar.sock
    之前抛出异常,尽管我的
    finally
    解决方案也易受此影响

    关于allocate vs register的注释与如下代码有关:

    handle <- openFile fp ReadMode
    register $ hClose handle
    

    handle感谢您的快速回复!
    
    handle <- openFile fp ReadMode
    register $ hClose handle