If part of a managed package I would provide a UI for them to schedule, cancel, etc. I would also make the scheduled and batch class public and not global so the user could not schedule it outside of the ui.
How complicated the UI is is up to you. This is an example UI to illustrate what I mean:
by storing the job Id you can provide for the ability to cancel.
When initially running you would simply use system.scheduleBatch
with the minutes being 1 and the batch will run in 1 minutes, then the finish method handle the rescheduling.
As for scheduling every 15 minutes, you can do that in the finish method using system.scheduleBatch
and use 15 as the minutes criteria. Essentially the first run kicks off the process. Since you will need the job Id to cancel, you will need to manage that Id as well and update it when you schedule the next batch.
It all depends on how much control you want to have over the process......
To do it using a CRON expression you would need 4 expressions and schedules to do it every 15 minutes..
UPDATE
All of the above is nice but what if you just want a simple answer.
I have done the following:
- Allow customer to schedule batch using UI
- In the Scheduler Class in the execute I abort the job
- In the finish method of the batch class I use
system.scheduleBatch
to run in 15 minutes
End result, customer use UI to initially schedule batch, schedule aborts itself after first run, batch takes over and schedules every 15 minutes
Schedule Class
global class ExampleScheduler implements Schedulable{
global void execute(SchedulableContext sc) {
ExampleBatch batch = New ExampleBatch();
database.executeBatch(batch);
//Cancel schedule
CronTrigger ct =
[SELECT Id,
CronExpression
FROM CronTrigger
WHERE Id = :SC.getTriggerId()];
System.abortJob(SC.getTriggerId());
}
}
Batch Class
global class ExampleBatch implements Database.Batchable<sObject> {
global Database.QueryLocator start(Database.BatchableContext BC) {
String query = 'Select ID From Account';
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope) {
//Do Stuff
}
global void finish(Database.BatchableContext BC) {
if(!test.isRunningTest()) system.scheduleBatch(New ExampleBatch(),'Run again in 15',15);
}
}
Best Answer
You can run a batch with five minutes between each execution using
system.scheduleBatch
by chaining it in your finish method. It won't run every five minutes, because it also takes some time to execute.You'll want to add some sort of kill switch so your batch is possible to test.