Linking CronTrigger and AsyncApexJob objects after rescheduling.

Linking CronTrigger and AsyncApexJob objects after rescheduling.

This post is continuation of my previous post https://patlatus.wordpress.com/2014/01/03/automating-the-process-of-cancelling-and-rescheduling-scheduled-jobs-in-salesforce/ about automating the process of cancelling and rescheduling scheduled jobs in Salesforce. I mentioned there that if I used my current implementation which doesn’t wait a second between rescheduling two scheduled jobs in a row, it can cause some obstacles or bugs. Here I consider possible implementation which would wait a second between two consecutive calls to System.schedule, what would allow us to reuse existing technique to link CronTrigger and AsyncApexJob objects joining them on CreatedDate. Please refer to my previous post for more details on that.

Assume we have two scheduled jobs which refer to the same class implementing Schedulable interface.
Then we can’t distinguish their AsyncApexJob class instances from each other if they have been scheduled in the same second.

One way of solution could be following. Schedule jobs one by one, and each time make SOQL Query to retrieve current AsyncApexJob instances existing in the database.
This would be ineffient since we can easily exaust 100 SOQL query limit per transaction or hit other limits.

Assume also other situation. Imagine that the user has scheduled some jobs, then opened my page, canceled all of them and rescheduled all of them.
If the user removes all my custom records keeping information about relationships between CronTrigger and AsyncApexJob objects, then my page would lose all information and would try again to match up these records, but this time it will fail since all the records were created by script in the same second.

The common solution for both problems which wouldn’t hypothetically exaust 100 SOQL query limit is to wait a second between scheduling jobs.
However, this would hit a limit for 10 seconds of CPU time if we had at least ten scheduled jobs.
So we can make a check of scheduled jobs count.
If we have less then 10 jobs to schedule then we can just do it inline.
If we have more then 9 jobs to schedule but less then 60 we can call the same code from future method.
If we have more then 59 jobs to schedule then we have to use another scheduled job to schedule these jobs.
I am going to test this solution on one of my developer instances.

By the way, one more interesting thing that I have found. Like correction.
Initially I assumed that it is possible to schedule only one scheduled job with specified class implementing Schedulable interface.
I was deceived by error message appearing if someone is trying to schedule job which duplicated existing job name: “Error: This Apex class is already scheduled for execution.”
However, it is not actually looking at apex class, only at scheduled job name.
So, if I choose another class and give it the same name as one of the already scheduled jobs name it wouldn’t allow me to schedule this (!another) class.
On the other hand, if I chooose the same class and give it another job name, it will allow me to schedule that class again.
So I suggest to change this misleading error message to something like: “Error: You have already scheduled job with the same job name”.
There is here link to my suggestion on success.salesforce.com: https://success.salesforce.com/ideaView?id=08730000000kzXuAAI .
Please vote for it if you agree with me.

This entry was posted in Posts in English, salesforce and tagged , , , , , , , , , , , , , , , . Bookmark the permalink.

2 Responses to Linking CronTrigger and AsyncApexJob objects after rescheduling.

  1. Pingback: Package for canceling and rescheduling schedulable jobs | patlatus

  2. Pingback: patlatus

Leave a comment