You need to sign in to do that
Don't have an account?
Ben Meyers
Scheduled apex runs out of time
I have the following three classes that are used to schedule an apex job. Yesterday I noticed the job had 13 batches complete successfully yet only 12 actions occurred insdie KeysBatch. Is there a good way to debug what happened or a way to alert me when a batch fails to complete or reschedule?
public class ScheduleHandler implements ScheduledDispatcher.IScheduleDispatched { private string query = 'SELECT Quote__c, Name FROM c2g__codaInvoice__c WHERE Small_Platform_Key__c = true'; public void execute(SchedulableContext sc) { system.abortJob(sc.getTriggerID()); // Always abort the job on completion system.debug('Here execute'); //Run key batch KeysBatch batch = new KeysBatch(query); Database.executeBatch(batch, 1); } public static String GetSchedulerExpression(Datetime dt) { return ('' + dt.second() + ' ' + dt.minute() + ' ' + dt.hour() + ' ' + dt.day() + ' ' + dt.month() + ' ? ' + dt.year()); } private static Boolean ScheduledInContext = false; public static void StartScheduler() { if(ScheduledInContext) return; ScheduledInContext = true; List<CronTrigger> jobs = [SELECT Id, CronJobDetail.Name, State, NextFireTime FROM CronTrigger where CronJobDetail.Name='Small Platform Schedule Job']; if(jobs.size()>0 && jobs[0].state!='COMPLETED' && jobs[0].state!='ERROR' && jobs[0].state!='DELETED') return; // Already running Set<String> activejobstates = new Set<String>{'Queued','Processing','Preparing'}; List<AsyncApexJob> apexjobs = [Select ID, ApexClass.Name from AsyncApexJob where ApexClass.Name = 'KeysBatch' And Status in :activejobstates]; if(apexjobs.size()>0) return; // The batch is running System.schedule('Small Platform Schedule Job', GetSchedulerExpression(DateTime.Now().addMinutes(10)), new ScheduledDispatcher()); } }
global class KeysBatch implements Database.Batchable<sObject>, Database.AllowsCallouts { private string query = ''; public KeysBatch(string query) { this.query = query; } global Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator(query); } global void execute(Database.BatchableContext BC, List<c2g__codaInvoice__c> invoices) { for (c2g__codaInvoice__c i : invoices) { try { } catch(Exception e) { } } } } global void finish(Database.BatchableContext BC) { if (!Test.isRunningTest()) ScheduleHandler.StartScheduler(); } }
global class ScheduledDispatcher Implements Schedulable { public Interface IScheduleDispatched { void execute(SchedulableContext sc); } global void execute(SchedulableContext sc) { Type targettype = Type.forName('ScheduleHandler'); if(targettype!=null) { system.debug('Inside Scheduler'); IScheduleDispatched obj = (IScheduleDispatched)targettype.NewInstance(); obj.execute(sc); } } }
You can send the mail in the finish method to get the results, like how many records processed, total count, error count. For this you ned to implement Database.Stateful in your batch class. Below is a sample code: Here in to Address you can add as many email addresses as you want. Let me know, if you need any other help.
Thanks,
Neetu