Skip to content

Instantly share code, notes, and snippets.

@rimms
Last active August 29, 2015 13:56
Show Gist options
  • Save rimms/9107551 to your computer and use it in GitHub Desktop.
Save rimms/9107551 to your computer and use it in GitHub Desktop.
Proxyの現状の動作と仕様変更(案)

現状の動作

Proxy-Server間のタイムアウト

  • Proxy から Server の通信処理(全体)が、 interconnect_timeout を超えると、 msgpack::rpc::TIMEOUT_ERROR を返却する。
    • ある Server との通信でタイムアウトが発生したというのは、異なる意味付け。「Proxy 処理(転送手続き)のタイムアウト」という意味になっている。
    • 本タイムアウトが発生した場合は、結果受付中の通信をすべてキャンセルする。

実装

  • セッション(通信)のタイムアウトは無効化。
  • async_task のタイマーのみが稼働しており、Proxy からの通信全体でタイムアウトが管理される。
  • async_task のタイマーがタイムアウトした場合、処理中の通信をキャンセルし、 msgpack::rpc::TIMEOUT_ERROR を返却する。

Serverからの例外検知時

  • Server から例外が返却された場合(通信例外も含む)には、何もしない。

実装

  • RPC通信時に例外が発生すると、jubaexception を継承した例外を投げる。
  • async_task 内では、例外を補足し、errors_ という変数に詰めるが、使ってない。

結果の集約

  • 通信結果(Serverからの例外返却 以外)の通信数に応じて、以下のように振る舞う。
    • 通信結果数 == 0 のときは 空のオブジェクトを返却
    • 通信結果数 == 1 または アグリゲートなし の場合は、得られた結果の先頭を返却
    • 通信結果数 => 2 のときは アグリゲート を実行し、返却
  • Serverからの例外検知時 の状況と踏まえると、以下のようになる。
    • 正常件数 = 2, 例外 = 0 の場合は、結果を集約して返却
    • 正常件数 = 1, 例外 = 1 の場合は、正常な通信の結果をそのまま返却
    • 正常件数 = 0, 例外 = 2 の場合は、空のオブジェクト

実装

  • すべての通信が終わった段階で、結果を集約する。
  • 得られた通信結果の数により、振る舞いが異なる。

Issue の状況解析

  • #586
    • 前述の Proxy-Server間のタイムアウト のとおり、通信の成功数にかかわらず、タイムアウトエラーが返却された。
  • #503
    • 何らかのエラーとなったが、 results_.size() == 0 のため、空の結果が返却された。

問題点

現状を踏まえた、解決すべき問題点は以下。

  • Proxy-Server間の通信の異常/通信結果が分らない。
    • Serverからの例外が返却された場合に、Proxy は ログ出力、クライアントへの返却を行わない。ただし、クライアントは空のオブジェクトが返却されたときだけ、何かあったことが 推測 できる。
    • タイムアウト発生時も同様に、どの通信がキャンセルされたのかが分らない。
  • 処理タイムアウトが発生した場合には、転送したRPCの成否に関係なく、RPCエラーが返却される。
    • 成功した通信があるのにもかかわらず、結果が返却されない。
    • 特定の通信のタイムアウトの発生へ、すべての転送処理の結果が丸められている。

以下は、個人的な意見。

  • タイムアウトに関して、現状の実装は 直感的 ではない。外部から見た時の意味は変わらない。
    • 直感的には、Proxy-Server間の通信のタイムアウトを想像するが、通信処理(全体)のタイムアウトである。
    • 通信を そのまま 転送(冗長化)するというほうがシンプルで分かりやすい気がする。

仕様変更(案)

タイムアウト時の振る舞いの変更

  • タイムアウト発生時は、Serverからの例外検知時と同様に、正常に通信できなかったケースの一つと同じ振る舞いとする。
    • タイムアウトした(させた)場合には、すぐにエラーを返却するのではなく、結果を集約してから返却する。

実装レベルでは、修正案は 以下の 2つ。外部から見た動きは同じであるため、いずれでも良いが、個人的な意見としては、直感的な動きとするためには、案1 が良いと考える。

  1. 通信処理全体 ではなく、それぞれの Server との通信の間にタイムアウトを設け、タイムアウトを個別の通信毎に検知する。
  2. 通信処理全体 でタイムアウトを管理(現状と同じ)し、キャンセルした通信を タイムアウトした通信 として、扱う。

Serverからの例外検知時の振る舞い変更

ログ出力

  • いかなるエラーであれ、以下の情報をログに出力する。
    • 通信先(IPアドレス、ポート番号) と エラー内容

クライアントへの通知

以下の2つの方針が考えられる。クライアント側で検知しても、その後、アプリケーション側/運用側でアクションを考えるにあたっては、それぞれの通信結果を見る必要があるので、1 の方針で良いと個人的には考える。

  1. クライアントには通知しない
  • Proxy-Server 間の異常は、クライアントではなく、Proxy の状態を監視することで見つけるべきものという方針
  1. ProxyException のような例外を返却し、Proxy処理の失敗を通知する
  • Proxy - Server 間の詳細なエラー内容の返却方法は以下の 4案。
    1. 詳細な内容は通知しない
    2. すべての異常内容を Map で返却
    3. 一番重大な異常を返却 (異常の優先度付けが必要)
    4. はじめに発生した異常を返却

ステータス情報への反映

ログを監視しなくとも、ステータスの監視で検知可能とするためのオプション(優先度低)。

  • 通信エラーの数を記録する

結果の集約

  • 正常な通信結果が 0件 の場合(result がない) は、「結果がない」という例外を返却する。
@rimms
Copy link
Author

rimms commented Feb 21, 2014

以下を少し修正しました。

  • 問題点
  • 仕様変更案: タイムアウト時の振る舞いの変更

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