How to create a recurring enumerator

I use the enumerator package John Millikin and try to create something roughly equivalent to Data.Enumerator.Binary.enumHandle , except that it connects the socket itself, and then I try to list the resulting handle. The difficulty arises because the connection is unreliable, and I would like it to reconnect and resume enumeration if something went wrong.

I usually expect the Enumerator to be a monad instance of its own meaning, but since it is a type of alias for a function, monadic behavior on it is only a reader of its input step, which seems to be of little use here, I tried to throw something together, which is just kept the Enumerator loop using catchError , but that’s not what I expected and I couldn’t figure out what it was doing, so I was wondering if anyone could suggest a good idiomatic approach to this. I'm fine with just the skeleton of the solution, as there are a lot of details that I omitted.

Any ideas?

+4
source share
2 answers

You may have to write this yourself. I do not think this is predetermined anywhere. However, this is not so difficult:

 enumConnectAgain :: forall b m. MonadIO m => IO Handle -> Enumerator ByteString mb 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 mb -> Iteratee ByteString mb 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 

That should work.

+3
source

From a slightly higher perspective, if you are doing things with sockets, especially potentially unreliable ones, I cannot recommend zeromq> high enough.

0
source

Source: https://habr.com/ru/post/1386250/


All Articles