【问题标题】:AWS SWF Restart workflow under specific conditions特定条件下的 AWS SWF 重启工作流程
【发布时间】:2016-08-22 20:54:54
【问题描述】:

我有一个 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 的值,然后在一小时后重新启动工作流。

上述方法最合适吗?或者有更好的方法吗?

谢谢

【问题讨论】:

    标签: java amazon-web-services amazon-swf


    【解决方案1】:

    除非您的工作流历史记录很大(例如在调用活动 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) {
         ....
       }
    

    }

    【讨论】:

    • 如果我理解正确:如果外部系统仍在执行 if 操作(即其中包含 API 定义的系统),则会抛出 ResultUnavailableException。但是,如果外部系统出现故障,我需要重新尝试 API 调用。看来我需要在您的解决方案的 processResult() 中执行此操作。
    • 我想尝试将两者都放在一个活动中,因为我更愿意在进行 API 调用之前查看我的系统状态。这是一项安全检查,以防某些其他进程/或工程师手动执行导致重新执行 API 调用无关紧要的操作。有没有一种方法可以在单个活动中实现。
    • 我已经用@ExponentialRetry 更新了ServiceFailureException 上整个业务逻辑的示例,如果应该重新执行服务调用,该活动可以抛出。我不明白为什么您不能从这两个活动中查看系统状态?
    猜你喜欢
    • 2017-10-09
    • 2019-06-25
    • 1970-01-01
    • 2014-06-09
    • 2013-01-02
    • 2016-12-11
    • 1970-01-01
    • 2015-03-17
    • 2017-02-20
    相关资源
    最近更新 更多