1

ハンドラーが受け取る各メッセージには、集約ルートの状態全体が含まれます。その後、システムはこのデータに基づいて必要な操作を実行できます。私のシナリオでは、メッセージ内のデータに基づいてアクセスを許可します。たとえば、部屋 A と B へのアクセスです。メッセージには、許可されたアクセスのセット全体が含まれます。MSMQ などのメッセージング システムは順序どおりの配信を保証しないため、これらのメッセージは順不同で到着する可能性があります。

メッセージ #1 は部屋 A と B へのアクセスを許可するが、メッセージ #2​​ は部屋 A へのアクセスのみを許可するシナリオ& B. これは望ましい結果ではありません。ルーム A へのアクセスのみを許可する必要があります。各メッセージにはタイムスタンプが含まれており、公開時に設定されます。このタイムスタンプを使用して、順不同で到着する古いメッセージを削除したいと思います。たとえば、メッセージ #2​​ がメッセージ #1 の前に到着した場合、メッセージ 1 # を破棄する必要があります。

このフィルターを各ハンドラー メソッドに実装することもできますが、それは面倒なので、Rebus にEAI Message Filtersのラインに沿った何かがあることを願っています。

私は他のオプション/実装を受け入れていますか?

4

1 に答える 1

1

メッセージ内で集約ルート全体を渡す理由がよくわかりませんが、それとは別に、Rebus を使用してメッセージを順序付けできるようにする簡単な方法があります。

すべてのメッセージに、この特定の側面を捉える共通のインターフェースを実装させることをお勧めします。

public interface IHaveSequenceNumber
{
    int SequenceNumber { get; }
}

次に、IHaveSequenceNumber古いメッセージが検出されたときにハンドラー パイプラインを処理して中止する単純なメッセージ ハンドラーを作成します。

public class WillDiscardOldMessages : IHandleMessages<IHaveSequenceNumber>
{
    public void Handle(IHaveSequenceNumber messageWithSequenceNumber)
    {
        if (IsTooOld(messageWithSequenceNumber))
        {
            MessageContext.GetCurrent().Abort(); //< make this the last handler
        }
    }
}

そして-非常に重要です:)-ディスパッチの開始時に、メッセージフィルターがハンドラーのパイプラインで常に最初にあることを確認します。

Configure.With(...)
    .Transport(...)
    .SpecifyOrderOfHandlers(s => s.First<WillDiscardOldMessages>())
    .(...)

上記のメソッドの実装はIsTooOld()お任せします。エンドポイントに 1 つのワーカー スレッドがある場合はおそらく簡単ですが、これらを同時に処理するのは簡単ではありません。

それは理にかなっていますか?

于 2013-04-16T18:48:33.540 に答える