const classafIoc::ConcurrentState
sys::Obj afIoc::ConcurrentState
A helper class to store and retrieve state between threads; use in const
classes. For IoC this means your services can be declared as perApplication
or singleton scope and still hold useful data.
In Java terms, the getState() { ... }
method behaves in a similar fashion to the synchronized
keyword, only allowing one thread through at a time.
ConcurrentState
wraps a state object in an Actor, and provides access to it via the withState
and getState
methods. Note that by their nature, these methods are immutable boundaries. Meaning that while all data in the State object can be mutable, but data passed in and out of the methods can not be.
ConcurrentState
has been designed to be type safe, that is you cannot accidently call methods on your State object. The compiler forces all access to the state object to be made through the withState
and getState
methods.
A fully usable example of a mutable const map class is as follows:
const class ConstMap { const ConcurrentState conState := ConcurrentState(ConstMapState#) ** Note that both 'key' and 'value' need to be immutable @Operator Obj get(Obj key) { getState |ConstMapState state -> Obj?| { return state.map[key] } } ** Note that both 'key' and 'value' need to be immutable @Operator Void set(Obj key, Obj value) { withState |ConstMapState state| { state.map[key] = value } } } class ConstMapState { Obj:Obj map := [:] }
As alternatives to ConcurrentState
don't forget you also have AtomicBool, AtomicInt and AtomicRef
- getState
virtual Obj? getState(|Obj?->Obj? f)
Use to return state, effectively wrapping the given func in a Java
synchronized { ... }
block.- makeWithStateFactory
new makeWithStateFactory(|->Obj? stateFactory)
- makeWithStateType
new makeWithStateType(Type stateType)
The given state type must have a public no-args ctor as per sys::Type.make
- withState
virtual Future withState(|Obj?->Obj? f)
Use to access state, effectively wrapping the given func in a Java
synchronized { ... }
block. Callget()
on the returnedFuture
to ensure any Errs are rethrown.