Request, replyパターン

途中途中で更新していく。

前回のhello <-> world なパターンは絵にするとこんな感じ。最も単純かつよく使う Request/Reply パターンと呼ぶそうな。

その前に、衝撃を受けたので書いとく

  • zmq_ctx_new()で生成したコンテキストはスレッドセーフ
  • zmq_socket()で作ったソケットはスレッドアンセーフ

REQタイプ

本の説明はいきなり last-peer とか fair queue とか出てきて混乱したんだけど、実は単純な話で zmq ではソケットタイプによって使用方法にある程度縛りを設けて、通信をパターン化しているらしい。、rfc読んだら一発だった。
https://rfc.zeromq.org/spec:28/REQREP/

ZMQ_REQタイプはlock-step round-robin algorithmでリクエスト送信、そのリプライの受信を行う。クライアント側。単純なモデルで信頼性はそれほど必要としない、という前提。

  • 任意数のREP or ROUTER に接続できる。
  • 一度に1メッセージずつ送信-> 返信するモデル

送信パケットは

  • 空フレームがデリミタとして追加される(? まだいまいちイメージできてないがダムフレームで送るのかな)
  • 1つ以上のデータフレームでメッセージが構成される
  • 相手がいないとかで送信できないときは、ブロックするかエラーを返す
  • 送信できなかったメッセージも破棄されない

返信パケットは

  • last-peer(つまりREQを送ったやつ)から到着したメッセージのみ受理
    • それ以外のhostからのメッセージはしれっと捨てる

ZMQ_REP はいわゆるfair queue。つまり小さいほうから詰め込んでいく考え方。WFQじゃないのか。

REPタイプ

REQの受け側。リクエスト受信、そのリプライの送信を行う。

  • 任意個のREQ or DEALER ピアに接続できる
  • メッセージをフィルタや改変しない
  • 一度に1メッセージずつ

受信(リクエスト)パケットは

  • アドレスエンベロープは0以上のフレームからなりそれぞれが1つの識別子を持つ
  • 空フレームがデリミタ
  • 1つ以上のデータフレームでメッセージが構成される

受信パケットは

  • fair-queueingで到着メッセージを受信
  • アドレスエンベロープとかデリミタは削除してくれる
  • アプリケーションには残りの実データが送られる

返信パケットは

  • アプリケーションからの呼び出されて指定されるのを待つ
  • アドレスエンベロープやらデリミタが追加される
  • 発信元に送り返される
  • 発信元が死んでいたりしたら、しれっと捨てるか、エラーを返す。

ついでなのでROUTER

REPの非同期版。DEALERクライアントとお話しするサーバのベースになることが多い。
明示的にアドレス使って、複数のピアと通信できる。

  • 任意個のREQ, DEALER, ROUTERと接続できる
  • 接続したピアに対して 1つのダブルキューを管理する

うーむ、ダブルキューてなに?
あー、理解。送信・受信、両方向キューですね。

  • 自発的に送信するときも、リクエストもらうときも ダブルキューを確保する。
    • 送信キューは接続がなくても破棄されない
    • 受信キューは接続が切れたら破棄。
  • 一意の "identity" binary string(?)とやらで各ダブルキューを選択
  • Identity metadata property(?)とやらでピアが名乗る(識別される)ことが可能(なんのこっちゃい)
  • 送受信キューサイズは実行時にリミットを与えられる

受信メッセージは

  • fair queueing
  • 到着メッセージは発信元ダブルキューの識別子が入ったフレームが最初に入る

送信メッセージは

  • 送信メッセージの最初のフレームを破棄してこれをダブルキューの識別子とする- 送信キューに空きがあればそこに入れる
  • キューがない、または空きがなければ、しれっと捨てるかエラー(設定による)
  • ブロックしない

さらについでなのでDEALER