Search

Friday, 22 May 2015

Generic Model For Daisy Chain Batches



In the Winter 15 release Salesforce released my idea allowing daisy chaining batch jobs, so when 1 batch job finishes a new batch can be started. Now if you have say 3 different batch jobs and at the end of the batch a new batch must be started, or you need a decision making process to decide if to start a new batch or not, you would need to create 3 separate batch classes. So, I've created a design model where only 1 batch class needs to be created, this provides a generic and flexible batch model, as shown below:


global class batchclass implements Database.Batchable<sObject>, Database.Stateful, Database.AllowsCallouts{
    global String batchType;
    global String soql;
    global Boolean success;
   

    //each time you would normally want to create a new batch class instead simply add a new else if statement in execute() and finish()
    global batchclass(){
        //default batch type
        batchType = Constants.CONST_TYPE1;
    }
   
    global batchclass(String thisbatchType){
        //pass the batch type to run
    batchType = thisbatchType;
    }
   
    global batchclass(String thisbatchType, String thissoql){
        //pass the batch type to run and batch requires a soql      
    batchType = thisbatchType;
        soql = thissoql;
    }
   
    global Database.QueryLocator start(Database.BatchableContext bc) {
        //Some batches will need to retrieve data from the database, use soql for this
    if (soql == null || soql == '')
            return Database.getQueryLocator('Select id From User limit 1');//data will not be used in the execute but User is used because there will always be at least 1 user in the org
        else
            return Database.getQueryLocator(soql);
    }
   
    global void execute(Database.BatchableContext BC, List<sObject> glbs){
        //decide which function to call depending on the type
    if (Limits.getLimitCallouts() > (Limits.getCallouts() -10) ) {
            if (batchType == Constants.CONST_TYPE1)//Constants just contains static variable strings
                success = Utils.callFunction1();
            else if (batchType == Constants.CONST_TYPE2)
                success = Utils.callFunction2();
        }
    //success  variable deecides whether the batch will be run again
    }

    global void finish(Database.BatchableContext BC){
        //if success = true  decideToRunFunction1Again is called which will either call a different batch job, or the same. It may contain a decision process as well
    //such as each time the execute() runs a custom setting is incremented and the decide functions look at this custom setting to decide if to run the batch again
    if (batchType == Constants.CONST_TYPE1 && success){
            Utils.decideToRunFunction1Again();
        }
        else if (batchType == Constants.CONST_TYPE2 && success){
            Utils.decideToRunFunction2Again();
        }
    }

}

No comments:

Post a Comment

Note: only a member of this blog may post a comment.