Is there always a need to do the kill cron job after scheduling it?
Instead can I just schedule a one time job?
If so, what is the difference in syntax between a recurring job and a one time job?
You can schedule a job with a specific set cron string, e.g. 0 0 0 21 MAY ? 2022
to run something exactly at midnight tonight (at the time of this answer). After the job runs, it will be flagged as Completed and will not run again nor count against the 100 scheduled jobs governor limit. It is otherwise identical to a recurring job, but will contain no wildcards except for "day of week", which will be set to "?" ("do not care"). If you want to schedule a one-off batch job, you can also use System.scheduleBatch
, which schedules a batch job to run after a specified number of minutes, and never again.
I realize this has been answered for sometime, but I think my findings will be useful to others and are too long to fit into a comment.
I found that running System.schedule
with a cron string defined like 0 0 0 21 MAY ? 2022
actually schedules the job to run once per year. That is, when you specify a specific year value versus a year range. Looking at the SF docs and Quartz docs it seems like passing a single year value shouldn't be supported at all, but this is the behavior I've observed.
The good news is that System.scheduleBatch
works as desired. However only for batch classes and not schedulable classes. In my case, I needed to dynamically instantiate various job types, both schedulable and batchable. I was happy to find that casting to (Database.Batchable<SObject>)
is possible in my scenario and allows for use of the scheduleBatch
method with reflection & dynamic types. Here is a toy example:
public class myWrapper implements Schedulable {
// does important stuff
}
public class myScheduler {
public static void runNow(String name) {
Type curBatchType = Type.forName(name);
myWrapper myJob = (myWrapper) curBatchType.newInstance();
if (myJob instanceof Database.Batchable<SObject>) {
System.scheduleBatch((Database.Batchable<SObject>)myJob, 'Job Name', 1);
}
}
}