2

I'm looking to implement a class that I can schedule every 5 minutes. This class will carry out some basic monitoring activity. But in order to know what to monitor, my scheduled class will need to keep some minimum amount of data in order to maintain state.

As recommended by sfdcfox, I could store most of my data in a record. But I'd need some sort of ID/key to access that record, and THAT needs to persist across executions.

I've referenced this link for handling the 5 minutes scheduling (is this the only way? Seems tedious...), however I'm not sure how to maintain state. If I initialize an object of the schedulable class by passing some data to the constructor and storing it in instance variables, can I access that as and when I want? For example:

global class SchedulableClass implements Schedulable 
{
    private String p1;
    private String p2;

    global SchedulableClass(String p1, String p2) {
        this.p1 = p1;
        this.p2 = p2;
    }

    global void execute(SchedulableContext ctx) {
        System.debug(p1);
        System.debug(p2);
    }
}

...and now

SchedulableClass s = new SchdulableClass('test1', 'test2');
System.schedule('...', chronExp, s);

Thanks for the help.

1 Answer 1

5

For Schedulable, if you need to maintain state, you can always use System.abortJob and System.schedule. Namely, you can use "this" to reschedule yourself. Here's a simple implementation that simply remembers how many times it has successfully executed:

public class FiveMinuteScheduler implements Schedulable {
    Integer timesExecuted = 0;
    public static void initialize() {
        new FiveMinuteScheduler().schedule();
    }
    public void schedule() {
        System.schedule('FiveMinuteScheduler', '0 '+System.now().addMinutes(5).minute().format()+' * ? * *', this);
    }

    public void execute(SchedulableContext sc) {
        timesExecuted++;
        System.abortJob(sc.getTriggerId());
        schedule();
    }
}

Keep in mind that the Schedulable's state is serialized at the moment System.schedule is called, so make sure that you have the state you want before calling System.schedule; ideally, this should be the last thing that you do. Also, no error handling is included here, so make sure that you do add any appropriate error handling.

5
  • Amazing! One question though, what does sc.getTriggerId() do? Can I use that as my record key for maintaining state?
    – coldspeed
    Jan 17, 2017 at 6:43
  • 1
    @Shiva getTriggerId returns an Id appropriate for aborting the current job. It's not a useful object for storing your own state information. You can store almost any type of data you want in your class' instance variables. timesExecuted is my "state" that I'm maintaining. You could use whatever kind of data you wanted to, or even store data in a custom setting.
    – sfdcfox
    Jan 17, 2017 at 6:47
  • I understand. So with this, the example code I've written in my question would work without issues right?
    – coldspeed
    Jan 17, 2017 at 6:52
  • @Shiva Yes, you can use a new instance with parameters, or by reusinf this, whicheer you prefer.
    – sfdcfox
    Jan 17, 2017 at 6:57
  • Salesforce has such a painful learning cure. It's nice to know that there are helpful people like you out there ready to share their expertise. Thanks again :)
    – coldspeed
    Jan 17, 2017 at 6:59

You must log in to answer this question.

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