Update Batch Run Status Records After an Abort

Change the state of Batch Run Status records that stay in the Running state after an abort.

An abort does not update the Batch Run Status records of the stopped run. They stay in the Running state. This step is optional. CG Cloud does not do it for you.

The Batch_State__c field is a restricted picklist. Its values are Running, Error, Done, and Fatal. No value means aborted. The closest value for a stopped run is Fatal.

Run this update only after step 2 returns 200.

Which Records to Update

A job chain worker controls two kinds of records.

  • Job chain controller records have a Batch_Name__c value that starts with ProcessQueueWorker_.
  • Job records have a Job_Name__c value that starts with JobChainWorker:, such as JobChainWorker:Promotions.

The query uses two limits.

  • A created date limit. The batch reads only records created on or after the date that you choose. This keeps the batch from reading the full history.
  • An idle time limit. The batch reads only records whose Last_Update_Date__c is older than the number of minutes that you choose. A running job chain worker updates this field about once a minute, so a running chain is never changed.

The query does not filter by sales org. One job chain worker runs the chains of all sales orgs on a platform. After an abort, stale records can belong to any of those sales orgs.

Apex Batch Class

public class JobChainAbortCleanupBatch implements Database.Batchable<SObject> {
    private final Datetime createdFrom;
    private final Datetime staleCutoff;

    public JobChainAbortCleanupBatch(Datetime createdFrom, Integer staleMinutes) {
        this.createdFrom = createdFrom;
        this.staleCutoff = System.now().addMinutes(-1 * staleMinutes);
    }

    public Database.QueryLocator start(Database.BatchableContext ctx) {
        return Database.getQueryLocator([
            SELECT Id
            FROM cgcloud__Batch_Run_Status__c
            WHERE cgcloud__Batch_State__c = 'Running'
              AND CreatedDate >= :createdFrom
              AND cgcloud__Last_Update_Date__c < :staleCutoff
              AND (cgcloud__Batch_Name__c LIKE 'ProcessQueueWorker%'
                   OR cgcloud__Job_Name__c LIKE 'JobChainWorker:%')
        ]);
    }

    public void execute(Database.BatchableContext ctx, List<cgcloud__Batch_Run_Status__c> scope) {
        for (cgcloud__Batch_Run_Status__c brs : scope) {
            brs.cgcloud__Batch_State__c = 'Fatal';
        }
        update scope;
    }

    public void finish(Database.BatchableContext ctx) {
        System.debug('JobChainAbortCleanupBatch finished.');
    }
}

The class uses the cgcloud namespace for objects and fields.

Run the Batch

This example reads records created in the last 7 days. It updates records that were idle for more than 10 minutes.

Datetime createdFrom = System.now().addDays(-7);
Database.executeBatch(new JobChainAbortCleanupBatch(createdFrom, 10), 200);