我有一个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);


要使用上述方法,我可以在调用API后从活动方法返回TimeinMinutes的值,然后在一个小时后重新启动工作流程。

以上方法最合适吗?还是有更好的方法来做到这一点?

谢谢

最佳答案

除非您的工作流历史记录很长(例如,在调用活动100次之后),否则无需调用continueAsNew。只需使用@Asynchronous方法或Task来等待诺言。我会将您的工作流建模为两个活动:调用和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) {
     ....
   }


}

10-07 19:33
查看更多