4

私は John Millikin の enumerator パッケージを使用しData.Enumerator.Binary.enumHandleており、ソケット自体を接続し、結果のハンドルを列挙しようとすることを除いて、 とほぼ同等のものを作成しようとしています。問題は、接続が信頼できないという事実によるものです。何か問題が発生した場合は、再接続して列挙を再開したいと考えています。

私は通常、Enumerator が独自の意味のある Monad インスタンスであることを期待しますが、関数の型エイリアスであるため、そのモナド動作は入力ステップの単なるリーダーであり、ここではあまり使用されないようです。を使用して Enumerator をループし続ける何かを一緒に投げようとしましたcatchErrorが、期待どおりに動作せず、何をしているのか理解できませんでした。 . 明らかに省略した詳細がたくさんあるので、ソリューションの骨組みだけで問題ありません。

何か案は?

4

2 に答える 2

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

それはうまくいくはずです。

于 2011-12-14T08:04:11.837 に答える
0

少し高い観点から言えば、ソケット、特に潜在的に信頼性の低いソケットを使用している場合、zeromqを十分に推奨することはできません。

于 2011-12-15T13:21:48.953 に答える