我有两台服务器(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内执行的活动。服务器应该被取消,因为它自己的服务器活动已经失败,另一台服务器应该尽可能地继续(即它依赖的地方)。
答案 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);
}
}