【问题标题】:AWS SWF Promise IllegalStateException: Not readyAWS SWF 承诺 IllegalStateException:未准备好
【发布时间】:2016-12-30 23:13:36
【问题描述】:

我正在尝试执行 SWF 工作流程。我遇到了关于Promise 对象状态的问题。我的代码结构如下:

WorkflowClientImpl.java 中的方法:

  @Override
  public void doSomething() {
    new TryCatch() {

        @Override
        protected void doTry() throws Throwable {
            System.out.println("Workflow Started");
            Promise<SomeObject> someObject = activityClient.doAction(param1);
            if(someObject.isready()) {
                 boolean reDo = shouldRestartWorkflow(someObject);
                 if(reDo) {
                      Promise<Void> timer = decisionContextProvider.getDecisionContext().getWorkflowClock()
                        .createTimer(TimeUnit.MINUTES.toSeconds(5));
                      continueAsNew(timer, param1);
                 }
            }
        }

        @Override
        protected void doCatch(Throwable e) throws Throwable {
            System.err.printlnt("Error occured while workflow");
            throw new RuntimeException(e);
        }
    };
}    


@Asynchronous
private boolean shouldRestartWorkflow(@Wait Promise<SomeObject> someObject) {

    if(someObject.get().getVariable() > 1)
        return true;

    return false;
}

@Asynchronous
public void continueAsNew(Promise<Void> timer, String param1) {
    selfClient.execute(param1);
    // SelfClient is instance of TempWorkflowSelfClient
}

上面的代码应该在满足某些条件时重新启动工作流。条件取决于活动方法返回的 SomeObject 实例中填充的值。但是代码shouldRestartWorkflow 似乎从未被调用过。

我试图为此编写一个单元测试。下面是代码:

@Before
public void setUp() throws Exception {

    trace = new ArrayList<String>();
    // Register activity implementation to be used during test run
    TempActivitiesImpl activitiesImpl = new TempActivitiesImpl(null, null) {

        @Override
        public SomeObject doAction(String randomString) {
            trace.add("Test Case - " + randomString);
            SomeObject testObject = new SomeObject();
            testObject.setVariable(true);

            return testObject;
        }
    };
    workflowTest.addActivitiesImplementation(activityImpl);    //Instance to activity class
    workflowTest.addWorkflowImplementationType(WorkflowImpl.class);
}


 @Test
public void testWorkflowExecutionCall() throws Throwable {

    WorkflowClient workflow = workflowFactory.getClient("RandomString");
    Promise<Void> promise = workflow.execute("RandomString");

    List<String> expected = new ArrayList<String>();
    expected.add("Test Case - RandomString");

    AsyncAssert.assertEqualsWaitFor("Unexpected Result", expected, trace, promise);
}

上述测试用例有效。但是,如果我要删除 if(someObject.isready()) 条件。我收到错误IllegalStateException: Not Ready。当它尝试执行shouldRestartWorkflow() 调用时,我能够确定发生了错误。

我做错了吗?据我了解,shouldRestartWorkflow() 应该等到 SomeObject 被填充并由活动方法返回,然后再继续。

【问题讨论】:

  • 我发现当 AspectJ 或 SWF 注释设置不正确时最常发生特定错误。那样就很烦人了……
  • 您如何确定哪些注释设置不正确?我删除了项目的 AspectJ 功能,然后重新添加了它们。仍然得到同样的错误。如果我只调用一次活动方法(即在第一次调用活动方法后删除代码路径),代码就可以工作。
  • "您如何确定哪些注释设置不正确?"很多痛苦。筛选文档以检查和仔细检查。需要 AspectJ 的 SWF 使得调试它变得非常痛苦。抱歉,我帮不上什么忙。
  • 使用任务而不是@Asynchronous。它看起来更丑,但不依赖 AspectJ。

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


【解决方案1】:

SWF 注释设置不正确。由于这个问题,@Asynchronous 无法正常工作。

将 AspectJ 添加为 Java 代理

  1. 要打开“首选项”对话框,请单击“窗口”>“首选项”。
  2. 导航到 Java > 已安装的 JRE。
  3. 选择适当的 JRE 并单击编辑。
  4. 在默认 VM 参数框中,输入安装的路径 AspectJ 二进制文件。这将是一条路径,例如 /home/user/aspectj1.7/lib/aspectjweaver.jar,取决于你的 操作系统和您下载的 AspectJ 版本。

在 Linux、OS X 或 Unix 上使用:

-javaagent:/your_path/aspectj/lib/aspectjweaver.jar

在 Windows 上,请改用标准的 Windows 样式路径:

-javaagent:C:\your_path\aspectj\lib\aspectjweaver.jar

要为 AWS Flow Framework for Java 配置 AspectJ,请将 aop.xml 文件添加到项目中。

  1. 添加 aop.xml 文件
  2. 在项目的 src 目录中,添加一个名为 META-INF 的目录。
  3. 将名为 aop.xml 的文件添加到 META-INF,内容如下。
<aspectj>
   <aspects>
      <!-- declare two existing aspects to the weaver -->
      <aspect name="com.amazonaws.services.simpleworkflow.flow.aspectj.AsynchronousAspect"/>
      <aspect name="com.amazonaws.services.simpleworkflow.flow.aspectj.ExponentialRetryAspect"/>
   </aspects>
   <weaver options="-verbose">
     <include within="<replaceable>MySimpleWorkflow.*</replaceable>"/>
   </weaver>
</aspectj>

的值取决于您如何命名项目的包。上面的示例假定项目的包遵循模式 MySimpleWorkflow.*。使用适合您自己项目包的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2017-07-05
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多