0

I have a schedulable class that will be rescheduled again. This class contains a count.

Here is how it is supposed to work

  1. constructor set count to 0
  2. a run method increase count then test condition
  3. if count > 1 (= if this is not the first run) then schedule trigger is aborted.
  4. instance is rescheduled every x min until a certain hour

This way i keep my daily scheduled job, but I delete every rescheduled job

My problem is : for some days I know that, instead having a count from 0 to 1, I have a count from 1 to 2. There is no reason for it (well, there must be a reason but I can't figure it out). To debug it I use some custom class that send me an email every time the increase method is used so I know the value of the count.

Please can you help me to figure this out ?

Or I will use another code : use a static formated label for reschedule only and use it in a query to delete scheduled jobs. But I would prefer to understand what goes wrong, this "bug" is driving me crazy !

public ExternalCallImportScheduler(Integer nbMinutesToReschedule, Integer closingHour, String period,String queuePrefix,String title){
    system.debug('Custom constructor: period="'+period+'" ; queuePrefix="'+queuePrefix+'" ; title="'+title+'"');

    if(nbMinutesToReschedule == null || closingHour == null) throw new CException('None of those parameters can be null: nbMinutesToReschedule(1st)="'+nbMinutesToReschedule+'" ; closingHour(2nd)="'+closingHour+'"');
    if(nbMinutesToReschedule < 1) throw new CException('nbMinutesToReschedule (1st) parameter cannot be < 1: nbMinutesToReschedule="'+nbMinutesToReschedule+'"');
    if(closingHour < 1 || closingHour > 23) throw new CException('closingHour (2nd parameter) must be included from 1 to 23');

    if(period == null || queuePrefix == null || title == null){
        throw new CException('None of those parameters can be null: period(3rd)="'+period+'" ; queuePrefix(4th)="'+queuePrefix+'" ; title(5th)="'+title+'"');
    }

    this.nbMinutesToReschedule=nbMinutesToReschedule;
    this.closingHour=closingHour;

    this.period=period;
    this.queuePrefix=queuePrefix;
    this.title=title;
    this.result=new ExternalCallImportBatch.ProcessResult();

    this.runCount = 0;
}

global void schedule(Integer schHour, Integer schMin){
    try{
        String sch = '0 '+schMin+' '+schHour+' * * ? *'; // every day chron + hour / min
        String jobID = system.schedule('ExternalCallImportScheduler daily '+schHour+':'+('00'+schMin).right(2), sch, this);
    } catch(Exception e){
        IncidentReport.create('Import ExternalCallsBatch/Schedule - Exception aborting job', 'WombatDialerRcrtCampaignLeadTrtmtBatch.schedule()', 'Exception:\n'+e.getMessage());
    }
}

global void execute(SchedulableContext SC) {
    run(SC.getTriggerId());
}

global void run(String jobId) {
    system.debug('ExternalCallImportScheduler.run() RUNNING with parameter jobId="'+jobId+'"');
    //runCount ++;
    increaseRunCount();
    system.debug('ExternalCallImportScheduler.run() count is now:'+runCount);

    try{
        if(DateTime.now().hour() >= closingHour){
            if(runCount == 1) this.runAction = new ActionFirstAndLastRun (this,jobId);
            else this.runAction = new ActionFinalRun(this, jobId);
        } else{
            if(runCount == 1){
                this.runAction = new ActionInitialRun(this,jobId);
            } else{
                this.runAction = new ActionDefaultRun(this, jobId);
            }
        }

        Boolean willExecuteFinishHitself = runAction.run();
        if(!willExecuteFinishHitself) runAction.finish(null);

    } catch(Exception e){
        system.debug('Exception: '+e.getMessage());
        IncidentReport.create('Import ExternalCallsBatch/Schedule - Exception aborting job', 'WombatDialerRcrtCampaignLeadTrtmtBatch.runBatch()', 'Exception:\n'+e.getMessage());
    }
}

private void increaseRunCount(){
    String log = 'runCount was:'+runCount;
    this.runCount++;
    log += ' ; now:'+runCount;
    // comment this after tests are done
    if(this.runCount<5) IncidentReport.create('Import ExternalCallsBatch/Schedule - increaseRunCount()'+title, 'ExternalCallImportScheduler.increaseRunCount()', log);
}

And here are the emails I get :

  • runCount was:1 ; now:2
  • runCount was:2 ; now:3
  • runCount was:3 ; now:4

So the incrase method is working fine, but something is happening between initializaton and this. runCount is not used anywhere except here...

Thanks

1 Answer 1

0

I may have an anwser. I still need to test.

This is how I did it :

  1. I schedule and reschedule this code for "today" from 8am to 8pm.
  2. I schedule an "emergency" run for "yesterday" at 1am the day after

It is supposed to be 2 distinct instance of my class so they shouldn't share the runCount attribute.

I removed the scheduled emergency run and reschedule a "clean" normal daily run =>

  1. this morning I had the debug email saying runCount was:0 ; now:1
  2. tomorrow run is still scheduled

It wouldn't be logic 2 different instance of a class share an attribute but honestly I don't remember how I scheduled them.

As I said I still need to test it to be sure it was an initialization/run mistake.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .