web-dev-qa-db-ja.com

イベント駆動型アーキテクチャでの失敗の処理

約30のビジネスイベントの制限付きコンテキストがあり、簡単にするために、ChangeUserEmailCommand-> UserEmailChangedEventのような同じ数のコマンドがWeb UIから開始されたとします。コマンドの処理は、次の主な理由で失敗する可能性があります(もちろん、インフラストラクチャの障害に加えて)。

  1. 検証の問題(メールの一意性)
  2. 技術的な問題(楽観的同時実行バージョンの不一致)

クライアントに最高のユーザーエクスペリエンスを提供し、問題点を表示することに興味があります。

失敗を知らせるためのベストプラクティスは何ですか?

  1. ChangeUserEmailFailedEventのようなイベントをさらに30個作成しますか?そうでない場合、ペアになっているイベントを作成するための経験則は何ですか*FailedEvent
  2. bool Success {get;set;}既存のイベントのプロパティ?エラーメッセージだけではなく、詳細なエラーを通知する必要がある場合、これはおそらく最良の方法ではありません。
  3. ペイロードの一部としてソースコマンドタイプを追加して、すべての同時実行の問題に対して単一のConcurrencyFailedEventを作成しますか?この種の失敗をビジネス検証の失敗から分離するだけですか?

コマンドは非同期に(ブローカー経由で)処理されます。読み取りストレージは書き込みストレージから分離されています。イベントソーシングはありません。

なぜこれが必要になるのかについては、次のことを考えることができます。

  1. たとえば、Webソケット経由でクライアントにプッシュバックされた詳細なエラーメッセージ
  2. 脅威の検出-攻撃の可能性があるユーザー登録の失敗の増加への対応
  3. 監視-たとえば、失敗した注文の数をダッシュ​​ボードに表示します。一定の範囲内であればサポートに任せても大丈夫だと思います。特定の数を超える場合-おそらくログを掘る必要があります。
5
UserControl

あなたは単一のタイプで逃げることができるように私には思えます

ErrorEvent
    EventId
    ErredEventId
    ErrorType
    Message

対処する必要のある一般的なエラーがあるだけの場合は、さらに進んで、UIのエラーイベントを削除します。

ユーザーが何かエラーが発生したかどうかを確認するために待機している場合は、ユーザーが呼び出した関数からエラーを返し、成功時にのみイベントを書き込むことができます。

したがって、EmailUpdatedEmailUpdateRequestEmailUpdateFailedなどの代わりにEmailUpdated

完全にイベント駆動型にすることで、必要なタイプの数が爆発することがわかります。それらがすべてシッククライアントの内部にある場合、すべてを処理するためのコンパイル時間チェックがありますが、分散システムを介してそれらを渡す必要がある場合、それはとんでもないことになります。

2
Ewan
  1. あなたの質問から、ChangeUserEmailFailedEventがドメインのコアパーツであることを理解しました。したがって、常に保存する必要があります。重要なのは、ビジネス要件がどのように変化するかを予測できないため、念のためにドメインイベントを保存することをお勧めします。
  2. わからないbool Processing {get;set;} 手段。ドメインの概念ではない場合は、省略してください。
  3. 技術的な問題にはビジネス上の価値がないため、イベントログに保存しないでください。技術関連のものについては、個別のアプリケーションログを維持する必要があります。 (つまり、プレーンテキストファイル、Elastic APMログ、またはLogstashのようなものです。要点を理解していただければ幸いです)。
1
Bohdan Stupak