根据使用AWS SWF提供的输入迭代活动列表

时间:2014-10-03 14:48:36

标签: amazon-web-services amazon-swf

我有两台服务器(EC2实例)。在一个服务器(服务器1)中我有5个批处理而另一个(服务器2)我有6个批处理。我将每个批处理包装成活动,下面给出了工作流程实现类。我想基于给定执行日期迭代活动(整个活动,包括服务器1和2)。例如,如果日期小于当前日期,则执行从给定日期到当前日期的服务器1和2的所有活动。如果执行日期等于当前日期,则执行服务器1和2的所有活动以获取当前日期。此外,如果一天的任何活动抛出任何异常,则不要执行第二天的活动(< =当前日期)。

 public class JobWorkflowImpl implements JobWorkflow{

   private DecisionContextProvider contextProvider
     = new DecisionContextProviderImpl();

   private WorkflowClock clock
     = contextProvider.getDecisionContext().getWorkflowClock();

    private BS1JobActivitiesClient bs1ActivitiesClient 
     = new BS1JobActivitiesClientImpl();
    private BS2JobActivitiesClient bs2ActivitiesClient 
     = new BS2JobActivitiesClientImpl();

    @Override
    public void executeJob(Date exedate) {
       Date today = new Date(clock.currentTimeMillis());
       Date toProcess = exedate;
       // All date manipulations are pseudocode here as I'm lazy 
       // to look up the real ones.
       Promise<Void> previousDateDone = null;
       while(toProcess <= today) {
          // Create chain of executeJobForExactDate 
          // linked by previousDateDone to ensure that they are executed sequentially.
          // null Promise is treated as ready promise by the framework.
          previousDateDone = executeJobForExactDate(toProcess, previousDateDone);
          toProcess.addDay(1);
       }
    }

    Promise<Void> void executeJobForExactDate(Date date, Promise<Void> previous) {

       Settable<Integer> firstServerDone = new Settable<Integer>();
       Settable<Integer> secondServerDone = new Settable<Integer>();

       Settable<Integer> resultODLSLBs1 = new Settable<Integer>();

       //TODO Iterate over the activities
        new TryCatchFinally(previous){

            @Override
            protected void doTry(){
                Promise<Integer> resultFARBs1 = bs1ActivitiesClient.executecommand1(date);
                Promise<Integer> resultUAMLFBs1 = bs1ActivitiesClient.executecommand2(date, resultFARBs1);
                Promise<Integer> resultLLPBs1 = bs1ActivitiesClient.executecommand3(date, resultUAMLFBs1);
                Promise<Integer> resultODLDLBs1 = bs1ActivitiesClient.executecommand4(date, resultLLPBs1);
                // Chain links result of the activity execution 
                // to an aready existing Settable.
                resultODLSLBs1.chain(bs1ActivitiesClient.executecommand5(date, resultODLDLBs1));
            }

            @Override
            protected void doCatch(Throwable e){
               throw new MyException("Failed");
            }

            @Override
            protected void doFinally() throws Throwable {
                firstServerDone.set(null);
            }
        };

        new TryCatchFinally(previous){

            @Override
            protected void doTry()  {
                Promise<Integer> resultFARBs2 = bs2ActivitiesClient.executecommand1(date);
                Promise<Integer> resultUAMLFBs2 = bs2ActivitiesClient.executecommand2(date, resultFARBs2);
                Promise<Integer> resultLLPBs2 = bs2ActivitiesClient.executecommand3(date, resultUAMLFBs2);
                Promise<Integer> resultODLDLBs2 = bs2ActivitiesClient.executecommand4(date, resultLLPBs2);
                Promise<Integer> resultODLSLBs2 = bs2ActivitiesClient.executecommand5(date, resultODLDLBs2, resultODLSLBs1);
                bs2ActivitiesClient.executecommand6(date, resultODLSLBs2);
            }

            @Override
            protected void doCatch(Throwable e){
                throw new MyException("Failed");
            }

            @Override
            protected void doFinally(){
                secondServerDone.set(null);
            }

        };
        // AndPromise is done when all of its constructor parameters are done.
        // I decided to consider the date processing done when both 
        // TryCatchFinallies are done. You can implement more complex logic depending on
        // the business requirements. One option is to wrap both TryCatcFinallies 
        // in another TryCatchFinally.
        return new AndPromise(firstServerDone, secondServerDone);
    }
}

问题是,如果服务器1的任何活动抛出任何异常,那么它将取消服务器1和服务器2都没有启动的所有活动。但是我只想要一个未在服务器1和服务器2内执行的活动。服务器应该被取消,因为它自己的服务器活动已经失败,另一台服务器应该尽可能地继续(即它依赖的地方)。

1 个答案:

答案 0 :(得分:0)

棘手的部分是Flow Framework要求您使用它通过决策上下文提供的Clock。否则它将无法正常运行。其余的只是异步Java编程。

public class JobWorkflowImpl implements JobWorkflow{

   private DecisionContextProvider contextProvider
     = new DecisionContextProviderImpl();

   private WorkflowClock clock
     = contextProvider.getDecisionContext().getWorkflowClock();

    private BS1JobActivitiesClient bs1ActivitiesClient 
     = new BS1JobActivitiesClientImpl();
    private BS2JobActivitiesClient bs2ActivitiesClient 
     = new BS2JobActivitiesClientImpl();

    @Override
    public void executeJob(Date exedate) {
       Date today = new Date(clock.currentTimeMillis());
       Date toProcess = exedate;
       // All date manipulations are pseudocode here as I'm lazy 
       // to look up the real ones.
       Promise<Void> previousDateDone = null;
       while(toProcess <= today) {
          // Create chain of executeJobForExactDate 
          // linked by previousDateDone to ensure that they are executed sequentially.
          // null Promise is treated as ready promise by the framework.
          previousDateDone = executeJobForExactDate(toProcess, previousDateDone);
          toProcess.addDay(1);
       }
    }

    Promise<Void> void executeJobForExactDate(Date date, Promise<Void> previous) {

       Settable<Integer> firstServerDone = new Settable<Integer>();
       Settable<Integer> secondServerDone = new Settable<Integer>();

       Settable<Integer> resultODLSLBs1 = new Settable<Integer>();

       //TODO Iterate over the activities
        new TryCatchFinally(previous){

            @Override
            protected void doTry(){
                Promise<Integer> resultFARBs1 = bs1ActivitiesClient.executecommand1(date);
                Promise<Integer> resultUAMLFBs1 = bs1ActivitiesClient.executecommand2(date, resultFARBs1);
                Promise<Integer> resultLLPBs1 = bs1ActivitiesClient.executecommand3(date, resultUAMLFBs1);
                Promise<Integer> resultODLDLBs1 = bs1ActivitiesClient.executecommand4(date, resultLLPBs1);
                // Chain links result of the activity execution 
                // to an aready existing Settable.
                resultODLSLBs1.chain(bs1ActivitiesClient.executecommand5(date, resultODLDLBs1));
            }

            @Override
            protected void doCatch(Throwable e){
                System.out.println("Failed to execute BS1 daily job");
            }

            @Override
            protected void doFinally() throws Throwable {
                firstServerDone.set(null);
            }
        };

        new TryCatchFinally(previous){

            @Override
            protected void doTry()  {
                Promise<Integer> resultFARBs2 = bs2ActivitiesClient.executecommand1(date);
                Promise<Integer> resultUAMLFBs2 = bs2ActivitiesClient.executecommand2(date, resultFARBs2);
                Promise<Integer> resultLLPBs2 = bs2ActivitiesClient.executecommand3(date, resultUAMLFBs2);
                Promise<Integer> resultODLDLBs2 = bs2ActivitiesClient.executecommand4(date, resultLLPBs2);
                Promise<Integer> resultODLSLBs2 = bs2ActivitiesClient.executecommand5(date, resultODLDLBs2, resultODLSLBs1);
                bs2ActivitiesClient.executecommand6(date, resultODLSLBs2);
            }

            @Override
            protected void doCatch(Throwable e){
                System.out.println("Failed to execute BS2 daily job");
            }

            @Override
            protected void doFinally(){
                secondServerDone.set(null);
            }

        };
        // AndPromise is done when all of its constructor parameters are done.
        // I decided to consider the date processing done when both 
        // TryCatchFinallies are done. You can implement more complex logic depending on
        // the business requirements. One option is to wrap both TryCatcFinallies 
        // in another TryCatchFinally.
        return new AndPromise(firstServerDone, secondServerDone);
    }
}