2012-03-20 11 views
0

thisで説明されているNServiceBusの使用例があります。基本的には、ImportProductCommandメッセージ用のメッセージハンドラがあります。通常、これらのメッセージのコレクションは、別のハンドラがインポートする一連の製品を指定するImportProductsCommandを受け取った後にハンドラに送信されます。設定されたインポートのステータスを知る必要があるため、インポートの状態を管理するためにサガが使用されます。 ImportProductCommandのハンドラは、完了時にProductImportedEventメッセージとProductImportFailedEventメッセージを発行します。サガは、最初に受信されたときにメッセージに割り当てられたIDを使用して、それらを開始するImportProductsCommandメッセージに関連付けるメッセージを購読します。NServiceBusでローカル加入者に公開

public class ProductImportSaga : NServiceBus.Saga.Saga<ProductImportSagaData>, 
    IAmStartedByMessages<ImportProductsCommand>, 
    IHandleMessages<IProductImportedEvent>, 
    IHandleMessages<IProductImportFailedEvent> 
{ 
    public override void ConfigureHowToFindSaga() 
    { 
     ConfigureMapping<IProductImportedEvent>(x => x.ImportId, x => x.CorrelationId); 
     ConfigureMapping<IProductImportFailedEvent>(x => x.ImportId, x => x.CorrelationId); 
    } 

    public void Handle(ImportProductsCommand message) 
    { 
     this.Data.ImportId = message.Id; 
     this.Data.Total = message.SKUs.Length; 
     foreach (var command in message.SKUs.Select(sku => new ImportProductCommand(message.SupplierId, sku, message.ImportImage, message.Id))) 
      this.Bus.SendLocal(command); // send to local handler shown below 
    } 

    public void Handle(IProductImportedEvent message) 
    { 
     this.Data.OnCompleted(); 
    } 

    public void Handle(IProductImportFailedEvent message) 
    { 
     this.Data.OnFailed(); 
    } 
} 

と個々のImportProductCommandメッセージのハンドラは次のようになります。

// handles messages sent by saga above (or sent individually by WCF service) 
public class ImportProductHandler : IHandleMessages<ImportProductCommand> 
{ 
    public IBus Bus { get; set; } 

    public void Handle(ImportProductCommand message) 
    { 
     // importing logic here and upon success: 
     if (success) 
     { 
      this.Bus.Publish(new ProductImportedEvent(correlationId: message.Id)); 
     } 
     else 
     { 
      this.Bus.Publish(new ProductImportFailedEvent(correlationId: message.Id)); 
     } 
    } 
} 

この問題は、イベントメッセージが公開されたとき、彼らは両方をホストしているプロセスに関連付けられたキューに配置してしまうことがあります個々のハンドラとサガ。これが起こると、キューには、ImportProductsMessageへの応答としてサガによって最初に送信されたメッセージがたくさんある可能性があります。これは、キューに入れられたImportProductCommandメッセージが処理され、バッチインポートの処理ステータスが適時に更新されるまで、サガはこれらのイベントを受け取らないことを意味します。異なるプロセスで佐賀をホストすると、コマンドキューが処理されるのを待たずにメッセージを受信します。ハンドラとサガを同じプロセスでホストしているときに同じ効果を達成する方法はありますか?基本的には、イベント・メッセージがImportProductCommandメッセージとは異なる順序で処理されるようにしたいのですが、サガがそれらのイベントを処理してそれに応じて状態を更新できるように、同じキューに入っています。これは可能ですか、この結果を達成するためのより良い方法はありますか?私はFirst<T>を使用してメッセージハンドラの順序を指定しようとしましたが、密接に関連するロジックのために2つの異なるホストを展開するのは難しいようです。

答えて

2

NSBとの優先度の概念はありませんので、別のエンドポイントを使用して作業を行うのが一般的です。あなたが仕事の配分であるのと同じように聞こえますが、Distributorを見てみてください。そのモデルでは、各エンドポイントが実際の処理を処理する間、Sagaは作業ユニット全体の状態を維持します。これにより、状況が減速し始める場合に、エンドポイントを動的に追加することができます。

完全ディストリビュータを実装したくない場合は、少なくとも実際の作業を別のエンドポイントにプッシュすると、優先度の必要性が緩和されます。

+0

バッチインポートコマンドによってキューに入れられた個々のインポートよりも優先順位を付けるために手動で要求された個別のインポートをサポートする別の要件があるため、別のエンドポイントを使用することができます。 – eulerfx

+0

これで、ノードの1つを手動でインポートを処理し、いくつかのUIを介して対話するように指定できます。 –

関連する問題