Scripting Double For Loops, safe or unsafe?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-11-2017 09:38 AM
I have a form with two selection fields that are used as types. Each combination of these two fields represents one entry, so it has been set up so that no two entries have the same combination of these two fields. One selection field has about 50 choices, the other has about 60. Meaning that I have about 3000 total entries in this form.
This form is used to spin out an analysis that is saved onto a third form so that it can be downloaded via an integration. For this, I run a background script that has two for loops, one for each selection field, with one for loop nested under another so as to run for all 3000 entries. Each for loop refers to the elements of an array, and for testing purposes, each array was constructed using the choice list of the selection field being used.
While I have no issues with regards to the code that saves onto the third form, I'm noticing that the for loops are not running as expected. What I'm finding that is happening is that for the first iteration of the first for loop, it runs the second for loop effectively and just stops. It doesn't run through the other iterations per the for loop definitions. Despite putting the second for loop into a separate function and calling that, it just runs through the first iteration of the first for loop and then stops. If I remove the actual running code and put in logging statements to track how many iterations it goes through the loop, it does run 3000 times.
One of my possible hypotheses is the fact that I am doing a GlideRecord lookup for each iteration, modifying value of some of the fields, then doing an update on the record itself. The update triggers a business rule on the record that does a whole boatload of stuff. A delay of 2000 has been put in after each upgrade, this was used to test. What I'm wondering is whether the business rule that is triggering the boatload of stuff is running too long to the point that it does not finish before the delay is up and that the script simply stops after that. I was also advised by someone that the for loop ignores the sleep function and just goes to the next iteration, the sleep function is meant for the record being updated, not the general flow.
Ideas on how to handle this?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-11-2017 10:21 AM
For this, I run a background script
Any chance of seeing the code?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-11-2017 11:31 AM
updateE1Stage ();
function updateE1Stage ()
{
var sx_list = [list of stuff];
var ms_list = [list of more stuff];
for (i = 0; i < ms_list.length; i++)
{
var mstype = ms_list [i];
gs.log (mstype);
for (x = 0; x < sx_list.length; x++)
{
var sxn = sx_list [x];
updatetarget (mstype, sxn);
}
}
}
function updatetarget (mtype, sx)
{
gs.log (sx);
var gr = new GlideRecord ('u_host_e1');
gr.addQuery ('u_e1_reference.u_parent_sx.u_target_code', sx);
gr.addQuery ('u_host_stage', 'NOT IN', 'host_complete,host_freeze,host_rollback,host_cancelled,none');
gr.query ();
while (gr.next())
{
gs.log ('before: ' + gr.u_e1_reference.u_parent_sx.u_target_code + ' ' + mtype);
var ms = new GlideRecord ('u_beta_target');
ms.addQuery ('u_host_e1_reference', gr.sys_id);
ms.addQuery ('u_target.u_mtype', mtype);
ms.addQuery ('u_marker_task', true);
ms.addQuery ('state', 1);
ms.query();
if (ms.next())
{
gs.log ('middle: '+ gr.u_e1_reference.u_parent_sx.u_target_code + ' ' + ms.u_target.u_mtype);
if (ms.u_target.u_mtype == 'Update Allocate LA/UN Target')
{
var la_un1 = new GlideRecord ('u_beta_la_un');
var la_un2 = new GlideRecord ('u_beta_la_un');
if (!la_un1.get ('u_e1_host', gr.sys_id))
{
la_un2.initialize();
la_un2.u_la_un_not_required = true;
la_un2.insert();
}
}
else if (ms.u_target.u_mtype == 'Update Assign Build Target')
{
var cm1 = new GlideRecord ('u_beta_build');
var cm2 = new GlideRecord ('u_beta_build');
if (!cm1.get ('u_e1_host', gr.sys_id))
{
cm2.initialize ();
cm2.u_build_manager = <hard coded value>;
cm2.insert();
}
}
gs.log (ms.u_target.u_mtype + ' ' + mtype);
ms.state = 3;
ms.update();
gs.sleep (10000);
}
gs.log ('after: '+ gr.u_e1_reference.u_parent_sx.u_target_code + ' ' + mtype);
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-11-2017 11:39 AM
I want to point out that at the line ms.update(); that triggers a business rule that supposedly takes some time to run due to its impact on workflow attached to a different form in question. Previously, it was flagged as an unsafe recursive rule that I resolved by adding conditions to the rule to prevent it from unnecessarily running. This is why I have a gs.sleep (10000) to allow all rule processing for the update to complete. A little excessive but I have found that this is the only way to get it through one iteration.
If I remove the updatetarget call, it goes through the loop normally, and I had logging statements previously there to confirm that. But with the updatetarget call, it seems to want to proceed through a few values of the i loop before stopping completely. At least that's what I see in the logs.