4

イベントソーシングでCQRSパターンを実装しています.NServiceBus、NEventStore、およびNES(NSBとNEventStoreを接続します)を使用しています。

私のアプリケーションは、Web サービスを定期的にチェックして、ダウンロードして処理するファイルがないか確認します。ファイルが見つかると、コマンド (DownloadFile) がバスに送信され、新しい集約ルート (File) を作成してメッセージを処理する FileCommandHandler によって受信されます。

(ファイル集約ルート)内で、ファイルのコンテンツが他のファイルコンテンツと一致しないことを確認する必要があります(Webサービスはファイル名のみが一意であることを保証し、コンテンツは別の名前で複製される可能性があるため) 、それをハッシュし、ハッシュされたコンテンツのリストと比較します。

問題は、ハッシュ コードのリストをどこに保存する必要があるかということです。読み取りモデルを照会することは許可されていますか?

public class File : AggregateBase
{
    public File(DownloadFile cmd, IFileService fileDownloadService, IClaimSerializerService serializerService, IBus bus)
            : this()
        {
        // code to download the file content, deserialize it, and publish an event.
        }
}

public class FileCommandHandler : IHandleMessages<DownloadFile>, IHandleMessages<ExtractFile>
{
        public void Handle(DownloadFile command)
        {
             //for example, is it possible to do this (honestly, I feel it is not, since read model should always considered stale !)
            var file = readModelContext.GetFileByHashCode (Hash(command.FileContent));
            if (file != null)
                throw new Exception ("File content matched with another already downloaded file");

            // Since there is no way to query the event source for file content like:
            // eventSourceRepository.Find<File>(c=>c.HashCode == Hash(command.FileContent));
        }
}
4

3 に答える 3

1

重複排除を探しているようです。

コマンド側は、一貫性を持たせたい場所です。クエリでは、常に競合状態が発生する可能性があります。したがって、クエリを実行する代わりに、ロジックを逆にして、実際にハッシュをデータベース テーブル (ACID が保証されている任意のデータベース) に書き込みます。この書き込みが成功した場合は、ファイルを処理します。ハッシュの書き込みに失敗した場合、処理をスキップします。

失敗した場合にメッセージを再試行する (つまり、ハッシュを複数回格納する) と成功しないため、このロジックをハンドラーに入れる意味はありません。また、エラー q で重複ファイルのメッセージが表示されることになります。

重複排除ロジックに適した場所は、おそらく Web サービス クライアント内です。いくつかの疑似ロジック

  1. ファイルを取得
  2. 取引を開く
  3. ハッシュをデータベースに挿入し、失敗をキャッチします (失敗ではなく、挿入の失敗のみ)
  4. 手順 3 で挿入されたレコードの数がゼロでない場合、プロセス ファイルへの Bus.Send メッセージ
  5. トランザクションをコミットする

NServiceBus ゲートウェイの重複排除コードの例はこちら

編集:彼らのコードを見ると、実際には不要
だと思います。で十分であり、一貫性の境界です。session.Get<DeduplicationMessage>session.Save(gatewayMessage);

クエリの実行は、失敗率が高い場合、つまりコンテンツ ファイルの重複が多い場合にのみ意味があります。99% 以上の挿入が成功した場合、重複は実際に例外として扱うことができます。

于 2014-04-23T09:49:16.690 に答える
0

ドメインに真の一意性制約がある場合、一意性テスターを、実装がインフラストラクチャの一部であるドメイン サービスにすることができます。これは、インターフェースがドメインの一部であり、実装がインフラストラクチャの一部であるリポジトリに似ています。インフラストラクチャ。実装には、必要に応じて更新/クエリされるメモリ内ハッシュまたはデータベースを使用できます。

于 2014-04-23T07:05:15.017 に答える