I'm working on a custom approval flow where a user can mass approve or reject records from a LWC data Table. Then using the Approval class in the Apex controller to update the record in the approval process.
When load testing I've run in to a issue that I can only mass approve/reject around 180 records. Anything greater than this I hit a CPU error. I've run the code with the Account flows and Triggers inactive and this has not made any difference. I've noticed the largest use of the CPU occurs updating the approval records via Approval.process().
Has anyone else come across this problem, or any suggestions on how to improve/increase the number of records that can be handled via Approval.process()?
The approval process is a shell and has no workflows assigned to approval or rejection actions.
Example CPU times. 2e to 2f is where the records enter the Approval Class:
Code that uses the Approval class to process the records:
public static List<Approval.ProcessResult> approveRejectRecords(Set<ID> targetObjectIds, String comments, String action, String processDeveloperName) {
String sMethodName = 'approveRejectRecords';
System.debug(UtilityApexHelper.prepareDebug(CLASS_NAME, sMethodName, true) + ' targetObjectIds.size() <' + targetObjectIds.size() +
'> + action <' + action + '>' + 'processDeveloperName <' + processDeveloperName + '>' );
String thisMethod = 'approveRejectRecords';
String status;
String actionVal = action == SUSPEND ? 'Approve' : 'Reject';
System.debug('*** CPU 2a *** ' + Limits.getCpuTime());
List<Approval.ProcessWorkitemRequest> approvalRequests = new List<Approval.ProcessWorkitemRequest>();
List<Approval.ProcessResult> results = new List<Approval.ProcessResult>();
Id approvalProcessId = [SELECT Id FROM ProcessDefinition WHERE DeveloperName =: processDeveloperName LIMIT 1].Id;
System.debug(UtilityApexHelper.prepareDebug(CLASS_NAME, sMethodName) + ' approvalProcessId <' + approvalProcessId + '>');
System.debug('*** CPU 2b *** ' + Limits.getCpuTime());
Set<Id> pInstanceIdSet = (new Map<Id, ProcessInstance>([SELECT Id, Status, TargetObjectId
FROM ProcessInstance
WHERE Status = 'Pending'
AND ProcessInstance.ProcessDefinitionId =: approvalProcessId
AND TargetObjectId = :targetObjectIds WITH SYSTEM_MODE])).keySet();
System.debug(UtilityApexHelper.prepareDebug(CLASS_NAME, sMethodName) + ' pInstanceIdSet.size() <' + pInstanceIdSet.size() + '>');
System.debug('*** CPU 2c *** ' + Limits.getCpuTime());
Set<Id> pInstanceWorkitemSet = (new Map<Id, ProcessInstanceWorkitem>([SELECT Id,ProcessInstanceId
FROM ProcessInstanceWorkitem
WHERE ProcessInstanceId = :pInstanceIdSet WITH SYSTEM_MODE])).keySet();
System.debug(UtilityApexHelper.prepareDebug(CLASS_NAME, sMethodName) + ' pInstanceWorkitemSet.size() <' + pInstanceWorkitemSet.size() + '>');
System.debug('*** CPU 2d *** ' + Limits.getCpuTime());
for(Id eachpInstanceWrkItem :pInstanceWorkitemSet) {
Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
req.setComments(comments);
req.setAction(actionVal);
req.setWorkitemId(eachpInstanceWrkItem);
approvalRequests.add(req);
}
System.debug('*** CPU 2e *** ' + Limits.getCpuTime());
try {
results = Approval.process(approvalRequests,false);
} catch(Exception e) {
LogException.addLog(CLASS_NAME, thisMethod, e);
}
System.debug('*** CPU 2f *** ' + Limits.getCpuTime());
return results;
}