Martin Ivanov
Giga Sage
Giga Sage

Background

Looking at the ServiceNow native processes, one can easily see that big portion of them are event-based, rather than synchronous. This is especially true for the processes which are not critical to the user experience or the ones which are not dependencies of other business logic.

In a nutshell, an event is logged in a queue and when system resources are available, the event is picked up and processed by the associated Script Action.

 

Below is a simple visual representation of the process along with explanation (source: Steven Bell) : 

MartinIvanov_0-1699438734284.png

0. I register my new event in the Registry, create my Script Action associated to that event, and if needed my Script Include which could be called by the Script Action. Registering my event tells the Worker to listen for that event, and that it will be expected to do something with it.

1. Something executes a gs.eventQueue statement which writes an event record on the queue. BTW, this is not an exhaustive list.

2,3,4. The event worker(s), whose job it is to listen for events listed in the Registry, picks up the event and sees if there is a Script Action(s) associated with the registered event.

5,6. If a Script Action is found to run then it is executed which in turn may execute my Script Include if I choose.

 

Remember the info message when adding a role to a user or a group:

MartinIvanov_1-1699438734285.png

 

What’s happening behind – an event is logged to the queue and the roles are added to the group in the first possible moment, when the system has resources for that. Usually this is near real-time, but in case of higher priority operations are already queued, this will wait till they free up some processing power.

 

Now if one is implementing an application, based on synchronous logic, occupying almost all the system resources, this may lead to performance implications, slowing down the instance tremendously.

 

One possible approach in such cases is to shift from synchronous processing to event-based processing, which will lead to better performance.

 

But since events are being logged (unless another queue is explicitly specified) to the default queue, we might run into performance issues again.

 

Here comes the custom queue implementation. It is nothing more than a separate queue to which events can be queued explicitly, leveraging the fifth parameter of gs.eventQueue() API (more on that later).

 

Implementation

 

The implementation process is similar with the normal event-based logic implementation. We need to have:

  • An event registered in the event registry
  • A Business rule or any other logic to fire the event
  • A Script action to process the event
  • Custom queue processor

I will not discuss the first three, because these are pretty straightforward, and docs are easily available.

Custom queue processor implementation

The easiest way to create a processor for a custom queue is to:

  • go to System Scheduler -> Scheduled Jobs -> Scheduled Jobs
  • find a job with Trigger type = interval (i.e. ‘text index events process’)

MartinIvanov_2-1699438734288.png

 

  • change the name (it can be anything) replace ‘text_index’ with the name of your custom queue inside the fcScriptName=javascript\:GlideEventManager(<HERE>).process(); line
  • set Next action to be in the near future, i.e. 30 seconds from the current moment (This is very important in order to get the job running)

MartinIvanov_3-1699438734291.png

 

  • (optional) edit the Repeat interval (short repeat interval may have some negative impact on the system performance, but at the same time, the lower the repeat interval, the sooner your event will be queued and processed)
  • Right click -> Insert and stay! Do not Save/Update!

You can have one or more custom queues, depending on the purpose. These must be aligned with the system resources – nodes, semaphores, workers. I will not go deeper on these, more information can be found in the Resources chapter below.

Logging an event to a specific (custom) queue

gs.eventQuque() API accepts 5 parameters:

  • Event name
  • GlideRecord object
  • Param1
  • Param2
  • (optional) queue

This fifth optional parameter ‘queue’ is the one that tells the system to which event queue an event should be logged.

We can log an event to the custom queue we have created above (‘custom_queue_one’) we can use the following line of code:

gs.eventQueue('event.name', grSomeObject,  null, null, ‘custom_queue_one’);

 

NB: queue name (fifth parameter) must be exactly the same as the one we’ve passed to the GlideEventManager during the process creation above.

 

Everything else (script actions, etc. is the same like in a normal event logging)

 

Good practices

  • Just because you can, doesn’t mean you should – this implementation is applicable only to cases where huge amounts of records must be processed (see Performance chapter)
  • Naming is important, give your names and processor readable names
  • For optimal performance, multiple custom queues can be created to handle a particular event. In this case, the event logging must be done in a way that ensures even distribution between the queues. To better organize these, one possible approach can be to:
    • Create a script include, holding an array with the names of your event queues
    • Use the following line of code to randomly distribute events to the queues:

gs.eventQueue('event.name', grSomeObject,  null, null, event_queues[Math.floor(Math.random()*event_queues.length)]);

where event_queues is an array containing the names of your queues

 

Performance

  • Even though we implement this approach to achieve performance, for low number of transactions it does not yield any performance gain, because of the Repeat interval – the longer it is, the slower will be the overall wait time
  • For large number of transactions (thousands of records), the achieved performance gain can be really significant. In one of my implementations, I was able to achieve 30x faster execution.

 

More information

 

Comments
Harshit Sharma1
ServiceNow Employee
ServiceNow Employee

whats the job id and its use in scheduled job record? 

Version history
Last update:
‎11-08-2023 04:13 AM
Updated by:
Contributors