Today is one of the days when I thought it would be a good idea to look in to some research on cleaning up some scripts.

In particular scripts that don’t clean up properly after themselves. I am sure that there are Lawson staff that look at some of the scripts here and shake their heads – in particular ones where they are automating the entry of multiple lines of data.

The instances where I tend to do this have been on programs where people will tend to close the program once the script has run and the script itself won’t recurse too many times – so the negative effects are fairly minor. But there comes a time when you really need to sit down and have a good look at how you should handle these situations.

As I have previously posted, whenever we do just about any operation in LSO, the Init() method gets called as the script is re-attached to the window. In theory after each operation you should be cleaning up your script – removing any event handlers etc. This of-course creates problems if you are interating through a list or trying to enter multiple lines of data.

The clever developers at Lawson – err…Infor recognised this fact and provided SessionCache and InstanceCache.

Sadly the documentation on what they actually do is pretty, well…poor is an understatement…“The SessionCache is a helper class for scripts that can be used to cache items in the MForms session.”

“The InstanceCache is a helper class for scripts that can be used to cache items for a specific MForms instance.”

Ok, what are we defining as an instance and a session?

So, how do we find out? Write a script 🙂

In short, Session Cache survives the closing of the window that the script is associated with. InstanceCache does not. This is the Window being closed, so if you have a script associated with OIS300 and you right click on an entry and it takes you in to the Order Lines (OIS101) the window is NOT closed, so the InstanceCache won’t be reset.

So now that we have that cleared up, I guess that we should start cleaning up those broken scripts eh? 😉

To prove this I have created a script to test the behaviours of the Session Cache and the Instance Cache and attached it to OIS300 (it is a deployed script).

I run OIS300 and get this – at this point because my script does all the work in the Init() method the OIS300 window won’t open until after I click on OK.

Now I close OIS300. Then I run OIS300 and get the following message

We can see that the SessionCache is at 2 now. But the Instance Cache is 1.

We will click Ok to allow OIS300 to display.

Next we will press F5 to refresh OIS300 – this will cause the Init() method to be called again and we get another messagebox.

Now we can see the SessionCache has incremented AND the InstanceCache has incremented.

If we do an open related to open the order lines (which goes to OIS101), and then hit the previous button we will get the messagebox pop up again

So we can see that both cache objects have incremented.

Anyway, here’s the script, commented as per usual and you can test to your hearts content 🙂

3 Responses to SessionCache and InstanceCache

Scott — both of these are pretty powerfull features. I’ve used instancecache specifically when trying to ‘remember’ settings from one panel to another. Its a shame infor didn’t have a dictionary attached to the program/ panel however instancecache works a treat – bit like the session cache in asp.net 🙂 , Paul

As a Smart Office developer: InstanceCache lives as long as the IInstanceController that you get in the script so it is for one “window” so to say. SessionCache is pretty straight forward. The reason we did not have a dictionary to the program/panel is that the two other caches are capable of storing the information you need 🙂 If you need a Dictionary per program/panel, store a dictionary, or you could use a composite key and a wrapper method, the variations are endless…

I can only imagine that there are lot of data that you get with APIs that are valid for one IInstanceController or even for one session…

Cleaning up in scripts is a must. It is not only your script that lingers around, you could prevent the entire window from being garbage collected. That will show after running an hour or two…

To prevent more missunderstandings I post this entry.
I have investigated this script issue and found that there are a few bugs in the test script above, most obvious is that two varables are both named “key”.
After correcting the test script to the code below no leakage of caches could be detected by the script.
Do note that checking for number of instance caches this way is not likely to detect any leakage as the counter is stored in the instance cache. I did the code this way to make minimal modifications to the original code.

// do we already have a SessionCache saved?
if(SessionCache.ContainsKey(keySession))
{
// yes; we should retrieve that value in to our counterSessionCache
// variable. We will add one to it shortly and save it again
counterSessionCache = SessionCache.Get(keySession);
}
else {
// add 1 to the session cache counter
counterSessionCache++;
// save these values
SessionCache.Add(keySession, counterSessionCache);
}

// do we already have an InstanceCache saved?
if(InstanceCache.ContainsKey(controller, keyInstance))
{
// yes; we should retrieve that value in to our counterInstanceCache
// variable. We will add one to it shortly and save it again
counterInstanceCache = InstanceCache.Get(controller, keyInstance);
}
else {
// add 1 to the instance cache counter
counterInstanceCache++;
// save these values
InstanceCache.Add(controller, keyInstance, counterInstanceCache)
}