I have a scheduled class that calls a Queueable class which does an api callout. What seems to be happening is once the scheduled class is done setting up all of the queueable classes to run, they all run too close together and breaks the system. Is there a way to either space out the queueable classes or how would I account for the 429 error in the catch?
Here is the Scheduled class:
global void execute(SchedulableContext sc) {
// Query all of the shipstation stores to update their tracking
shipstation_store_credential__c[] sscList = [SELECT name, secret__c, key__c, storeID__c, source__c FROM shipstation_store_credential__c];
// Loop through all of the stores
for(shipstation_store_credential__C ss : sscList){
Shipstation_to_totalSales_Service ws = new Shipstation_to_totalSales_Service(ss.name, ss.key__c, ss.secret__c, ss.storeID__c, ss.source__c, '1');
System.enqueueJob(ws);
}
}
}
Here is the Queable class:
public class Shipstation_Service implements Queueable,Database.AllowsCallouts{
public void execute(QueueableContext context) {
try{
if(source == 'Shopify'){
tsList =[
SELECT
id,
External_Id__c,
Source__c,
Sent_To_Shipstation__c,
tracking_number__c,
channel_detail__c
FROM total_sales__c
WHERE Source__c = :source AND channel_detail__c = :name AND tracking_number__c = null
ORDER BY CreatedDate DESC];
String responseBody = getCalloutResponse();
ShipppedShipments trackingShipments = (ShipppedShipments) System.JSON.deserialize(responseBody, ShipppedShipments.class);
processOrdersUpdate(trackingShipments);
}else{
String responseBody = getCalloutResponse();
ShipppedShipments completeShipments = (ShipppedShipments) System.JSON.deserialize(responseBody, ShipppedShipments.class);
processOrdersUpsert(completeShipments);
}
} catch(exception e){
string message = 'ERROR DESERIALIZING RESPONSE' + '\n ERROR=' + e.getMessage();// Displays an Error message in log if above did not work correctly
system.debug(message);
}
}
/**************************************************************************
* Method used to run the GET method and recieve the Shipmentlist as a JSON
**************************************************************************/
public String getCalloutResponse(){
Http http = new Http();
HttpRequest request = new HttpRequest();
String endpoint = 'https://ssapi.shipstation.com/shipments?storeId='+storeID+'&shipDateStart='+ shippingdate+'&shipDateEnd='+shippingdate+'&includeShipmentItems=true&page='+currentPage;
request.setEndpoint(endpoint);
request.setMethod('GET');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
String username = key;
String password = secret;
Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
request.setHeader('Authorization', authorizationHeader);
request.setTimeout(60000);
HttpResponse response = http.send(request);
system.debug('Response Status Code:'+ response.getStatusCode());
system.debug('Response Body:'+ response.getBody());
return response.getBody();
}
/***************************************************************************
* Method used to find the corresponding totalsales record and update it with the tracking number
****************************************************************************/
public void processOrdersUpdate(ShipppedShipments trackingShipments){
list<total_sales__c> ordersToUpdate = new list<total_sales__c>();
for(cls_shipments shipment :trackingShipments.shipments){
if(shipment.voided == false){
for(cls_shipmentItems item : shipment.shipmentItems){
String shipstationExternalID = shipment.orderNumber + '_' + item.sku;
for(total_sales__c record : tsList){
if(record.external_id__c == shipstationExternalID){
record.tracking_number__c = shipment.trackingNumber;
ordersToUpdate.add(record);
break;
}
}
}
}else{
continue;
}
}
try {
update ordersToUpdate;
Integer currentPageNum = integer.valueOf(trackingShipments.page);
Integer totalPagesNum = integer.valueOf(trackingShipments.pages);
if(currentPageNum < totalPagesNum){
Integer nextPageNum = currentPageNum + 1;
String nextPage = String.valueOf(nextPageNum);
Shipstation_to_totalSales_Service ws = new Shipstation_to_totalsales_Service(name,key, secret, storeID, source, nextPage);
System.enqueueJob(ws);
}
}catch (DmlException e) {
System.debug(e.getMessage());
}
}
/***************************************************************************
* Method used to create a new total sales record from the shipsation information
* if it does not already exist
****************************************************************************/
public void processOrdersUpsert(ShipppedShipments trackingShipments){
list<total_sales__c> ordersToUpsert = new list<total_sales__c>();
for(cls_shipments shipment :trackingShipments.shipments)
{
if(shipment.voided == false)
{
String[] customerName = shipment.shipTo.name.split(' ');
for(cls_shipmentItems item : shipment.shipmentItems)
{
total_sales__c ts = new total_sales__c();
ts.address_1__c = shipment.shipTo.street1;
ts.address_2__c = shipment.shipTo.street2;
ts.channel__c = 'Website';
ts.channel_detail__c = name;
ts.city__c = shipment.shipTo.city;
ts.country__c = shipment.shipTo.country;
ts.division__c = 'Black Box';
ts.email__c = shipment.customerEmail;
ts.first_name__c = customerName[0];
ts.fulfillment_type__c = 'E-Com';
ts.item__c = item.name;
ts.last_name__c = customerName[customerName.size() -1];
ts.lob__c = 'Distribution';
ts.major_channel__c = 'POS';
ts.order_number__c = shipment.orderNumber;
ts.postal_code__c = shipment.shipTo.postalCode;
ts.price__c = item.unitPrice;
ts.qty__c = item.quantity;
ts.sales_type__c = 'B2C';
ts.shipping_amount__c = shipment.shipmentCost;
ts.sku__c = item.sku;
ts.source__c = source;
ts.state_provence__c = shipment.shipTo.state;
ts.total_sales__c = item.unitPrice;
ts.transaction__c = 'Purchase';
ts.external_id__c = shipment.orderNumber + '_' + item.sku;
ts.tracking_number__c = shipment.trackingNumber;
ordersToUpsert.add(ts);
}
}else{
continue;
}
}
try {
upsert ordersToUpsert external_id__c;
Integer currentPageNum = integer.valueOf(trackingShipments.page);
Integer totalPagesNum = integer.valueOf(trackingShipments.pages);
if(currentPageNum < totalPagesNum){
Integer nextPageNum = currentPageNum + 1;
String nextPage = String.valueOf(nextPageNum);
Shipstation_to_totalSales_Service ws = new Shipstation_to_totalsales_Service(name,key, secret, storeID, source, nextPage);
System.enqueueJob(ws);
}
}catch (DmlException e) {
System.debug(e.getMessage());
}
}
}```