SWF:基于Promise结束工作流程

时间:2015-09-02 23:07:54

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

我有一个调用活动的决策者。活动返回验证错误列表。如果决策者收到该列表并且它不为空,我想退出工作流程。

要退出工作流程,我只能在决策程序中返回,然后退出工作流程。问题是我无法从活动中获得结果。我预计这会有效,但它没有.. violation.isReady()总是返回false:

public class WorkflowImpl implements Workflow {
    ActivitiesClient activities;

    public Workflow(/*...*/) {
        // ...
    }

    @Override
    public void do(WorkflowInput input) {
        Promise<List<String>> violations = activities.validate(input);

        if (!violations.isReady()) { // "do()" will be called when violations is ready.. right?
            return;
        } else if (!CollectionUtils.isEmpty(violations.get())) {
            return; // or throw ValidationException
        }

        // do other stuff
    }
}

我不想做另一种选择,即poll.isReady()轮询是真的,因为这会占用决策线程,知道谁知道多长时间。我甚至不确定这是否有效。

帮助?

1 个答案:

答案 0 :(得分:2)

工作流代码是异步的。因此,从活动返回的Promise从未在同一回调中准备就绪。因此,在您的代码 violation.isReady()中,始终返回 false 是正确的行为。 您必须使用注释为@Asynchronous或Task的方法将回调关联到Promise。所以你的代码应该是这样的:

public class WorkflowImpl implements Workflow {
  ActivitiesClient activities;

  public Workflow(/*...*/) {
      // ...
  }

  @Override
  public void do(WorkflowInput input) {
    Promise<List<String>> violations = activities.validate(input);
    processValidationResult(violations);
  }

  @Asynchronous
  private void processValidationResult(Promise<List<String>> violations) {
    // As method is @Asynchronous framework guarantees violations is ready 
    // when its body is executed.
    if (!CollectionUtils.isEmpty(violations.get())) {
        return; // or throw ValidationException
    }
    // do other stuff
  }
}

请注意,带有@Asynchronous注释的Flow Framework Aspects的AspectJ should be configured correctly将生效。

另一种选择是直接使用Task:

public class WorkflowImpl implements Workflow {
  ActivitiesClient activities;

  public Workflow(/*...*/) {
      // ...
  }

  @Override
  public void do(WorkflowInput input) {
    Promise<List<String>> violations = activities.validate(input);
    new Task(violations) {
       @Override
       public void  doExecute() {
         // Framework guarantees violations is ready 
         // (as it is Task constructor parameter)
         // when execute method is executed.
         if (!CollectionUtils.isEmpty(violations.get())) {
             return; // or throw ValidationException
         }
         // do other stuff
       }
    };
  }
}

我建议您阅读SWF Recipessamples,以便更好地了解编写SWF工作流程时使用的模式。

同时确保您通过TryCatchFinally javadoc作为AWS Flow Framework错误处理,而非常强大的功能与大多数人习惯的完全不同。

添加以显示从processValidationResult(...)返回值的示例:

  @Override
  public void do(WorkflowInput input) {
    Promise<List<String>> violations = activities.validate(input);
    Promise<String> whatever = processValidationResult(violations);
    processNextStep(whatever);
  }

  @Asynchronous
  private Promise<String> processValidationResult(Promise<List<String>> violations) {
    // As method is @Asynchronous framework guarantees violations is ready 
    // when its body is executed.
    if (!CollectionUtils.isEmpty(violations.get())) {
        throw new ValidationException(...);
    }
    // do other stuff
    return Promise.asPromise("result string");
  }

  @Asynchronous
  private void processNextStep(Promise<String> whatever) {
     ...
  }