Object Pooling
Nidus provides a thread-safe generic object pool (TObjectPool<T>) and a TComponent variant. Pooling eliminates repeated allocation of expensive objects under high concurrency.
Registering a pool
Generic objects
GetNidus
.UsePools<TMyHeavyResource>(128) // max pool size = 128
.Start(TAppModule.Create);
This calls TPoolRegistry.RegisterDefaultObjectPool<TMyHeavyResource>(128) internally.
TComponent subclasses
GetNidus
.UsePools<TMyDbConnection>(32, AOwner,
procedure(C: TMyDbConnection)
begin
C.Reset; // called before returning to pool
end)
.Start(TAppModule.Create);
Or the equivalent alias:
GetNidus.UseComponentPool<TMyDbConnection>(32, AOwner, ResetProc);
Custom registry
Provide your own IPoolRegistry implementation:
GetNidus.UsePools(TMyPoolRegistry.Create);
Acquiring and releasing objects
Via WithPool
The safest pattern — automatically acquires and releases around the callback:
GetNidus.WithPool<TMyHeavyResource>(
procedure(R: TMyHeavyResource)
begin
R.DoWork;
end);
With a named key (when multiple pools exist for the same type):
GetNidus.WithPool<TMyHeavyResource>('v2',
procedure(R: TMyHeavyResource)
begin
R.DoWork;
end);
Source: TNidus.WithPool<T> delegates to TPoolHelpers.WithPool<T> (Nidus.Pooling.Helpers).
Via IPoolRegistry directly
var LPool := GetNidus.Pools;
var LObj := LPool.Acquire<TMyHeavyResource>;
try
LObj.DoWork;
finally
LPool.Release(LObj);
end;
Pool internals
TObjectPool<T> wraps a TQueue<T> protected by a TCriticalSection. Behaviour:
Acquire: dequeues an existing instance if available; otherwise callsT.Create.Release: enqueues the instance ifCount < MaxSize; otherwise frees it.MaxSizedefaults to 256 for object pools, 32 for component pools.
Source: Nidus.ObjectPool — TObjectPool<T>, TObjectPoolAdapter<T>.
Accessing the pool registry
var LRegistry := GetNidus.Pools; // returns IPoolRegistry
SetGlobalPoolRegistry / GetGlobalPoolRegistry manage the global singleton.
Source: Nidus.Pooling.Interfaces.