ほとんどのミドルウェア API は SdvResult オブジェクトを返します。成功した場合、このオブジェクトには想定される結果オブジェクトが含まれます。失敗した場合、このオブジェクトには SdvStatus オブジェクトが含まれます。これは、予期しない動作またはエラー状態を示します。多くの場合、Internal、Unavailable、DataLoss などのエラーコードで識別されます。
このページでは、これらのエラーコードのトラブルシューティングについて説明します。
登録と作成の失敗をトラブルシューティングする
登録と作成の失敗は通常、無効なサービスを作成または登録しようとした場合に発生します。
2 番目のサービスを作成できない
エラー:
Internal エラー。
原因:
まったく同じサービス バンドル インスタンス(名前とインスタンス ID)を 2 回登録しようとしています。
修正:
まったく同じサービス バンドル インスタンス(名前とインスタンス ID)を 2 回登録しないでください。
重複するサービス バンドルを削除できない
エラー:
Status(-3, EX_ILLEGAL_ARGUMENT)
原因:
存在しない重複するサービス バンドルを削除しようとしています。
修正:
存在しない重複するサービス バンドルを削除しないでください。
メッセージを送信するためのパブリッシャー インスタンスを取得できない
エラー:
take_publisher() の呼び出しが none を返します。
原因:
同じサービス バンドル インスタンスから同じバリアントに対して take_publisher() を 2 回呼び出しました。
修正:
同じサービス バンドル インスタンスから同じバリアントに対して take_publisher() を 2 回呼び出さないでください。
Subscriber、Observer、History、InstantReader を作成できない
エラー:
Unavailable エラー。
原因:
存在しないパブリッシャーまたは登録解除されたパブリッシャーに対して、Subscriber、Observer、History、InstantReader を作成しようとしました。
修正:
パブリッシャーに対して Subscriber、Observer、History、InstantReader を作成する前に、パブリッシャーが存在するか、登録されていることを確認します。
RPC クライアントを作成できない
エラー:
Unavailable エラー
原因:
存在しないサーバーユニット名または登録されていないサーバーユニット名に対して RPC クライアントを作成しようとしました。
修正:
RPC クライアントを作成する前に、サーバーが存在し、登録されていることを確認します。
通信の失敗をトラブルシューティングする
通信の失敗は、サービスが実行され、他のサービスとの通信を開始した後に発生する可能性があります。
パブリッシャーの登録解除をトラブルシューティングする
リーダーがアクティブな状態でパブリッシャーが登録解除されると、エラーが発生する可能性があります。
Subscriber の read_next_messages() が空のリストを返す
エラー:
read_next_messages() は成功しますが、空のリストを返します。
原因:
リーダーがアクティブな状態でパブリッシャーが登録解除されています。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用できない場合、パブリッシャーは登録解除され、新しいメッセージはありません。
Observer の next() が内部エラーを返す
エラー:
next() が Internal エラーを返します。
原因:
リーダーがアクティブな状態でパブリッシャーが登録解除されています。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用できない場合、パブリッシャーは削除され、新しいメッセージはありません。
History の read_from_history() が新しいメッセージを返さない
エラー:
read_from_history() は新しいメッセージを返さず、古いメッセージのみを返します。
原因:
リーダーがアクティブな状態でパブリッシャーが登録解除されています。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用できない場合、パブリッシャーは削除され、新しいメッセージはありません。
InstantReader read_latest_message() が内部エラーを返す
エラー:
read_latest_message() が Internal エラーを返します。
原因:
リーダーがアクティブな状態でパブリッシャーが登録解除されています。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用できない場合、パブリッシャーは削除され、新しいメッセージはありません。
空のメッセージ キューをトラブルシューティングする
空のメッセージ キューから読み取ろうとすると、エラーが発生する可能性があります。
Subscriber の read_next_messages() が空のリストを返す
エラー:
read_next_messages() が空のリストを返して成功します。
原因:
パブリッシャーはアクティブですが、メッセージを送信していません。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用可能な場合、パブリッシャーはアクティブであり、新しいメッセージはありません。
Observer の next() が内部エラーを返す
エラー:
next() が Internal エラーを返します。
原因:
パブリッシャーはアクティブですが、メッセージを送信していません。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用可能な場合、パブリッシャーはアクティブであり、新しいメッセージはありません。
History の read_from_history() が新しいメッセージを返さない
エラー:
read_from_history() が空のリストを返して成功します。
原因:
パブリッシャーはアクティブですが、メッセージを送信していません。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用可能な場合、パブリッシャーはアクティブであり、新しいメッセージはありません。
InstantReader read_latest_message() が内部エラーを返す
エラー:
read_latest_message() が Internal エラーを返します。
原因:
パブリッシャーはアクティブですが、メッセージを送信していません。
修正:
可用性ストリームを持つサブスクライバーまたは履歴を使用します。可用性ストリームの最後のメッセージが利用可能な場合、パブリッシャーはアクティブであり、新しいメッセージはありません。
バッファ オーバーフローまたはデータ損失をトラブルシューティングする
パブリッシャーがリーダーが消費できるよりも速いレートでメッセージを送信すると、エラーが発生する可能性があります。
オーバーフロー後の Subscriber の最初の読み取りで DataLoss エラーが返される
エラー:
read_next_message() が DataLoss エラーを返します。
原因:
パブリッシャーがリーダーが消費できるよりも速いレートでメッセージを送信します。
修正:
オーバーフロー後の Observer の最初の next() で DataLoss エラーが返される
エラー:
next() が DataLoss エラーを返します。
原因:
パブリッシャーがリーダーが消費できるよりも速いレートでメッセージを送信します。
修正: 次の修正が考えられます。
パブリッシャーがより遅いレートでパブリッシュします。たとえば、最新のメッセージのタイムスタンプを含む変数があるとします。現在の時刻が最新の公開時刻にデルタを加えた値よりも小さい場合、メッセージは公開されません。このメカニズムを使用すると、デルタごとに最大 1 つのメッセージが公開されます。
コンシューマーはオブザーバーの代わりに
InstantReadオブジェクトを使用します。InstantReadオブジェクトはオーバーフロー エラーを返さず、常に最後のメッセージを返します。最後のメッセージのみが重要な場合は、オブザーバーの代わりにInstantReadオブジェクトを使用できます。コンシューマーがサンプリングを実装します。ソリューションに、オブザーバー(01)が読み取れるよりも速いレートでメッセージをパブリッシュするパブリッシャー(P1)がある場合は、パブリッシュ速度と読み取り速度の違いに対応するために、新しいパブリッシャー(P2)とオブザーバー(02)を作成できます。
たとえば、P1 が 10 ミリ秒ごとにメッセージをパブリッシュするが、O1 は 100 ミリ秒ごとに 1 つのメッセージしか読み取れず、残りの 9 つのメッセージをドロップするとします。この不一致を解決するには、次の手順に沿ってソリューションを作成します。
- P1 は O2 にメッセージをパブリッシュします。
- O2 は 1 つのメッセージを読み取り、9 つのメッセージをドロップします。
- O2 は読み取った 1 つのメッセージを P2 に送信します。
- P2 は読み取った 1 つのメッセージを O1 に送信します。
- O1 は 10 秒ごとに 1 つのメッセージを読み取ります。
次のコード例は、このサンプリング シナリオを実装する方法を示しています。
int discarded_message = 10; while (true) { message m = O2.read_message(); if discarded_message == 10 { discarded_message = 0; P2.publish(m); } else { discarded_message ++; } }
履歴の読み取りが不完全である
エラー:
履歴のコピー前にメッセージが失われます。読み取り時に直接エラー通知はありません。
原因:
パブリッシャーがリーダーが消費できるよりも速いレートでメッセージを送信します。
修正:
InstantReader が最後のメッセージのみを読み取る
エラー:
履歴のコピー前にメッセージが失われます。読み取り時に直接エラー通知はありません。
原因:
パブリッシャーがリーダーが消費できるよりも速いレートでメッセージを送信します。
修正:
なし
RPC クライアントがメソッドを呼び出すが、メソッドが利用できない
エラー:
メソッド呼び出しが Unavailable エラーで失敗します。
原因:
SDV はサーバー名を認識せず、Unavailable を返します。サービス ディスカバリが有効なサーバー名を返さない場合、このエラーはミドルウェアによって返されます。
修正:
クライアントが使用する特定のインターフェースの server を定義するサービス バンドルを開始します。
サーバーサイドの実装が SdvStatus エラーを返す
エラー:
サーバーサイドの実装が、SdvResultを含むSdvStatus
エラー(例:SdvStatusCode::NotFound)を返します。エラーは呼び出し元のクライアントに伝播されます。
原因:
SDV とクライアントとサーバー間の通信システムは想定どおりに動作しますが、クライアントがサーバーでエラーをトリガーするリクエストを行いました。
修正:
クライアントで有効なリクエストを行うか、サーバーを修正してこれらのリクエストに正常に応答します。