[SalesForce] Multiple Schedules Batch Class

I have a scheduleable class that I use to schedule one batch job. It works and runs when I want it to.

global class NPD_Batch_Scheduler implements Schedulable {
public static String sched = '0 0 * * * ?'; // Erry hour
public static Integer  batchSize = 2000; // max size

global static String scheduleProductBundles() {
    NPD_Batch_Scheduler SC = new NPD_Batch_Scheduler(); 
    return System.schedule('Hourly Product Bundle Update', sched, SC);
}

global void execute(SchedulableContext sc) {
    SL_Batch_ProductBundleCurrencies b = new SL_Batch_ProductBundleCurrencies();
    ID batchprocessid = Database.executeBatch(b,batchSize);           
}      
}

I have a use case where I want to schedule another batch job to run every hour as well. It doesn't make sense to to have two scheduler classes so I think I should be able to combine them. The problem is I can't wrap my head around how to pass the class name into the execute method to make it dynamic.

I have this:

global class NPD_Batch_Scheduler implements Schedulable
{
// To start new batch: NPD_Batch_Scheduler.scheduleProductBundles(); in anon apex as api user
public static String   sched = '0 0 * * * ?'; // Erry hour
public static Integer  batchSize = 2000; // max size

global static String scheduleProductBundles()
{
    String cl = SL_Batch_ProductBundleCurrencies;
    NPD_Batch_Scheduler SC = new NPD_Batch_Scheduler(cl); 
    return System.schedule('Hourly Product Bundle Update', sched, SC);
}

global static String scheduleProductPractice()
{
    String cl = NPD_Batch_RevenuePipelineProductPractice;
    NPD_Batch_Scheduler SC = new NPD_Batch_Scheduler(cl); 
    return System.schedule('Hourly Product Practice Update', sched, SC);   
}

global void execute(String cl, SchedulableContext SC)
{
    cl b = new cl();
    ID batchprocessid = Database.executeBatch(b, batchSize);           
}      
}

but that gives the error:

Class NPD_Batch_Scheduler must implement the method: void System.Schedulable.execute(System.SchedulableContext)

is it possible to have multiple methods to schedule?

Best Answer

I highly recommend you just roll scheduling functionality into your batches and strip out all the cron information from your class. IMO that really belongs in the context where you schedule the job in the first place.

public class MyBatch implements Database.Batchable, Scheduleable
{
    public Integer batchSize = 200;
    public void execute(ScheduleableContext context)
    {
        Database.execute(this, batchSize);
    }
    // batchable implementation
}

You could even put this scheduling into an abstract class (e.g. ScheduleableBatch) and extend that instead of including this boilerplate in every batch you write. If you follow this pattern for both batch implementations, you would do something like:

system.schedule('Job A', '0 0 * * * ?', new ScheduleableBatchA());
system.schedule('Job B', '0 0 * * * ?', new ScheduleableBatchB());

If you really want to implement it using the approach you've started already, you need to add the relevant property as state. I recommend you cache a Type rather than a String.

public with sharing class MyBatchScheduler implements Scheduleable
{
    final Type batchType;
    final Integer batchSize;
    public MyBatchScheduler(Type batchType) { this(batchType, 2000); }
    public MyBatchScheduler(Type batchType, Integer batchSize)
    {
        this.batchType = batchType;
        this.batchSize = batchSize;
    }
    public void execute(ScheduleableContext context)
    {
        Database.Batchable<SObject> batch =
            (Database.Batchable<SObject>)batchType.newInstance();
        Database.executeBatch(batch, batchSize);
    }
}
Related Topic