2016-08-22 7 views
0

私はSWFのワークフローとアクティビティを持っています。以下の構造である:AWS SWF特定の条件でワークフローを再開する

WorkflowClientImplクラス:

class TempWorkflowImpl() { 
    @Override 
    public void execute() { 
      new TryCatchFinallly { 
       @Override 
       protected void doTry() throws Throwable { 
         activityClient.invoke(); 
       } 
       @Override 
       protected void doFinally() throws Throwable { 
         // Clean up code 
       } 
       @Override 
       protected void doCatch() throws Throwable { 
         // Handle Exception 
       }      
      } 
    } 
} 

ActivityClientImplクラス:

class TempActivityImpl() { 
    @Override 
    public void invoke() { 
     // Perform some logic 
     // Check if API call (API_Call_A) is made previously 
     // If not Invoke API_Call_A. 
     // If yes, throw exception 

    } 
} 

アクティビティクラスは、API呼び出しの非同期メソッドを作成します。 API呼び出しで定義されたアクションは完了するまでに約1時間かかります。場合によっては、実行中にアクションが失敗することがあります。このAPIコールは、私がアクセスできないサービスで定義されています。 1時間後にアクションが成功したかどうかをチェックできるように、アクティビティをスリープできる方法はありますか?うまくいかない場合は、私はAPIコールを再呼び出しします。今回は、アクションが成功し、API呼び出しの無限ループに終わらないと仮定しましょう。

Thread.sleep()が一方向であるように見えますが、それが最も適切な方法であるかどうかはわかりません。私はまた、我々は上記を使用するには

Promise<Void> timer = decisionContextProvider.getDecisionContext().getWorkflowClock().createTimer(TimeUnit.MINUTES.toSeconds(TimeinMinutes)); 
continueAsNew(timer); 

を使用してワークフロー全体を再起動することができ、私はAPIコールの後、活動方法TimeinMinutesの値から復帰してから時間後にワークフローを再起動することができました。

上記のアプローチは最も適切ですか?それとももっと良い方法がありますか?

おかげ

答えて

1

ワークフロー履歴が大きくなければ(100回の活動を呼び出した後のような)continueAsNewをコールする必要はありません。 @AsynchronousメソッドまたはTaskを使用して約束を待つだけです。私はあなたのワークフローをinvokeとcheckResultという2つのアクティビティとしてモデル化し、遅れてcheckResultを実行し、@ExponentialResultを使用してresultが利用可能になるまで再試行します。

class TempWorkflowImpl() { 
    private final WorkflowClock clock = decisionContextProvider.getDecisionContext().getWorkflowClock() 
    @Override 
    public void execute() { 
     new TryCatchFinallly { 
      @Override 
      protected void doTry() throws Throwable { 
        invoke(); 
      } 
      @Override 
      protected void doFinally() throws Throwable { 
        // Clean up code 
      } 
      @Override 
      protected void doCatch() throws Throwable { 
        // Handle Exception 
      }      
     } 
    } 

    @Asynchronous 
    // On ServiceFailureException retry from the beginning 
    @ExponentialRetry(initialRetryIntervalSeconds=300, exceptionsToRetry=ServiceFailureException.class) 
    private Promise<ResultType> invoke() { 
        Promise<Void> invoked = activityClient.invoke(); 
        Promise<ResultType> result = checkResultAfterDelay(invoked); 
        processResult(result); 
    } 

    @Asynchronous 
    private Promise<ResultType> checkResultAfterDelay(Promise<Void> invoked) { 
     Promise<Void> timer = clock.createTimer(TimeUnit.MINUTES.toSeconds(60)); 
     return checkResult(timer); 
    } 

    @Asynchronous 
    // Automatically retry on ResultUnavailableException 
    @ExponentialRetry(initialRetryIntervalSeconds=300, exceptionsToRetry=ResultUnavailableException.class) 
    private Promise<ResultType> checkResult(Promise<Void> timer) { 
     return activityClient.checkResult(); 
    } 

    @Asynchronous 
    private processResult(Promise<ResultType> result) { 
    .... 
    } 

}

+0

私が正しく理解していれば:アクションはまだ外部システム(それにAPIの定義を持っている、すなわちシステム)によって実行されている場合ときResultUnavailableExceptionがスローになります。しかし、外部システムから障害が発生した場合は、APIコールを再試行する必要があります。あなたのソリューションのprocessResult()でこれを行う必要があるようです。 – learningMyWayThru

+0

私はAPIコールを行う前に私のシステムの状態を見ることを好むので、私は単一のアクティビティで両方を持つことを試みたかったのです。これは、他のプロセスまたはエンジニアが手動でアクションを実行して再実行APIコールを重要でないものにするセーフティチェックです。 1つのアクティビティで達成できる方法はありますか? – learningMyWayThru

+0

ServiceFailureExceptionのビジネスロジック全体の@ExponentialRetryの例を更新しました。これは、サービスの呼び出しを再実行する必要がある場合に発生する可能性のあるアクティビティです。なぜあなたは両方の活動からシステム状態を見ることができないのか分かりません。 –

関連する問題