Article
· Aug 9, 2016 2m read

Tips & Tricks - Process-private Globals as a class storage

Process-private Globals  can be used as a data global in storage definition. That way, each process can have its own objects for the class with ppg storage. For example lets define a pool, which can:

  • add elements to a pool (ignoring duplicates)
  • check if an element exists in the pool

Here's the class:

/// Stores unique identifiers
Class Utils.Pool Extends %Persistent
{

Property Value As %String;

Index IDKEY On Value [ IdKey, PrimaryKey, Unique ];

Method %OnNew(Value As %String = "") As %Status [ Private, ServerOnly = 1 ]
{
    Set ..Value = Value
    Quit $$$OK
}

ClassMethod Add(Value As %String = "")
{
    Quit:..%ExistsId(Value)
    Set Obj = ..%New(Value)
    Do Obj.%Save()
}

Storage Default
{
<Data name="PoolDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
</Data>
<DataLocation>^||Utils.PoolD</DataLocation>
<DefaultData>PoolDefaultData</DefaultData>
<IdLocation>^||Utils.PoolD</IdLocation>
<IndexLocation>^||Utils.PoolI</IndexLocation>
<StreamLocation>^||Utils.PoolS</StreamLocation>
<Type>%Library.CacheStorage</Type>
}
}

And the testing code:

/// Do ##class(Utils.Pool).Test()
ClassMethod Test()
{
    Do ..%KillExtent()
    Do ..Add(1)
    Write "Is 1 in pool: ", ..%ExistsId(1),!
    Write "Is 2 in pool: ", ..%ExistsId(2),!
    Do ..Add(2)
    Write "Is 2 in pool: ", ..%ExistsId(2),!
}

Outputs:

Is 1 in pool: 1
Is 2 in pool: 0
Is 2 in pool: 1 

This approach can be used if you  want:

  • Storage space, inaccessible to other processes (without using locks, etc)
  • Store something only while process lives

The code is also available on GitHub.

Discussion (2)0
Log in or sign up to continue

Unfortunately in times when web-applications prevail other types of applications this approach is cannot be widely used. This way can't be used directly in CSP, because of by default any session could be joined to any process, but Procces-private globals is not session-provite globals. And If you need to have such functionality with CSP, you should use Preserve sessions or use something like Sessions-private global, something like this

^CacheTemp.SomeTableD($select($isobject($get(%session)):%session.SessionId,1:$job))