Teneo Developers

Static Data in Teneo Solutions

Within Teneo, any property defined as static will be shared across all sessions running on a single publish endpoint. Therefore static must only be used for unchanging information applicable to all sessions.

DO NOT store any session-specific information in a static property - it will cause undesired behavior and can be a data security risk (user session A having access to the data from user session B). Session-specific information should be stored in session scoped variables (e.g. Global variables in Studio).

DO use static final properties, static getter methods or lazy loaded static getter methods (use the thread safe Lazy<T> class - see more on this below) for storing information that is the same for all sessions. This reduces the memory footprint (same information in memory only once), reduces the session log size (static class properties are not written to session logs).

DO NOT use static properties to share ongoing/changing/state information between sessions. An external data store must be used for this. SaaS production deployments have load balanced engines and therefore static would share only between the sessions running in a single engine instance - there would be ~3 different ideas of "current state".

What is a static property?

The static keyword defines that there should only be 1 instance of the property in the entire scope of the running application. In Teneo all sessions running in a single engine (publish target) are in the same application - and therefore same scope. This means that all sessions will share the same property value if a property is set as static.

Defining a static property in Teneo is done in a class in a Solution Loaded script inside a solution:

groovy

1// Solution Loaded
2class StaticDataExample {
3	static final String someObject = new Object()
4}
5

Using a static property in Teneo is done from within any script via a reference to the class:

groovy

1// Script node
2if(otherObject != StaticDataExample.someObject) {
3    // do something
4}
5

How to / approaches

Shared session specific things

For shared session-specific things - DO NOT USE static.

Since all static data is shared across all sessions using static properties for session-specific data will cause errors.

In this example, a class is defined to store the user ID for the session - however, this user ID at runtime would actually be the same for all sessions because it is declared as static. All sessions would see the user ID of the most recently started session as each call to Begin Dialog will overwrite the previous value.

groovy

1// Solution Loaded
2class UserData_BadExample {
3	static String userId = ""
4//	^^^^^^ DO NOT DO THIS! 
5}
6

groovy

1// Begin Dialog
2UserData_BadExample.userId = _.getProperty('userId')
3

For shared session data, use a Global variable storing an instance of a shared data class.

groovy

1// Solution Loaded
2class UserData_GoodExample {
3    String userId = ""
4}
5

groovy

1// Global variable "userData" default value
2new UserData_GoodExample()
3

groovy

1// Begin Dialog
2userData.userId = _.getProperty('userId')
3

Share fixed things: static final

Where some field needs to be referred to multiple times and the value is the same for every session, use static final.

This will share the same data across all sessions (reduced memory footprint) and prevent the value being changed (error at runtime on attempting to write to the property).

groovy

1// Solution Loaded
2class StaticDataExample {
3	static final String productCodeRegex = /[IE][ABC][0-9]{4}/    // eg. EC1234
4}
5

groovy

1// Pre-processing
2def productCodes = _.userInputText =~ StaticDataExample.productCodeRegex
3

Shared changeable things

For Shared changeable things - DO NOT USE static.

There are some scenarios where sessions may want to share transient information. If this is the case then an external data store/service must be used. static properties must NOT be used for this purpose.

Sessions running in the same engine instance (publish target) will share static scope data. However, there are no guarantees that all sessions for a publication share a static scope, so any "shared state" in static properties can not be guaranteed to be shared between all sessions.

In fact in SaaS production environments there are multiple load balanced engines for scaling and resilience. As such in production SaaS environments it is guaranteed that "shared state" in static properties is NOT shared between all sessions. Do not assume that something working with shared state in a dev publication (single publish target) will therefore work in QA/Prod (multiple load balanced publish targets), it will not.