Marty Zigman Marty Zigman
Prolecto Labs Accelerator Templates

Solve for Simultaneous NetSuite Scheduled or Map/Reduce Script Deployments

Infrastructure NetSuite Technical



This article is relevant if you are working with NetSuite with scheduled or map/reduce scripts and you seek to gain control over multiple executions.

Background

In our NetSuite Systems Integration Practice, we write many scheduled scripts. More and more, we use the Map/Reduce pattern to work NetSuite business records. In these types of NetSuite programs, there are times that we want our logic to be fired on-demand, or on the back of saving business records (via UserEvents) while we also want our logic to run in a scheduled manner.

An approach we use to achieve this objective is to create two deployments of the script:

  1. Scheduled: this deployment is set up to run at a regular frequency and controlled during configuration.
  2. Unscheduled: this deployment is set so that we can call the script on-demand or on the back of UserEvents.

There are situations where you don’t want the script running at the same time. The idea is that there is a set of work to do and you don’t want a script running simultaneously on the same set of work. In these cases, you need a strategy to address the situation.

Detect if a NetSuite Scheduled Script is Already Running

I want to thank Boban D., a senior member on our team for bringing this concern forth and offering the following SuiteScript 2.0 function. This JavaScript can be used to have your Scheduled script detect if it is already running in another deployment. If so, then you have an opportunity to stop processing business logic on the newly created instance that is now running in parallel with the already running script.

function anotherDeploymentIsExecuting() {
	var ss = search.create({
		type:		record.Type.SCHEDULED_SCRIPT_INSTANCE,
		filters:    [
						["status","anyof","PENDING","PROCESSING","RESTART","RETRY"]
						,"AND",
						["script.scriptid",search.Operator.IS,runtime.getCurrentScript().id]
						,"AND",
						["scriptDeployment.scriptid",search.Operator.ISNOT,runtime.getCurrentScript().deploymentId]
					],
		  columns:	["status", "script.internalid"]
	}).run().getRange(0,1);
	return (ss.length > 0);
}

Work with NetSuite Technology Experts

Our NetSuite Systems Integration Practice allows us to see so many client situations. Accordingly, our expertise deepens to drive the NetSuite platform to solve our clients’ concerns.

If you found this article helpful, feel free to sign up to receive notifications of new articles as I post them. If you would like to be appreciated for your talent and leadership in the NetSuite domain, let’s have a conversation.

Marty Zigman

Holding all three official certifications, Marty is regarded as the top NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 30 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

More Posts - Website - Twitter - Facebook - LinkedIn - YouTube

About Marty Zigman

Marty Zigman

Holding all three official certifications, Marty is regarded as the top NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 30 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

Biography • Website • X (Twitter) • Facebook • LinkedIn • YouTube

4 thoughts on “Solve for Simultaneous NetSuite Scheduled or Map/Reduce Script Deployments

  1. Stefan Reeder says:

    HI Marty,

    Thought i’d share a solution i came up with.

    Had a scenario that require M/R to handle some billing, that needed any user to be able trigger at anytime…

    Few steps…

    First the suitelet creates a “queue” record with some basic info. ie. SO numbers, email addresses etc… stored in a JSON string in a Long Text field

    Second… first M/R triggers after step one, and this M/R actually builds the process queue based on the JSON string/array in step one. A “process record” for each transaction being processed. This allows dupe check/remove handling here.

    Here’s the important bit.. in the Summary phase on step 2, run another search to see if any extra “queue” JSON records have been created (ie. simultaneous users triggering stuff).

    If any more found, in the summary phase, trigger the same M/R to repeat again. THIS IS ALLOWED AND WORKS BEAUTIFULLY.

    When no more “queue” JSON data is found, then the summary phase can trigger the ACTUAL processing M/R script to do the work based on a search of “process queues”

    Same thing in summary phase, check if there are any new “process” records, and trigger the M/R again, if not… it ends.

    This creates a looping solution which allows the queue to be “topped” up mid process, and in turn allows unlimited processing within a single thread.

  2. Marty Zigman says:

    Hello Stefan,

    Thanks for that pattern and the use of the Summarize step to check a queue. Helpful!

    Marty

  3. Keep up the great work!

    Here’s a similar function that uses half the governance by calling runPaged() and can handle any arbitrary script instead of only the current one.


    function isExecuting(scriptId, deploymentId) {
    const executingStatuses = ["PENDING","PROCESSING","RESTART","RETRY"];
    return Boolean(search.create({
    type: record.Type.SCHEDULED_SCRIPT_INSTANCE,
    filters: [
    ["status", search.Operator.ANYOF, executingStatuses], "AND",
    ["script.scriptid", search.Operator.IS, scriptId] ,"AND",
    ["scriptDeployment.scriptid", search.Operator.ISNOT, deploymentId]
    ],
    columns: ["script.internalid"]
    }).runPaged().count);
    }

  4. Marty Zigman says:

    Hi Eric,

    I like it! Condensed and clean.

    Marty

Leave a Reply

Your email address will not be published. Required fields are marked *