2

I am trying to schedule a batch class to run every 2 min. What I tried so far is :

global class schlerclass implements Schedulable{

   global void execute(SchedulableContext sc) {


        // Re-schedule 
        System.debug('Enter Scheduler class');
        DateTime now  = DateTime.now();
        DateTime nextRunTime = now.addMinutes(2);
        String cronString = '' + nextRunTime.second() + ' ' + nextRunTime.minute() + ' ' + 
            nextRunTime.hour() + ' ' + nextRunTime.day() + ' ' + 
            nextRunTime.month() + ' ? ' + nextRunTime.year(); 
        System.schedule('SchdJob', cronString, new schlerclass());
        // Abort the current job
        Id jobId = sc.getTriggerId();
        System.abortJob(jobId);     
        // Launch a batch job or call a future method to do the actual work
        AbatchClass b = new AbatchClass(); 
        database.executebatch(b);
        system.debug('done scheduling');



   }

}

I try to run this using execute anonymous code:

AbatchClass b = new AbatchClass (); 
String sch = '0 0 11 27 12 ?';
system.schedule('Start Ord Replacement', sch, new schlerclass ());

As I am creating this code as part of managed package and make it available to install , I am wondering how would the user downloading the package should invoke the AbatchClass to run from execute anonymous? Is this something that should be done after installing the package? Can this be trigger from somewhere.

Also, please comment on the approach I followed to schedule a batch job every 2 minutes. Is this a good approach or is there anything better ? Thanks

  • If you ask me, I'd say you're having a bit of an X-Y problem. Except for some precious few exceptions, it's almost always better to find a solution that does not involve suicide scheduling, because salesforce may eventually decide to penalize such code (but #safeHarbor because we don't know when, or if, it'll happen). Perhaps you might pose a question where you simply state what your intended goals are, and see if there's a better solution. – sfdcfox Dec 27 '16 at 16:45
  • @sfdcfox I am developing a solution to get a list of records every 15 min and send it to an external system as a web service callout. Thus I am using the a batch class and re scheduling it every 15 min to do this job. Does my approach sounds good? – SfdcBat Dec 27 '16 at 17:47
4

If part of a managed package I would provide a UI for them to schedule, cancel, etc. I would also make the scheduled and batch class public and not global so the user could not schedule it outside of the ui.

How complicated the UI is is up to you. This is an example UI to illustrate what I mean:

enter image description here

by storing the job Id you can provide for the ability to cancel.

When initially running you would simply use system.scheduleBatch with the minutes being 1 and the batch will run in 1 minutes, then the finish method handle the rescheduling.

As for scheduling every 15 minutes, you can do that in the finish method using system.scheduleBatch and use 15 as the minutes criteria. Essentially the first run kicks off the process. Since you will need the job Id to cancel, you will need to manage that Id as well and update it when you schedule the next batch.

It all depends on how much control you want to have over the process......

To do it using a CRON expression you would need 4 expressions and schedules to do it every 15 minutes..

UPDATE

All of the above is nice but what if you just want a simple answer.

I have done the following:

  1. Allow customer to schedule batch using UI
  2. In the Scheduler Class in the execute I abort the job
  3. In the finish method of the batch class I use system.scheduleBatch to run in 15 minutes

End result, customer use UI to initially schedule batch, schedule aborts itself after first run, batch takes over and schedules every 15 minutes

Schedule Class

global class ExampleScheduler implements Schedulable{ 


   global void execute(SchedulableContext sc) {
        ExampleBatch batch = New ExampleBatch();
           database.executeBatch(batch);

        //Cancel schedule
        CronTrigger ct =
            [SELECT Id,
            CronExpression
            FROM CronTrigger
            WHERE Id = :SC.getTriggerId()];

            System.abortJob(SC.getTriggerId());



   }

}

Batch Class

global class ExampleBatch implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext BC) {

        String query = 'Select ID From Account';

        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<sObject> scope) {

        //Do Stuff

    }

    global void finish(Database.BatchableContext BC) {
       if(!test.isRunningTest()) system.scheduleBatch(New ExampleBatch(),'Run again in 15',15); 
    }


}
  • Thanks for the answer Eric. Appreciate the response. Would you mind letting me know some sources which I can refer to build this page? – SfdcBat Dec 27 '16 at 18:15
  • 1
    @SfdcBat - It is all in the documentation. Unfortunately I am not aware of any blog or specific resource that would be a one stop resource. Its a combination or SLDS, VF, and Querying the appropriate objects for the status. Scheduling is using the system.scheduleBatch. This answer was meant to get you thinking not provide a complete solution as that would not be a very succinct answer.. The direction you take it is up to you. Easiest route is to just allow the user to schedule. I will update my answer to include some instructions – Eric Dec 27 '16 at 18:26
  • Yes this helps me to think in a direction where I can start. Appreciate your input – SfdcBat Dec 27 '16 at 18:27
  • @SfdcBat - See updated answer – Eric Dec 27 '16 at 18:34
3

You can use PostInstall script in apex for managed package to automatically schedule the batch apex to run every 2 minutes .

PostInstall scripts run as soon as the installation of your managed package is completed by subscriber.

Also admins can also schedule using developer console but a better approach for the same would be build a custom visualforce page for admins to monitor and schedule the jobs using clicks .

Note that there is no SLA for the batch apex and there is no guarantee your jobs will be executed in 2 minutes before your next job starts .So always have proper error recovery mechanisms and alternate methods to restore data integrity if batches do not operate

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.