Skip to content

Instantly share code, notes, and snippets.

@kmaehashi
Last active December 13, 2015 17:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmaehashi/ab51ae3232e2bb092ad8 to your computer and use it in GitHub Desktop.
Save kmaehashi/ab51ae3232e2bb092ad8 to your computer and use it in GitHub Desktop.
Jubatus クライアントで msgpack-rpc 接続を切断する方法

Jubatus クライアントから TCP 接続を切る方法

どうやってクライアント側からコネクションを close させるか検討する。

背景

  • Jubatus サーバは、アイドル状態が 10 秒続くと TCP 接続を自動切断するが、クライアントは切断を検知できないため、クライアントが次のリクエストを投げるタイミングでタイムアウトエラーが発生する

  • このタイムアウト機能は本家 MsgPack-RPC サーバにはなく、 jubatus-msgpack-rpc で独自に実装したもの。

  • 2013/02/12 の打合せで、以下の方針が決まった

    • 「タイムアウト機能が不要であれば --timeout 0 を利用すること」を FAQ に記述する
    • --timeout 0 を使う場合、クライアントが自らコネクションを close できる機能が必要。だが、現状ではできない

アイディア

  • クライアントクラス内の mprpc クライアントのフィールドを private から public に変更して直接 close() を呼べるようにする

    • pros
      • mprpc クライアントの全機能にアクセス可能
    • cons
      • マナーが悪い
  • mprpc クライアントのインスタンスの参照を返す get_client() メソッドをクライアントクラスに用意する

    • pros
      • mprpc クライアントの全機能にアクセス可能
    • cons
      • get_client というメソッドが IDL で定義されていた時にどうするか考える必要あり
  • close() メソッドをクライアントクラスに用意 (proxyパターン的な方法)

    • pros
      • 各言語でメソッド名が統一できる
      • マナーは最良
    • cons:
      • mprpc クライアントの一部の機能にしかアクセスできない
      • 同じように内部インスタンスに触りたいケースが発生する度に、クライアントクラスを再生成する必要あり
      • close というメソッドが IDL で定義されていた時にどうするか考える必要あり

個人的には「get_client() メソッドを用意する」案が筋が良いのではと思う.

現状整理

まとめると、close / タイムアウト値の変更を行うためには:

  • Python は、現状のままでも可能
  • Java, Ruby は Jubatus クライアントの改造が必要
  • C++ は jubatus-msgpack-rpc と Jubatus クライアントの改造が必要

である。


  • C++

    • 現状: mprpc クライアントが private なので close 不可
    • mprpc クライアントの機能: get_timeout(), set_timeout(), イベントループ
      • TCP 接続を close するインタフェースは無い (jubatus-msgpack-rpc を改造する必要あり)
  • Java

    • 現状: mprpc クライアントが private なので close 不可
    • mprpc クライアントの機能: close(), getRequestTimeout(), setRequestTimeout(), イベントループ など
  • Python

    • 現状: jubaClient.client.close() など内部の mprpc クライアント(client)を直接触れば close 可能
    • mprpc クライアントの機能: close() メソッド, _timeout フィールド, イベントループ など
  • Ruby

    • 現状: mprpc クライアント (@cli) にアクセサが無いので close 不可
    • mprpc クライアントの提供する機能: close() メソッド, timeout フィールド, イベントループ など
@suma
Copy link

suma commented Feb 18, 2013

ちなみにC++版はデストラクタでcloseされます!

@suma
Copy link

suma commented Feb 20, 2013

TCP 接続を close するインタフェースは無い (jubatus-msgpack-rpc を改造する必要あり)

C++のjubatus-msgpack-rpcの開発工数が多く、そしてこれの優先順位が低ければ、デストラクタでcloseを呼ばせること(現状のまま)としても良いように思います。GCが介在して呼ばれないわけでもありませんし。

@y-oda-oni-juba
Copy link

C++ jubatus-msgpack-rpc の開発工数は問題ないと思います。これ↓を追加すれば OK です。

https://gist.github.com/y-oda-oni-juba/5023479

なお、現状のままでも困らないという点には同意です。

@kmaehashi
Copy link
Author

エラー発生後の自動再接続について、追加で調査中です。

@kmaehashi
Copy link
Author

タイムアウトエラー発生後の自動再接続の挙動

  • C++, Python, Ruby: 例外発生。ただし、もう一度呼ぶとサーバに再接続される
  • Java: 透過的に再接続される (例外発生しない)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment