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.

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.