Skip to main content
1-Visitor
March 8, 2021
Solved

How to optimize a recursive service

  • March 8, 2021
  • 1 reply
  • 3016 views

Greetings.

I'm trying to build a service to call the BrowseGroups service from the root of a channel and then recursively call it on all of its subgroups (if they're not a System group) until they've all been visited and then return them in an InfoTable.

So, for example, I'd call the service on "HiProfile_LBR" and it would then call itself on "HiProfile_LBR.HiProfile" and so on... 

aiGreek_0-1615202148815.png

(I collapsed the groups, but the channel in the example has more levels than what's shown in the image.)

 

This is the code I've written at the moment:

 

var query = {
 "filters": {
 "type": "EQ",
 "fieldName": "IsSystemGroup",
 "value": "true"
 }
};
var tempTable, unionParams, groupTable;

var newField = new Object();
newField.name = 'Color';
newField.baseType = 'STRING';

groupTable = Things[indConnector].BrowseGroups({
	filter: undefined /* STRING */,
	path: path /* STRING */
});
groupTable.AddField(newField);

//-------------------------------------------------------

groupTable = Resources["InfoTableFunctions"].DeleteQuery({
	t: groupTable /* INFOTABLE */,
	query: query /* QUERY */
});

recBrowse(indConnector, groupTable);
 
function recBrowse(indConnector, groupTable){
 
 /*let debugJSON;*/
	let tableLength = groupTable.rows.length;
	for (let x=0; x < tableLength; x++) {
	 let row = groupTable.rows[x];
	 if(row.Color != "Black"){
	 	row.Color = "Black";
 if(row.HasNonSystemSubGroups){
 	tempTable = Things[indConnector].BrowseGroups({
					filter: undefined /* STRING */,
					path: row.FullPath /* STRING */
				});
 tempTable.AddField(newField);
				
 	 	unionParams = {
					t1: groupTable // INFOTABLE,
					t2: tempTable // INFOTABLE 
 	};
	 	tempTable = Resources["InfoTableFunctions"].Union(unionParams); 
				
 recBrowse(indConnector, tempTable);
 }
	 }
	}
}

var result = tempTable;

 

 

The service unfortunately times out for complex trees (such as the one in the image above) and I have no idea on how to solve this issue. Besides increasing the service time out (to a value at the moment I don't know), how can I solve the issue? How would you optimize my code?

Thank you.

Best answer by aiGreek

Hi @slangley,

I've actually been able to find a work around for the issue. Since the service is meant to run from a mashup, I've changed the code so that the service is restarted via a validator rather than from the code itself. So it shouldn't time out as it restarts through a new "instance".

I don't think a ticket is needed for this case, but thanks anyway.

Regards.

1 reply

Community Manager
March 11, 2021

Hi @aiGreek.

 

Have you checked the logs located in \ThingworxStorage\logs for possible errors?  If it is actually timing out, how much data are you trying to process?

 

Regards.

 

--Sharon

aiGreek1-VisitorAuthor
1-Visitor
March 15, 2021

Hi @slangley,

 

I can't check the log files as the platform is hosted on the PTC Cloud. I did check the ScriptLog from the Monitoring interface and I can confirm it's timing out, as I get this message: Execution of Script terminated after : 42 seconds. Timeout configured for 30 seconds.

The data I'm trying to process at the moment is this channel/device tree on a Kepware (note that PLM2/3/4 and Controller_H2/3/4 have the same underlying structure as PLM1/Controller_H1): 

aiGreek_0-1615797718810.png