2

Pipes-2.1.0 パッケージと zeromq3-haskell パッケージを使用して、小さなメッセージ パイプラインを構築しています。フレームのファイナライズを理解するのに問題があることを除けば、すべてうまくいっているようです。

次のフレームでは、2 つのリソースを取得します。zeromq コンテキストと zeromq ソケット。次に、メッセージ (の形式ByteStrings) が zeromq ソケットに公開されるのを待ち続けます。

{-# LANGUAGE RebindableSyntax    #-}
{-# LANGUAGE ScopedTypeVariables #-}

module PipesZeroMQ where

import           Control.Frame
import           Control.IMonad.Do
import           Control.IMonad.Trans
import qualified Control.Monad          as M
import           Data.ByteString        (ByteString)
import           Data.String
import           Prelude                hiding (Monad(..))
import qualified System.ZMQ3            as ZMQ

type Address = String

fromList :: (M.Monad m) => [b] -> Frame b m (M a) (M a) ()
fromList xs = mapMR_ yield xs

publisher :: Address -> Frame Void IO (M ByteString) C ()
publisher addr = do
  c  <- liftU $ ZMQ.init 1
  s  <-liftU $ ZMQ.socket c ZMQ.Pub
  liftU $ ZMQ.bind s addr   
  liftU $ print "Socket open for business!!!"

  foreverR $ do
    bs <- await
    finallyF (ZMQ.close s M.>> ZMQ.term c M.>> print "ZMQ socket closed") $ do
         (liftU $ ZMQ.send s [] bs)
         (liftU (print "Sending message"))

今私がこれを試してみると:

λ> runFrame $ (publisher localAddress) <-< (fromList ["This", "that", "that"] >> close)

私はこれを得る:

"Socket open for business"
"Sending message"
"ZMQ socket closed"
*** Exception: ZMQError { errno = 88, source = "send", message = "Socket operation on non-socket" }

publisher1つだけ受け取った後に確定しBytesStringます。

なぜこうなった?

Pipes-2.1.0 のフレームを使用したファイナライズについて誤解しているのは何ですか?

攻撃を開始した場合、外の木にチャンスはありますか?

4

1 に答える 1

3

関数を書くときに間違いを犯しましたpublisher

foreverR $ do
    bs <- await
    finallyF (ZMQ.close s M.>> ZMQ.term c M.>> print "ZMQ socket closed") $ do
         (liftU $ ZMQ.send s [] bs)
         (liftU (print "Sending message"))

finallyFOUTSIDE をforeverRループの外側に配置したい場合があります。

finallyF (...) $ foreverR $ do
    bs <- await
    liftU $ ZMQ.send s [] bs)
    liftU (print "Sending message")

あなたが書いた方法では、各送信後にファイナライズするため、送信するたびにファイナライズするように指示したことを正確に実行しています。 finallyFラップするアクションが完了すると、ファイナライザーが呼び出されます (成功または失敗の両方で終了)。catchFとにかくループが終了しないため、その場合にも使用できます。

 catchF (...) $ foreverR $ do
    bs <- await
    liftU $ ZMQ.send s [] bs)
    liftU (print "Sending message")

または、ループ内に保持することもできますがcatchF、各送信後にファイナライザーが実行されないように切り替えることができます。

foreverR $ do
    bs <- await
    catchF (ZMQ.close s M.>> ZMQ.term c M.>> print "ZMQ socket closed") $ do
         (liftU $ ZMQ.send s [] bs)
         (liftU (print "Sending message"))

また、パイプに基づく zeroMQ ライブラリの作成を計画している場合は、次のリリースでフレームを通常のモナドに戻すことを計画しているので、私と連絡を取り合ってください。リソースを閉じて再初期化する機能。私に連絡するには、私の gmail.com アドレスとユーザー名 Gabriel439 を使用してください。

于 2012-07-14T00:21:22.153 に答える