jonallenaz
10/17/2018, 4:23 PM/*
* checkUsage() checks the remaining usage units and time elapsed
* If either does not meet threshold requirements, nlapiYieldScript() is called to reset usage
* and continue where the script left off.
*
* Author: Jon Allen
*/
function checkUsage(usage_threshold, message) {
time_threshold = 55; // maximum script running time in minutes
usage_threshold = (usage_threshold || 100) + 100;
message = message || '';
var remaining_usage = global_context.getRemainingUsage();
var current_time = new Date();
var elapsed_time = ((current_time - global_start_time) / 60000).toFixed(2); // elapsed time in minutes
if (remaining_usage < usage_threshold || elapsed_time >= time_threshold) {
s_log.audit({title: 'Usage Remaining is Below Set Threshold of ' + usage_threshold, details: 'remaining_usage: ' + remaining_usage + (message ? ' message: ' + message : '') + ' -- elapsed_time: ' + elapsed_time + ' minutes' })
global_start_time = new Date();
setRecoveryPoint();
s_log.debug({title: 'nlapiYieldScript', details: 'Attempting to Yield Script...'});
var state = nlapiYieldScript();
// state.status will never be SUCCESS because a success would imply a yield has occurred. The equivalent response would be yield
if (state.status == 'FAILURE') {
s_log.error({title: 'nlapiYieldScript', details: "Failed to yield script, exiting: Reason = " + state.reason + " / Size = " + state.size});
throw "Failed to yield script";
} else if (state.status == 'RESUME') {
s_log.audit({title: 'nlapiYieldScript', details: 'Resuming script because of ' + state.reason + '. Size = ' + state.size});
}
}
return {points: remaining_usage, minutes: elapsed_time};
}
function setRecoveryPoint() {
if (typeof SCRIPT_RESCHEDULED != 'undefined'){
SCRIPT_RESCHEDULED = true;
}
s_log.debug({title: 'setRecoveryPoint', details: 'Setting Recovery Point...'});
var state = nlapiSetRecoveryPoint(); //100 point governance
if (state.status == 'SUCCESS') return; //we successfully create a new recovery point
if (state.status == 'RESUME') { //a recovery point was previously set, we are resuming due to some unforeseen error
s_log.error({title: 'Resuming script because of ' + state.reason + '. Size = ' + state.size});
handleRecoveryFailure(state);
} else if (state.status == 'FAILURE') { //we failed to create a new recovery point
s_log.debug({title: 'Failed to create recovery point', details: state.reason + " / Size = " + state.size});
handleRecoveryFailure(state);
}
}
function handleRecoveryFailure(failure) {
s_log.error({title: 'handleRecoveryFailure', details: 'Failed: ' + JSON.stringify(failure)});
if (failure.reason == 'SS_MAJOR_RELEASE') throw "Major Update of NetSuite in progress, shutting down all processes";
if (failure.reason == 'SS_CANCELLED') throw "Script Cancelled due to UI interaction";
if (failure.reason == 'SS_EXCESSIVE_MEMORY_FOOTPRINT') throw "Exceeded Memory Footprint";
if (failure.reason == 'SS_DISALLOWED_OBJECT_REFERENCE') throw "Could not set recovery point because of a reference to a non-recoverable object: " + failure.information;
}