using concurrent** (Service) - ** Maintains a collection of named 'ActorPools'. Use to keep tabs on your resources, particularly ** useful when creating 'SynchronizedMap' and 'SynchronizedList' instances.** ** 'ActorPools' is automatically made available in IoC enabled applications. ** Contribute to 'ActorPools' via 'AppModule' contributions:** ** pre>** syntax: fantom** @Contribute { serviceType=ActorPools# }** Void contributeActorPools(Configuration config) {** config["myPool"] = ActorPool() { it.name = "MyPool" }** }** <pre ** ** Note it is always a good idea to name your 'ActorPools' for debugging purposes.** ** @uses Configuration of 'Str:ActorPool'constmixin ActorPools {** Returns the 'ActorPool' mapped to the given name, or throws a 'IocErr' / 'NotFoundErr' if it doesn't exist. @Operatorabstract ActorPool get(Str name)** Returns a map of 'ActorPool' names and the number of times it's been requested. abstract Str:Int stats()** Creates an 'ActorPools' instance. Use in non-IoC environments. staticnew make(Str:ActorPool actorPools){ ActorPoolsImpl(actorPools)}}internalconstclass ActorPoolsImpl : ActorPools {const Str:ActorPool actorPoolsconst Str:AtomicInt usageStatsnew make(Str:ActorPool actorPools){this.actorPools = actorPools counts := Str:AtomicInt[:] actorPools.keys.each |k| { counts[k] = AtomicInt()}this.usageStats = counts} @Operatoroverride ActorPool get(Str name){ pool := actorPools[name] ?: throw ActorPoolNotFoundErr("There is no ActorPool with the name: ${name}", actorPools.keys) usageStats[name].incrementAndGetreturn pool}** Returns a map of 'ActorPool' names and the number of times it's been requested. override Str:Int stats(){ usageStats.map {it.val }}}@NoDocconstclass ActorPoolNotFoundErr : ArgErr {const Str?[] availableValuesnew make(Str msg, Obj?[] availableValues, Err? cause := null) : super(msg, cause){this.availableValues = availableValues.map {it?.toStr }.sort}}