5

I am developing a Queueable class to send data to an external system via HTTP callouts. I am planning to chain this class to call itself multiple times, until all records have been processed, or until I hit some limit for re-queue to prevent forever running retries. Once all records have been synced (or the re-queue limit has been reached), I will call the next Queueable class in the chain.

My initial thought is that I'd use a static variable to track the queue depth, but this won't work because static variables live inside the current transaction only, so I need some way to share state between Queueable executions to track my current queue depth.

One thing I thought of was to persist this value to the database, but I don't like it because there could be concurrency issues if jobs were to overlap for some reason.

Has anyone else solved this problem, and if so how?

8

The standard approach for this is to pass state via the constructor

class MyQueueable {
  Object state;
  public void execute(QueueableContext qc) {
    // do work using state up to the point where you need to chain queueable
    state = ... // set new state
    System.enqueueJob(state);
  }
  /*  constructor */
  public MyQueueable(Object state) {this.state = state;}
}

I used an Object for state here as a placeholder but you can make it whatever is convenient for you like a collection of Ids (e.g. Id[] work)

1
  • 2
    Constructor, of course! I was clearly over thinking this. Thank you. :) Jul 16 at 18:51
7

A class calling itself can enqueue itself. No need to construct a new object.

public class MyQueueable implements Queueable {
  Integer counter = 0;
  public void execute(QueueableContext context) {
    // If we have not yet run five times...
    if(counter++ < 5) {
      // Go again!
      System.enqueueJob(this);
    }
  }
}

This is a special use case. If you need to call a different queueable and maintain state, you can use a state variable to pass information between contexts, as stated by cropredy in their answer.

1
  • 1
    i should have thought of this (so-to-speak)
    – cropredy
    Jul 17 at 18:03

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.