Introduction

Before using api.local or api.global, check if you can create an element for that purpose.

The api.global and api.local are hashmaps that are populated in the memory of each server node. Variable api.local is initialized to an empty Map before calculation of every item while api.global is (if the api.retainGlobal variable is set to true) initialized to an empty Map before the calculation of the first item. Old projects: If the api.retainGlobal variable is not set, then api.global behaves the same way as api.local and therefore it is deprecated practice and api.local should be used.

Calculation Flows Specifics

api.global persists between Calculation Flow (CF) logic executions and is stored within the globalFormulaState property of the CF object. If you do not want to share the global cache between logic executions, use the api.local instead, or add api.retainGlobal = false at the beginning of CF logics.
Note: api.global data in Calculation Flows (in the globalFormulaState property) is stored as a String. Use the jsonDecode(String) to convert it back to the Groovy object (a Map).

Example:


 def cf = api.find(
     "CF",
     Filter.equal("uniqueName", "ScheduleCalculations"),
     Filter.equal("draft", "false")
 ).first()

 def config = api.jsonDecode(cf.configuration).entries.get(0)?.globalFormulaState

 return config.lastCalculationDate


Usage examples are documented at Caching Strategies in Configuration.

If any of the variables api.global or api.local holds a lot of data, these variables should not be returned as an element result since the data gets usually persisted for each calculated record.

api.global

By setting api.retainGlobal = true you can instruct the formula engine to keep the hash map in between logic runs. It works between line items and, in case of Quotes, Agreements/Promotions, Rebate Agreements and Claims, between the header and the line items (but only in the pre-phase, not in the post-phase). The values are also carried forward between two list calculation passes (i.e., form initial run to dirty item run; ONLY in non-distributed mode.).

Remember that for distributed calculations api.global is populated on each server node and each thread independently. So if you store there the results of some data queries, those queries will get executed on every node (and not once as one may think).

You should always:

When api.global should not be used:


For old projects created before Manhattan 4.0 release: make sure api.retainGlobal is set to true by default. Since if not set, the variable to true in the first element of the logic; otherwise the value of api.global will get lost. This was a common error that caused performance issues when values which should be cached for all items were calculated for every item.


(info) See also:

api.local

Before using api.local, consider creating a new element (possibly with the Display option = None) and store the value there. Performance-wise it is identical since both api.getElement and api.local are represented by HashMaps. You will also debug the value more easily: as elements result(s) of a logic test. You also will not need to call api.trace to debug the value. Last but not least, it will also help you avoid potential naming clash of the api.local key.

So api.local should be used only in the following scenarios:

When api.local should not be used: