# system.util.getGlobals() not persisted across Designer Save

**URL:** <https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869>\
**Category:** Ignition\
**Created:** [April 12, 2020, 12:59am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869 "2020-04-12T00:59:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mark.sluser](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mark.sluser/32/19753_2.png) [@mark.sluser](https://forum.inductiveautomation.com/u/mark.sluser)\
**Post date:** [April 12, 2020, 12:59am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/1 "2020-04-12T00:59:39Z")

</div>

I have the following startup script:

```auto
logger = system.util.logger("Scripting.Startup") 
logger.trace("Scripting.Startup --->")

int_1 = system.util.getGlobals().get("int_1")

logger.debug("Scripting.Startup --- int_1 type=" + type(int_1). __name__ )

if int_1 is None:
	int_1 = 0
	logger.debug("Scripting.Startup --- global[int_1] not found, set value=" + str(int_1))
else:
	int_1 = int_1 + 1
	logger.debug("Scripting.Startup --- global[int_1] found. set value=" + str(int_1))

logger.debug("Scripting.Startup --- int_1=" + str(int_1))

system.util.getGlobals()['int_1'] = int_1

logger.debug("Scripting.Startup --- len(globals)= " + str(len(system.util.getGlobals())))

for key, val in system.util.getGlobals().items():
	if key == " __builtins__":
		logger.debug("Scripting.Startup --- globals [" + key + "]=" + "built-in functions")
	else:
		logger.debug("Scripting.Startup --- globals [" + key + "]=" + str(val))

logger.trace("Scripting.Startup<---")

```

See the results on the server.

 ![getGlobals](https://us1.discourse-cdn.com/inductiveautomation/original/2X/d/dabbfdb077e94ddc88643c9eb3a908dd40195abb.png)

Any reasons why system.gui.getGlobals() is not persisting between Designer saves ?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2020, 1:32am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/2 "2020-04-12T01:32:29Z")

</div>

It might be a side effect of legacy scoping in gateway events. Try putting your code in a script module, and referencing a dummy function therein from the startup event to ensure the module loads.

Consider doing something like `g = system.util.getGlobals()` at the beginning, and using `g` everywhere below. Also consider using the python [dictionary method](https://docs.python.org/2.7/library/stdtypes.html#mapping-types-dict) `.setdefault()` to handle the initial value.

---

<div class="post-metadata">

**Author:** ![mark.sluser](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mark.sluser/32/19753_2.png) [@mark.sluser](https://forum.inductiveautomation.com/u/mark.sluser)\
**Post date:** [April 12, 2020, 6:20am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/3 "2020-04-12T06:20:21Z")

</div>

Thank you pturmel for replying, however the problem persists.

As you can see from my screenshot, the value int\_1 is **not** increasing each time I press save from the Designer. I moved the code to a project script called _test1.onStartup()_, replaced _get_ with _setdefault()_ so int\_1 will never be _None_ and used g = system.util.getGlobals().

My startup script is

```auto
logger = system.util.logger("Scripting.Startup") 
logger.trace("Scripting.Startup --->")

test1.onStartup()

logger.trace("Scripting.Startup<---")

```

My project script _test1_

```auto
def onStartup():
	logger = system.util.logger("Scripting.Project.test1") 
	logger.trace("Scripting.Project.test1 --->")

	g = system.util.getGlobals()
	#int_1 = g.get("int_1")
	int_1 = g.setdefault("int_1",0)
		
	logger.debug("Scripting.Project.test1 --- int_1 type=" + type(int_1). __name__ )
	
	if int_1 is None:
		int_1 = 0
		logger.debug("Scripting.Project.test1 --- global[int_1] not found, value=" + str(int_1))
	else:
		int_1 = int_1 + 1
		logger.debug("Scripting.Project.test1 --- global[int_1] found. value=" + str(int_1))
	
	logger.debug("Scripting.Project.test1 --- int_1=" + str(int_1))
	
	g['int_1'] = int_1
		
	logger.debug("Scripting.Project.test1 --- len(globals)= " + str(len(g)))
	
	# send to log all global items
	for key, val in g.items():
		if key == " __builtins__":
			logger.debug("Scripting.Project.test1 --- globals [" + key + "]=" + "built-in functions")
		else:
			logger.debug("Scripting.Project.test1 --- globals [" + key + "]=" + str(val))
	
	logger.trace("Scripting.Project.test1<---")

```

 ![getGlobals2](https://us1.discourse-cdn.com/inductiveautomation/original/2X/b/ba9e8d5f0fa9a9383cb926b9d5921a97d6bcae8c.png)

Any other ideas?

---

<div class="post-metadata">

**Author:** ![PRAMANJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pramanj/32/66935_2.png) [@PRAMANJ](https://forum.inductiveautomation.com/u/PRAMANJ)\
**Post date:** [April 12, 2020, 10:39am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/4 "2020-04-12T10:39:55Z")

</div>

Try using every where system.util.getGlobals()[‘init\_1’] in the code directly in any expression as one variable

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 12, 2020, 12:21pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/5 "2020-04-12T12:21:44Z")

</div>

The globals don’t persist across gateway script restarts.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2020, 3:47pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/6 "2020-04-12T15:47:14Z")

</div>

> [@Kevin.Herron](#):
>
> The globals don’t persist across gateway script restarts.

When did that change? They are utterly useless if they don't persist.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [April 12, 2020, 4:04pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/7 "2020-04-12T16:04:22Z")

</div>

I only took a brief look at the code but it looks like in 7.9 and 8.0 any time a new ScriptManager is created a new globals map is created for that ScriptManager.

Perhaps there’s a difference between how often a project’s ScriptManager is created and re-created between the two? I haven’t really tested anything.

I don’t think the docs have ever claimed that `system.util.getGlobals` persists, it only offers a workaround to the unintuitive behavior of Jython’s `global` in some script scopes.

Haven’t we always told people to use tags for global state that must persist?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2020, 4:14pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/8 "2020-04-12T16:14:24Z")

</div>

> [@Kevin.Herron](#):
>
> new globals map is created for that ScriptManager.

Indeed, but that isn't the globals map that is returned by getGlobals(). getGlobals() returns the globals from legacy scope, which historically has not been reconstructed on script restarts.

> [@Kevin.Herron](#):
>
> Haven’t we always told people to use tags for global state that must persist?

You may have. But it is useless for generic objects, like holding a thread reference or a socket reference for safe replacement on script restarts. Tags also (try to) persist across gateway restarts, while getGlobals() does not. Persisting non-serializable generic objects across restarts is not possible or desired. Some of my v7.9 code is dependent on getGlobals() to avoid memory leaks.

If unbreaking this functionality is not possible, I will create a functional alternative in my Sim Aids module.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2020, 4:28pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/9 "2020-04-12T16:28:25Z")

</div>

Hmm. It would be a separate module, in order to use \<exports…/\> in `module.xml`.

---

<div class="post-metadata">

**Author:** ![mark.sluser](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mark.sluser/32/19753_2.png) [@mark.sluser](https://forum.inductiveautomation.com/u/mark.sluser)\
**Post date:** [April 12, 2020, 4:44pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/10 "2020-04-12T16:44:39Z")

</div>

Ignition doesn’t have a built in scheduler for script execution. I thought Ignition’s BasicExecutionEngine was a solution.

Creating a new BasicExecutionEngine object on each startup loses reference to the old one and the old reference was needed to shutdown the existing scheduled threads. Without the that reference there is no way to stop the old threads and so new threads are duplicated on each gateway restart causing duplicated execution and memory leaks.

My purpose in using getGlobals() was to save a reference to A BasicExecutionEngine as described in this post.

> [@Creating a BasicExecutionEngine schedule](http://forum.inductiveautomation.com/t/creating-a-basicexecutionengine-schedule/27297):
>
> I’m trying to use the BasicExecutionEngine to create a tasks schedule, but I’m having issues (doesn’t help my Java knowledge is lacking). @pturmel ([Does Ignition have schedule events?](http://forum.inductiveautomation.com/t/does-ignition-have-schedule-events/16899/4)) from java.lang import Runnable from com.inductiveautomation.ignition.common.execution.impl import BasicExecutionEngine class Task(Runnable): def run(self): print 'Hellooo' s = BasicExecutionEngine() s.schedule("task", Task, "0-59 \* \* \* \*") I’m receiving the error: Traceback (most recent call last): File…

If getGlobals() can’t save a reference to BasicExecutionEngine is there another way to schedule script execution ?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2020, 4:46pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/11 "2020-04-12T16:46:52Z")

</div>

What version of Ignition are you using?

---

<div class="post-metadata">

**Author:** ![mark.sluser](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mark.sluser/32/19753_2.png) [@mark.sluser](https://forum.inductiveautomation.com/u/mark.sluser)\
**Post date:** [April 12, 2020, 4:48pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/12 "2020-04-12T16:48:06Z")

</div>

The most recent 8.10.

---

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [April 12, 2020, 5:16pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/13 "2020-04-12T17:16:45Z")

</div>

That is the more repliable way. A module with an hashmap to persist data in each scope. Some functions to store and retrieve values. We use this pattern for storing cache data mainly in the client scope. The data are initialized at client startup. As a side note I noticed that in 8.0 all client tags are restored to initial value when client tag is changed in the designer. That make sense because client tags are a single ressource.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2020, 7:35pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/14 "2020-04-12T19:35:09Z")

</div>

Ok. New module “Life Cycle” w/ `system.util.persistent(name)` utility function.

For v7.9: [https://www.automation-pros.com/ignition/Life%20Cycle-0.9.0.2004121825.modl](https://www.automation-pros.com/ignition/Life%20Cycle-0.9.0.2004121825.modl)

For v8.0: [https://www.automation-pros.com/ignition/Life%20Cycle-0.9.0.2004121920-v8.modl](https://www.automation-pros.com/ignition/Life%20Cycle-0.9.0.2004121920-v8.modl)

Test with a project script like this:

```auto
# project script "Life"

g = system.util.persistent('LifeTest')

count = g.setdefault('editCount', -1)
count += 1
g['editCount'] = count

def editCount():
	return count

```

Print the return from `Life.editCount()` in a gateway event.

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [August 6, 2020, 2:20pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/15 "2020-08-06T14:20:36Z")

</div>

Is there any documentation on `system.util.persistent()` functions? how do you delete an item, maybe with _pop()_? Also, is there a way to completely clean a persistent scope, ie `system.util.persistent('LifeTest')`

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [August 6, 2020, 4:16pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/16 "2020-08-06T16:16:56Z")

</div>

I haven’t written docs for that yet. But the return value is a python dictionary, so anything you can do with that is allowed. You are probably looking for the [.clear()](https://docs.python.org/2.7/library/stdtypes.html#dict.clear) method. Once a named dictionary is created, it persists until gateway/client/designer restart.

I deliberately did not expose any iterator for persistent names that have been created. You supply a name, you get a dictionary permanently attached to that name. A `.clear()`'d dictionary is indistinguishable from a new one.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 15, 2020, 12:36pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/17 "2020-09-15T12:36:46Z")

</div>

By the way, the breakage in system.util.getGlobals() ~~has been fixed for v8.1. With the loss of its _«raison-d'etre»_, I'm not planning to update this Life Cycle module for 8.1.~~

Edit: In v8.1 getGlobals() is isolated to a given script scope. So, not the same as v7.9. ~~I will be releasing LifeCycle for v8.1 and maintaining it going forward.~~ `system.util.persistent()` in this module has been superceded by `system.util.globalVarMap()` in my Integration Toolkit module. All users of v8.1+ should migrate.

---

<div class="post-metadata">

**Author:** ![ajacques](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@ajacques](https://forum.inductiveautomation.com/u/ajacques)\
**Post date:** [September 23, 2021, 1:25am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/18 "2021-09-23T01:25:18Z")

</div>

Hi @pturmel - do you have the code for that LifeCycle version 8.1 module anywhere? In GitHub?

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [September 23, 2021, 9:24am UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/19 "2021-09-23T09:24:19Z")

</div>

I think it’s this one:

[https://www.automation-pros.com/ignition/Life%20Cycle-0.9.0.2103311855-v81.modl](https://www.automation-pros.com/ignition/Life%20Cycle-0.9.0.2103311855-v81.modl)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 23, 2021, 12:33pm UTC](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869/20 "2021-09-23T12:33:06Z")

</div>

The source code is not public.

[Next page](https://forum.inductiveautomation.com/t/system-util-getglobals-not-persisted-across-designer-save/33869.md?page=2)
