Compare commits

..

5 Commits
v1.1 ... master

Author SHA1 Message Date
Alexander B 512ce0a83a Set verson to 1.2.1 5 years ago
Alexander B bce2ae2c3a Moved validate check down (fixed error creator not set) 5 years ago
Alexander B f78e00ffdc Merge 5 years ago
Alexander B 57d5c7b17b Set version to 1.2.0 5 years ago
Alexander B 3a6990d17f Added null-check for destructor and health-checker
Added null-check for creator in validate
Simlivied constructor using default values
5 years ago

@ -4,7 +4,7 @@
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
<SignAssembly>false</SignAssembly> <SignAssembly>false</SignAssembly>
<RootNamespace>eu.railduction.netcore.dll.ManagedPool</RootNamespace> <RootNamespace>eu.railduction.netcore.dll.ManagedPool</RootNamespace>
<Version>1.1.0</Version> <Version>1.2.1</Version>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance> <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<DelaySign>true</DelaySign> <DelaySign>true</DelaySign>
<AssemblyOriginatorKeyFile>eu.railduction_assembly-key.pfx</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>eu.railduction_assembly-key.pfx</AssemblyOriginatorKeyFile>

@ -7,25 +7,23 @@ using System.Threading.Tasks;
namespace eu.railduction.netcore.dll.ManagedPool namespace eu.railduction.netcore.dll.ManagedPool
{ {
public class Pool<T> where T : class public class Pool<T> where T : class
{ {
private ConcurrentStack<T> pool = new ConcurrentStack<T>();
private int current = 0, max = 100, min = 10, batch = 5, increaseBuffer = 5, decreaseBuffer = 10;
private Func<T> creator; private Func<T> creator;
private Action<T> destructor;
private Func<T, bool> healthChecker = (T) => { return true; };
#region Attribute declaration
/// <summary>Method to handle item-spawning (needs to return the item-type)</summary> /// <summary>Method to handle item-spawning (needs to return the item-type)</summary>
public Func<T> Creator { get => creator; set => creator = value; } public Func<T> Creator { get => creator; set => creator = value; }
/// <summary>Method to handle item-deleting/killing (needs to take the item-type as parameter)</summary> private Func<T, bool> healthChecker = (T) => { return true; };
public Action<T> Destructor { get => destructor; set => destructor = value; }
/// <summary>Method to handle item-health-checking (useful for unstable items) /// <summary>Method to handle item-health-checking (useful for unstable items)
/// <para/>While running the health-check, the Thread will be blocked!</summary> /// <para/>While running the health-check, the Thread will be blocked!</summary>
public Func<T, bool> HealthChecker { get => healthChecker; set => healthChecker = value; } public Func<T, bool> HealthChecker { get => healthChecker; set => healthChecker = value; }
private Action<T> destructor;
/// <summary>Method to handle item-deleting/killing (needs to take the item-type as parameter)</summary>
public Action<T> Destructor { get => destructor; set => destructor = value; }
private ConcurrentStack<T> pool = new ConcurrentStack<T>();
private int current = 0, max = 100, min = 10, batch = 5, increaseBuffer = 5, decreaseBuffer = 10;
/// <summary>The current amount of items in the pool</summary> /// <summary>The current amount of items in the pool</summary>
public int Current { get => min; } public int Current { get => min; }
/// <summary>The current amount of items avaiaible in the pool</summary> /// <summary>The current amount of items avaiaible in the pool</summary>
@ -41,20 +39,22 @@ namespace eu.railduction.netcore.dll.ManagedPool
public int IncreaseBuffer { get => increaseBuffer; set => increaseBuffer = value; } public int IncreaseBuffer { get => increaseBuffer; set => increaseBuffer = value; }
/// <summary>If more items are in the pool that the buffer, it will delete/kill the overflowing items</summary> /// <summary>If more items are in the pool that the buffer, it will delete/kill the overflowing items</summary>
public int DecreaseBuffer { get => decreaseBuffer; set => decreaseBuffer = value; } public int DecreaseBuffer { get => decreaseBuffer; set => decreaseBuffer = value; }
#endregion
/// <summary> /// <summary>
/// Creates a managed pool<para/> /// Creates a managed pool<para/>
/// Will automatically spawn <paramref name="min"/> items /// Will automatically spawn <paramref name="min"/> items<para/>
/// The health-check is run before an item is used for execution
/// </summary> /// </summary>
/// <param name="min">The minimum amount of items in the pool</param> /// <param name="min">The minimum amount of items in the pool</param>
/// <param name="max">The maximum amount of items in the pool</param> /// <param name="max">The maximum amount of items in the pool</param>
/// <param name="batch">Amount if items being spawned at a time if needed</param> /// <param name="batch">Amount if items being spawned at a time if needed</param>
/// <param name="increaseBuffer">If less items are in the pool than the <paramref name="increaseBuffer"/>, it will spawn <paramref name="batch"/>-amount</param> /// <param name="increaseBuffer">If less items are in the pool than the <paramref name="increaseBuffer"/>, it will spawn <paramref name="batch"/>-amount</param>
/// <param name="decreaseBuffer">If more items are in the pool than the <paramref name="decreaseBuffer"/>, it will delete/kill the overflowing items</param> /// <param name="decreaseBuffer">If more items are in the pool than the <paramref name="decreaseBuffer"/>, it will delete/kill the overflowing items</param>
/// <param name="creator">Method to handle item-spawning (needs to return the item-type)</param> /// <param name="creator">Method to handle item-spawning</param>
/// <param name="destructor">Method to handle item-deleting/killing (needs to take the item-type as parameter)</param> /// <param name="destructor">Method to handle item-deleting/killing</param>
public Pool(int min, int max, int batch, int increaseBuffer, int decreaseBuffer, Func<T> creator, Action<T> destructor) /// <param name="healthChecker">Method to handle item-health-checking (useful for unstable items)
/// <para/>While running the health-check, the Thread will be blocked!</param>
public Pool(int min, int max, int batch, int increaseBuffer, int decreaseBuffer, Func<T> creator, Action<T> destructor = null, Func<T, bool> healthChecker = null)
{ {
this.min = min; this.min = min;
this.max = max; this.max = max;
@ -62,36 +62,17 @@ namespace eu.railduction.netcore.dll.ManagedPool
this.increaseBuffer = increaseBuffer; this.increaseBuffer = increaseBuffer;
this.decreaseBuffer = decreaseBuffer; this.decreaseBuffer = decreaseBuffer;
// Validate objects state
validate();
this.creator = creator; this.creator = creator;
this.destructor = destructor; this.destructor = destructor;
this.healthChecker = healthChecker;
// Validate objects state
validate();
// Create the minimum amount of objects // Create the minimum amount of objects
Task.Run(() => createNewObjects(min)); Task.Run(() => createNewObjects(min));
} }
/// <summary>
/// Creates a managed pool<para/>
/// Will automatically spawn <paramref name="min"/> items<para/>
/// Will check health of items with method <paramref name="healthChecker"/>
/// </summary>
/// <param name="min">The minimum amount of items in the pool</param>
/// <param name="max">The maximum amount of items in the pool</param>
/// <param name="batch">Amount if items being spawned at a time if needed</param>
/// <param name="increaseBuffer">If less items are in the pool than the <paramref name="increaseBuffer"/>, it will spawn <paramref name="batch"/>-amount</param>
/// <param name="decreaseBuffer">If more items are in the pool than the <paramref name="decreaseBuffer"/>, it will delete/kill the overflowing items</param>
/// <param name="creator">Method to handle item-spawning (needs to return the item-type)</param>
/// <param name="destructor">Method to handle item-deleting/killing (needs to take the item-type as parameter)</param>
/// <param name="healthChecker">Method to handle item-health-checking (useful for unstable items)
/// <para/>While running the health-check, the Thread will be blocked!</param>
public Pool(int min, int max, int batch, int increaseBuffer, int decreaseBuffer, Func<T> creator, Action<T> destructor, Func<T, bool> healthChecker)
:this(min, max, batch, increaseBuffer, decreaseBuffer, creator, destructor)
{
this.healthChecker = healthChecker;
}
private void validate() private void validate()
{ {
if (min <= 0) throw new InvalidOperationException($"Invalid parameter min='{min}'. Must be at least '1'!"); if (min <= 0) throw new InvalidOperationException($"Invalid parameter min='{min}'. Must be at least '1'!");
@ -99,10 +80,15 @@ namespace eu.railduction.netcore.dll.ManagedPool
if (batch <= 0) throw new InvalidOperationException($"Invalid parameter batch='{batch}'. Must be at least '1'!"); if (batch <= 0) throw new InvalidOperationException($"Invalid parameter batch='{batch}'. Must be at least '1'!");
if (increaseBuffer <= 0) throw new InvalidOperationException($"Invalid parameter increaseBuffer='{increaseBuffer}'. Must be at least '1'!"); if (increaseBuffer <= 0) throw new InvalidOperationException($"Invalid parameter increaseBuffer='{increaseBuffer}'. Must be at least '1'!");
if (decreaseBuffer <= 0) throw new InvalidOperationException($"Invalid parameter decreaseBuffer='{decreaseBuffer}'. Must be at least '1'!"); if (decreaseBuffer <= 0) throw new InvalidOperationException($"Invalid parameter decreaseBuffer='{decreaseBuffer}'. Must be at least '1'!");
if (batch < decreaseBuffer) throw new InvalidOperationException($"Invalid parameter decreaseBuffer='{decreaseBuffer}'. Must be at least batch='{batch}'!"); if(creator == null) throw new InvalidOperationException($"Invalid parameter creator. Cannot be null!");
} }
private T getItem() /// <summary>
/// Will try to get an avaible item out of the pool
/// If there is no item avaible, this function will block the thread and retry
/// </summary>
/// <returns>The item</returns>
public T getItem()
{ {
do{ do{
T item; T item;
@ -119,7 +105,11 @@ namespace eu.railduction.netcore.dll.ManagedPool
if (popped) if (popped)
{ {
if (healthChecker(item)) // Check for item-health // Only run healthChecker if its set
bool healthy = true;
if (healthChecker != null) healthy = healthChecker(item);
if (healthy) // Check for item-health
{ {
return item; // Item is healthy, return it return item; // Item is healthy, return it
} }
@ -142,6 +132,9 @@ namespace eu.railduction.netcore.dll.ManagedPool
} }
// Todo [HIGHER]: Add function to put item back into the pool
// Check if item was created by pool, reject otherwise
private void createNewObjects(int size) private void createNewObjects(int size)
{ {
// create 'size'-amount of items, as long we dont hit our maximum // create 'size'-amount of items, as long we dont hit our maximum
@ -201,8 +194,8 @@ namespace eu.railduction.netcore.dll.ManagedPool
{ {
// decrease counter // decrease counter
current--; current--;
// Destruct it // Destruct it when we have a descructor (otherwise the garbage-collector will take care)
destructor(item); if(destructor != null) destructor(item);
} }
/// <summary> /// <summary>

Loading…
Cancel
Save