Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I am trying to schedule a batch after 15 mins from my post installation script which take 100 records and process it. But it might be possible that when my scheduled job will start already another 5 jobs are running or in queue in that case i want to reschedule my batch for next 15 mins.

I am not sure where to put this check which will count no of running apex jobs.

My post installation script contain below code.

       String  batchqueryString = 'Select ID, Account__c,InstanceList__c from CustomerInfo__c';
                         BatchHandler bhObj              = new BatchHandler();
                         bhObj.queryStr                  = batchqueryString;
                         bhObj.batchMethodName           = 'abc';

                   system.scheduleBatch(bhObj,'Scheduleabc',15,100);

Should i write logic to check counts of apex jobs running in BatchHandler execute function and if jobs running are less than 5 then proceed other wise create a new scheduler with same name for next 15 min.

share|improve this question

1 Answer 1

up vote 3 down vote accepted

I use this pattern, i've seen lots of others but all do something similar:

private static Integer getCurrentJobCount()
{
    return (Integer)[Select count() From AsyncApexJob Where JobType = 'BatchApex' and ( Status = 'Processing' or Status = 'Preparing' )];
}

private void submitJob( IReschedulable job, SchedulableContext SC )
{
    if( getCurrentJobCount() > 4 )
    {
        // try again in 15 minutes
        Datetime sysTime = System.now().addSeconds( 900 );

        String chronExpression = '' + sysTime.second() + ' ' + sysTime.minute() + ' ' + sysTime.hour() + ' ' + sysTime.day() + ' ' + sysTime.month() + ' ? ' + sysTime.year();

        System.schedule( job.getJobName() + sysTime, chronExpression, (System.Schedulable)job );
    }
    else
    {
        Database.executeBatch( (Database.Batchable<Object>)job, job.getBatchSize() );

        // abort scheduled job if this was as a result of a reschedule
        if( SC != null && job.getAbortAfterSubmit() )
        {
            System.abortJob( SC.getTriggerId() );
        }
    }
}

I've missed off some particulars, but hopefully you get the gist. You should basically put the count just prior to calling Database.executeBatch, which I'm guessing is in the BatchHandler class. I'm afraid it's not completely infallible, because there is of course a moment between the query returning < 4 and the job actually starting (at which point another job could have gotten in) but I've found it to be very reliable (and have it deployed in many orgs).

PS. Just noticed you're using System.scheduleBatch, I personally wouldn't trust that to be safe, see this post.

share|improve this answer
    
Thanks for quick reply. Let me try with System.schedule()method. –  Sandeep Aug 2 at 20:29
    
can you explain the purpose of else part i did not get why we call abortJob(). –  Sandeep Aug 2 at 20:45
    
Yes, if you schedule your job programatically as per my example, once the job has executed it will stay in the 'Scheduled Jobs' forever (even though it will never run again). So, the System.abortJob is simply to get rid of that entry (you may of course want to keep it there). Does that make sense? –  Phil Hawthorn Aug 2 at 20:52
    
Yes it make sense :) can i do same re scheduling logic with System.scheduleBatch() method? Thanks!! –  Sandeep Aug 2 at 21:08
    
I would say not, if you read the post I mention in my PS you'll see why. –  Phil Hawthorn Aug 2 at 21:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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