Recursive Scripting in ServiceNow

tahnalos
Kilo Sage

I'm trying to ascertain the feasibility of a recursive code script.

Long story short, we are trying to link dependant tickets together using a single reference field on the Task form.  We link a task as "dependant" if we require actions from that Task to be completed first.  But it's also possible that the "dependant task" itself also has a dependancy.

The idea that I have is to have a script include look at the dependant task, then call itself again to look at further dependancies, thus trying to determine how far the level of dependency tasks go.  This would link into other functionality that we have in the works, but a ServiceNow rep has suggested that the code may be flagged as "problematic" by ServiceNow itself, considering that this may result in a long running time depending on how deep the dependant tasks go.  Business has suggested that with current practices, this should go no longer than 5-deep, but the ServiceNow rep is insistent that we abandon that approach.

Can someone tell me how a recursive script can be labelled as "problematic"?  It isn't the same as a recursive business rule which does a current.update () on a before rule, so I'm not sure how the dependency search would be an issue.  Or does anyone else have an alternative as to what I am trying to do?

Thanks

9 REPLIES 9

Madhav18
Mega Expert

Hi Tahnalos,

I may not be the right person from ServiceNow to comment on script that can be labelled as "problematic". But below script might give you some idea to reduce multiple recursion calls by leveraging Dot-Walking.

var num = "TASK0010311"; //Task you want to find dependent tasks for.
var child = ""; //To store Child task details.

child = findChild(num);

function findChild (num){
	var gr = new GlideRecord("sc_task");
	gr.addQuery("active",true );
	gr.addQuery("number",num);
	gr.addNotNullQuery("dependant"); //Proceeding only if there is a dependent
	gr.query();
	if (gr.next()) {
		//Levaraging Dot Walking to reduce multiple script executions.
		if(gr.dependant.dependant.dependant){ //Using only 3 levels as ServiceNow's recommended limit for chain length is 3 levels.
			//3rd child is there. Finding if there are any sub childs.
			num = gr.dependant.dependant.dependant.getRefRecord().getValue('number');
			var value = findChild(num); //Using Recursion. But with no longer than 5-deep, we are using recursion only ONCE.
			return value;
		}else if(gr.dependant.dependant){
			//only 2nd child is there
			num = gr.dependant.dependant.getRefRecord().getValue('number');
			return num; //Use whatever data you want from that record.
		}else{
			//only one child is there
			num = gr.dependant.getRefRecord().getValue('number');
			return num;
		}

	} else{
		//No dependent Tasks for given Task "TASK0010311".
		return num; //Return Same task
	}
}


Please note the script is for reference purpose only, to give you some idea. I didn't tested it, so make sure to test it in dev Instance with proper log statements to fix any existing bugs.

If it helps, please mark Correct and 👍 Helpful.


Thanks & Regards,
Madhav

I'm not sure if I agree with this approach.  For our business, we need this to be as open as possible, and doing a hard limit of 3 interferes with that.  Which is why I'm trying to figure out to do this without resorting to having to do deep level recursion.

Tony Chatfield1
Kilo Patron

Hi,

if I recall correctly I thought I had seen recursive script somewhere in OOB code, but could have been mistaken? I see nothing wrong with properly (sensibly) implemented (low count) recursive function.

I believe the platform has some inbuilt functionality to prevent an infinite loop;
Running a simple loop in a background window results in most queries terminating early, across a wide iteration range (most counts in the 900-980 range, but some as low as 750) so perhaps time related.

I checked the logs for 1 early termination and it had no clear explaination.
SEVERE *** ERROR *** Problem processing asynchronous servlet request
java.lang.StackOverflowError


But I also had 1 test that did hit a hard stop.
'Evaluator: org.mozilla.javascript.RhinoStackOverflowException: Maximum JavaScript call depth of 1000 exceeded'

var i = 0;
var recur = function() {
i++
gs.info("myLoopTest " + i);
recur();
}

var letsGo = recur();

 

Perhaps configure and test for a never to be encountered scenario IE 200 iterations;

Then if it's only 5-10 iterations and your code test fine in a dev environment, I would consider it a viable solution.

 

DrewW
Mega Sage
Mega Sage

So the reason they are telling you it can be "problematic" is because of the danger of getting into an infinite loop.  ServiceNow does health checks that flag items that can be issues or do not follow there best practice and he/she is just warning you that it may get flagged.  But if its something you need to do then you need to do it and if it does get flagged just note why it was done and move on.