2016-09-13 2 views
1

Rebusのデキュープロセスを中断して再アクティブ化するには、2つのAPIを実装する必要があります。他のプロセスがテーブルをロックしているときにRebusの実行を中断する方法

サービスバスRebusと別のソフトウェアがアプリケーションデータ(キューではありません)を保存するのと同じデータベースとテーブルを共有しますが、後者のソフトウェア(「Xprocess」と呼ぶことにします)その日、約3分間テーブルをロックします。 XprocessはRebusメッセージの実行よりも優先度が高いため、この間にRebusをXprocessによって呼び出されたSuspend and Resume APIによって一時停止することに同意しました。

私はRebusメッセージの実行を中断するための最良の方法です。 次のメッセージを一時停止する特定のメッセージを追加することはできないことを考慮してください。

私の考えは、次のステップを呼び出す前に "Pausing"サービスに問い合わせるステップを受信パイプラインに追加することです。私が何かを行う前に、次の2つのオプションを検討する

public class HandlePausingServiceStep : IIncomingStep 
{ 
    readonly ILog _log; 
    readonly IPausingService _pausingService; 

    public HandlePausingServiceStep(IRebusLoggerFactory rebusLoggerFactory, IPausingService pausingService) 
    { 
     _log = rebusLoggerFactory.GetLogger<HandleApplicationExceptionsStep>(); 
     _pausingService = pausingService; 
    } 

    public async Task Process(IncomingStepContext context, Func<Task> next) 
    { 
     while (_pausingService.Pause) 
      Thread.Sleep(5000); 

     await next(); 
    } 
} 

答えて

1

:このよう

1)単純にデータベースがロックされている時間の間にあなたのREBUSエンドポイントをホストするプロセスを停止します。

エンドポイントがWindowsサービスとしてホストされている(多くの場合、これはすべきである)場合は、単にスクリプトnet stop YourService/net start YourServiceを作成し、Windowsのタスクスケジューラを使用するだけです。

2)あなたはこのような何か行うことができます0

に労働者の数を設定するために使用REBUS'スレッドワーカーAPI:

bus.Advanced.Workers.SerNumberOfWorkers(0); 

とし、それが再びものを行うための時間があるとき:

bus.Advanced.Workers.SerNumberOfWorkers(5); 

が、明らかにあなたはREBUSハンドラからこれを行うべきではない(なぜならそれは二度とそれをウェイクアップメッセージが表示されますか?:D)

個人的には、私は最初のオプションが好きです。なぜなら、操作が簡単で操作が簡単なためです。


アップデート:このバスは、Webアプリケーションの複数のインスタンスでホストされていることを認識した後、私は少し異なる方法でこの課題を解決すると思う...

私が受け入れ可能な解決策があることだと思いますWebアプリケーションのバックグラウンドにタイマーを置くことで、データベース内の特別なテーブルの設定フラグ値を定期的にチェックすることができます。これは5-10秒ごとに行うことができます。

フラグが通知されると、すべてのインスタンスがSetNumberOfWorkers(0)になり、すべてのメッセージ処理が効果的に停止します。

フラグを再度立てると、タイマーによってワーカーが再び追加される可能性があります。

データベースがロックされている間にメッセージ処理が行われないことが重要な場合は、フラグを上げたり下ろしたりすることに少し時間の余裕を持たせることが重要です。

+1

私は[ここ](http://mookid.dk/oncode/archives/4008)で提案したような構成を使用していると考えてください。だから私はオプション2)を使用する必要があると思うが、負荷分散環境はどうですか?私は各バスのインスタンスに到達する必要があります。 – ilcorvo

+0

しかし、実行中のスレッドはすべて中止されたようです。それでは、メッセージの実行はどうなりますか? context.OnAborted通知が発生していますか? – ilcorvo

+1

「実行中のスレッドはすべて中止されたようです」という意味はどうですか?アイドル状態のときにワーカースレッドを1つずつ停止させるだけで、実行中の作業を完了するために(デフォルトで)1分まで待機させる必要があります。継続はスレッドプール上で実行されるため、これによって影響を受けなくなります。 – mookid8000

関連する問題