Вопрос:

AWS SWF Перезапустить рабочий процесс при определенных условиях

java amazon-web-services amazon-swf

193 просмотра

1 ответ

617 Репутация автора

У меня есть рабочий процесс 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  

     }
 }

Класс Activity выполняет вызов API, который является асинхронным методом. Действие, определенное в вызове API, занимает около часа. Иногда действие может потерпеть неудачу во время его выполнения по определенным причинам. Этот вызов API определен для службы, к которой у меня нет доступа. Есть ли способ, которым я могу уснуть, чтобы через час можно было проверить, было ли действие успешным или нет. Если не удастся, я бы повторно вызвать вызов API. Давайте предположим, что на этот раз действие будет успешным, и мы не окажемся в бесконечном цикле попыток вызова API.

Thread.sleep()кажется, один из способов, хотя я не уверен, что это наиболее подходящий способ. Я также обнаружил, что мы можем перезапустить весь рабочий процесс, используя

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

Чтобы использовать вышеизложенное, я могу вернуть из метода действия значение TimeinMinutesпосле вызова API, а затем через час перезапустить рабочий процесс.

Является ли вышеуказанный подход наиболее подходящим? Или есть лучший способ сделать это?

Спасибо

Автор: learningMyWayThru Источник Размещён: 22.08.2016 08:54

Ответы (1)


1 плюс

2382 Репутация автора

Решение

Нет необходимости вызывать continueAsNew, если у вас большая история рабочего процесса (например, после вызова действия 100 раз). Просто используйте метод @Asynchronous или Task для ожидания обещаний. Я бы смоделировал ваш рабочий процесс как две активности: 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) {
     ....
   }

}

Автор: Maxim Fateev Размещён: 22.08.2016 10:00
Вопросы из категории :
32x32