2016-08-22 57 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調用中定義的操作大約需要一個小時才能完成。有時,由於某些原因,執行操作可能會失敗。此API調用是在我無權訪問的服務上定義的。 有沒有辦法讓我可以睡覺這個活動,以便它可以在一個小時後檢查行動是否成功。如果不成功,我會重新調用API調用。讓我們假設這次行動會成功,並且我們不會以無限循環的API調用嘗試結束。

Thread.sleep()似乎是一種方式,但我不確定這是最合適的方式。我還發現,我們可以重新開始使用

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

使用上面的整個工作流程,我可以從活動方法TimeinMinutes API調用後返回一個值,然後重新啓動一個小時後的工作流程。

上述方法最合適嗎?還是有更好的方法來做到這一點?

感謝

回答

1

沒有必要(調用活動100次後等)調用continueAsNew除非你的工作流程的歷史大。只需使用@Asynchronous方法或Task來等待promise。我會將您的工作流建模爲兩種活動:invoke和checkResult並在延遲後執行checkResult並使用@ExponentialResult重試它直到結果可用。

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

如果正確地明白:ResultUnavailableException將是當仍在由外部系統(其具有API定義在它即系統)執行的動作是否扔。但是,如果我從外部系統發生故障,我需要重新嘗試API調用。看來我需要在解決方案中的processResult()中執行此操作。 – learningMyWayThru

+0

我想嘗試在一個單獨的活動中進行,因爲我希望在進行API調用之前查看我的系統狀態。這是安全檢查,因爲某些其他進程/或工程師手動執行導致重新執行API調用不重要的操作。有沒有一種方法可以在單一活動中實現? – learningMyWayThru

+0

我已經使用@ExponentialRetry更新了ServiceFailureException上整個業務邏輯的示例,如果應該重新執行服務調用,則可以拋出哪個活動。我不明白你爲什麼不能從兩個活動中看你的系統狀態? –

相關問題