Iterate over the list of activities based on the input provided using AWS SWF

泪湿孤枕 提交于 2019-12-04 06:40:59

问题


I have two servers(EC2 instances). In one server(server 1) i have 5 Batch and on another(server 2) i have 6 Batch. I wrapped each batch into activities and the work flow implementation class is given below. I want to iterate over the activities(entire activities, including server 1 and 2) based on the give execution date. For example, if the date is lesser than the current date then, execute all the activities of both server 1 and 2 starting from the given date up to the current date. If the execution date is equal to current date then, execute all the activities of both server 1 and 2 for current date. Also, if any of the activity for a day throws any exception then, don't execute the activities for the next day(<=current date).

 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);
    }
}

The problem is that, if any activity of server 1 throws any exception then, it is cancelling the all the activity that have not started for both server 1 and server 2. But I want only the activity that have not executed within a server should get cancelled as its own server activity has failed, the other server should continue as far as possible(i.e. the place up to which it is dependent).


回答1:


The tricky part is that the Flow Framework requires that you use the Clock that it provides through the decision context. Otherwise it is not going to function correctly. The rest is just asynchronous Java programming.

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);
    }
}


来源:https://stackoverflow.com/questions/26181236/iterate-over-the-list-of-activities-based-on-the-input-provided-using-aws-swf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!