我正在使用John Millikin的枚举器包,并尝试创建大致相当于Data.Enumerator.Binary.enumHandle
的内容,除了它连接套接字本身,然后尝试枚举生成的句柄。困难来自连接不可靠的事实,如果出现问题,我希望重新连接并重新枚举。
我通常希望Enumerator成为它自己有意义的Monad实例,但由于它是函数的类型别名,因此它上面的monadic行为只是其输入步骤的读者,这在这里似乎没什么用处。我试图将一些东西放在一起,只是使用catchError
循环调整枚举器,但它没有按照我的预期进行,我无法弄清楚它在做什么,所以我想知道是否有人可以建议很好的惯用法。我只是一个解决方案的骨架很好,因为很明显我省略了许多细节。
有什么想法吗?
答案 0 :(得分:3)
你可能必须自己写。我不认为它是在任何地方预定义的。然而,这并不困难:
enumConnectAgain :: forall b m. MonadIO m => IO Handle -> Enumerator ByteString m b
enumConnectAgain open step =
fix $ \again -> do
mh <- liftIO (Ex.try open)
case mh of
Left (ex :: SomeException) -> again
Right h -> loop h step
where
loop :: Handle -> Step ByteString m b -> Iteratee ByteString m b
loop h step@(Continue k) = do
mstr <- liftIO (Ex.try $ B.hGetSome h 1024)
case mstr of
Left (ex :: SomeException) -> enumConnectAgain open step
Right str -> k (Chunks [str]) >>== loop h
loop h step = returnI step
这应该有效。
答案 1 :(得分:0)
从略高的角度来看,如果你正在使用套接字,特别是可能不可靠的套接字,我不能足够推荐zeromq。