Notifications

234 views

Description

A simple background script like below is executed.  The script is expected to be quickly but instead appears to hang the user's session.  

 

~~~snip example~~~
Var delMul = new GlideRecord(‘u_activity_log’);
delMul.addQuery(‘u_status’,’=’,’failed’);
delMul.query();
while (delMul.hasNext()){
delMul.deleteMultiple();
}
~~~/snip~~~

 

The background script execution is only known to be continuously running background script is known to be running is that new data meeting the script condition is not being written to the table.  The background script transaction (a call to sys.scripts.do) is not shown with Active Transactions (All nodes) or within /stats.do.

 

For all intents and purposes, the script gives no other indication of continued execution. It appears as defunct.

 

Release or Environment

Any modern release of the platform.

Cause

While this is a simple example script, it was coded by hand and was different than many other simple scripts used for data cleanup.  The key difference is that this time, the scripts utilizes a Glide Record hasNext() condition instead of next().

 

Please read up more on the details of gr.next at the below API reference guide on the ServiceNow developer website:
https://developer.servicenow.com/app.do#!/api_doc?v=newyork&id=r_GlideRecord-next

And compare the above to the API reference guide entry for hasNext():

https://developer.servicenow.com/app.do#!/api_doc?v=newyork&id=r_GlideRecord-hasNext

 

 

next()
Moves to the next record in the GlideRecord.

Use this method to iterate through the records returned by a GlideRecord query.

Note: This method fails if there is a field in the table called "next". If that is the case, use the method _next().

Note: The if(myObj.next()) construct only processes the first record returned.

 

Versus:

 

hasNext()
Determines if there are any more records in the GlideRecord.

Consistency across all API ref topics is critical. Follow the template exactly or the importer script will fail.




Resolution

Use Glide Record next() instead of hasNext().

Additional Information

Only after reaching the 4 hour mark was ServiceNow able to find that "defunct" background script as a result of an internal platform reaper mechanism which terminates long-running database SQL. 

 

The following entry was spotted in the application node logs from the node on which the user executed the background delete script.

 

Here is a sample of the log file 

 

~~~snip~~~
[somehost.sjc201:/glide/nodes/somenode063_16010/logs]$ grep 2523342 localhost_log.$(date +"%Y-%m-%d").txt


2019-12-10 10:49:05 (208) http-31 New transaction EC2498FEDB6148106D4F340FAA961915 #2523342 /sys.scripts.do
2019-12-10 10:49:05 (217) Default-thread-11 EC2498FEDB6148106D4F340FAA961915 txid=bc41d603dbad #2523342 /sys.scripts.do Parameters -------------------------
2019-12-10 10:49:05 (217) Default-thread-11 EC2498FEDB6148106D4F340FAA961915 txid=bc41d603dbad *** Start #2523342 /sys.scripts.do, user: USERXYZ
2019-12-10 14:49:05 (416) glide.quota.manager SYSTEM WARNING *** WARNING *** Transaction: Cancelling transaction #2523342 /sys.scripts.do (maximum execution time exceeded): Thread Default-thread-11 (USERXYZ, EC2498FEDB6148106D4F340FAA961915), after 14400208ms
2019-12-10 14:49:05 (421) glide.quota.manager SYSTEM Attempting to cancel MySQL request for transaction [2523342]
2019-12-10 14:49:05 (421) glide.quota.manager SYSTEM Issuing cancel SQL for transaction [2523342]: kill query 529338
2019-12-10 14:49:05 (475) Default-thread-11 EC2498FEDB6148106D4F340FAA961915 txid=bc41d603dbad EXCESSIVE *** End #2523342 /sys.scripts.do, user: guest, total time: 4:00:00.267, processing time: 4:00:00.267, SQL time: 3:58:39.068 (count: 224,506), ACL time: 0:00:00.001, source: 98.6.11.10 null
~~~/snip~~~

Carefully observe the 4-hour period at which the background script action was terminated.

Article Information

Last Updated:2019-12-16 09:14:34
Published:2019-12-16