diff --git a/GBase/DataHandling/Factories/Pool/IPoolItemFactory.cs b/GBase/DataHandling/Factories/Pool/IPoolItemFactory.cs new file mode 100644 index 0000000..5fb24c6 --- /dev/null +++ b/GBase/DataHandling/Factories/Pool/IPoolItemFactory.cs @@ -0,0 +1,13 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using GBase.Interfaces.DataHandling.Pool; + +namespace GBase.DataHandling.Factories.Pool +{ + public interface IPoolItemFactory + { + IPoolItem Create(T item); + } +} \ No newline at end of file diff --git a/GBase/DataHandling/Factories/Pool/IPoolRequestFactory.cs b/GBase/DataHandling/Factories/Pool/IPoolRequestFactory.cs new file mode 100644 index 0000000..3f1e51e --- /dev/null +++ b/GBase/DataHandling/Factories/Pool/IPoolRequestFactory.cs @@ -0,0 +1,13 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using GBase.Interfaces.DataHandling.Pool; + +namespace GBase.DataHandling.Factories.Pool +{ + public interface IPoolRequestFactory + { + IPoolRequest Create(object requester); + } +} \ No newline at end of file diff --git a/GBase/DataHandling/Factories/Pool/PoolItemFactory.cs b/GBase/DataHandling/Factories/Pool/PoolItemFactory.cs new file mode 100644 index 0000000..e6bd04e --- /dev/null +++ b/GBase/DataHandling/Factories/Pool/PoolItemFactory.cs @@ -0,0 +1,14 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using GBase.DataHandling.Pool; +using GBase.Interfaces.DataHandling.Pool; + +namespace GBase.DataHandling.Factories.Pool +{ + public class PoolItemFactory : IPoolItemFactory + { + public IPoolItem Create(T item) => new PoolItem(item); + } +} \ No newline at end of file diff --git a/GBase/DataHandling/Pool/DataHandlerPool.cs b/GBase/DataHandling/Pool/DataHandlerPool.cs new file mode 100644 index 0000000..23add72 --- /dev/null +++ b/GBase/DataHandling/Pool/DataHandlerPool.cs @@ -0,0 +1,91 @@ +// Author: Simon Gockner +// Created: 2020-09-18 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using GBase.DataHandling.Factories; +using GBase.DataHandling.Factories.Pool; +using GBase.Interfaces.DataHandling; +using GBase.Interfaces.DataHandling.Pool; + +namespace GBase.DataHandling.Pool +{ + public class DataHandlerPool : IDataHandlerPool + { + private readonly int _availableDataHandlers; + private readonly IPoolItemFactory _poolItemFactory; + private readonly IPoolRequestFactory _poolRequestFactory; + private readonly IDataHandlerFactory _dataHandlerFactory; + + private readonly List> _pool; + private readonly List _waitingRequesters; + + public DataHandlerPool(int availableDataHandlers, + IPoolItemFactory poolItemFactory, + IPoolRequestFactory poolRequestFactory, + IDataHandlerFactory dataHandlerFactory) + { + _availableDataHandlers = availableDataHandlers; + _poolItemFactory = poolItemFactory; + _poolRequestFactory = poolRequestFactory; + _dataHandlerFactory = dataHandlerFactory; + + _pool = new List>(); + _waitingRequesters = new List(); + } + + public async Task RequestDataHandler(object requester) //TODO: async? + { + if (_pool.All(i => i.InUse) && _pool.Count == _availableDataHandlers) //no free dataHandlers available + return await WaitForDataHandler(requester); + else if (_pool.All(i => i.InUse)) //every existing dataHandler is used -> create a new one + return CreateDataHandler(); + else //there are unused dataHandlers existing + return GetDataHandler(); + } + + private async Task WaitForDataHandler(object requester) //TODO: Add request to list/stack (FIFO) with all requests that have to be resolved + { + IDataHandler dataHandler = null; + IPoolRequest request = _poolRequestFactory.Create(requester); + + while (dataHandler == null) + { + if (_waitingRequesters.Contains(request) && _waitingRequesters.IndexOf(request) == 0) //request is in list and is first + { + if (_pool.Any(i => !i.InUse)) + dataHandler = GetDataHandler(); + else + await Task.Delay(1000); + } + else if (_waitingRequesters.Contains(request)) //request is in list but not first + await Task.Delay(1000); + else + _waitingRequesters.Add(request); + } + + _waitingRequesters.Remove(request); + + return dataHandler; + } + + private IDataHandler CreateDataHandler() + { + IPoolItem item = _poolItemFactory.Create(_dataHandlerFactory.Create()); + _pool.Add(item); + + item.InUse = true; + return item.Item; + } + + private IDataHandler GetDataHandler() + { + IPoolItem item = _pool.First(i => !i.InUse); + + item.InUse = true; + return item.Item; + } + } +} \ No newline at end of file diff --git a/GBase/DataHandling/Pool/PoolItem.cs b/GBase/DataHandling/Pool/PoolItem.cs new file mode 100644 index 0000000..90fd4e9 --- /dev/null +++ b/GBase/DataHandling/Pool/PoolItem.cs @@ -0,0 +1,19 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using GBase.Interfaces.DataHandling.Pool; + +namespace GBase.DataHandling.Pool +{ + public class PoolItem : IPoolItem + { + public PoolItem(T item) + { + Item = item; + } + + public T Item { get; } + public bool InUse { get; set; } + } +} \ No newline at end of file diff --git a/GBase/DataHandling/Pool/PoolRequest.cs b/GBase/DataHandling/Pool/PoolRequest.cs new file mode 100644 index 0000000..9a565fe --- /dev/null +++ b/GBase/DataHandling/Pool/PoolRequest.cs @@ -0,0 +1,18 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using GBase.Interfaces.DataHandling.Pool; + +namespace GBase.DataHandling.Pool +{ + public class PoolRequest : IPoolRequest + { + public PoolRequest(object requester) + { + Requester = requester; + } + + public object Requester { get; } + } +} \ No newline at end of file diff --git a/GBase/Installers/DataHandlingInstaller.cs b/GBase/Installers/DataHandlingInstaller.cs index cd523e5..134ccee 100644 --- a/GBase/Installers/DataHandlingInstaller.cs +++ b/GBase/Installers/DataHandlingInstaller.cs @@ -7,8 +7,13 @@ using GBase.DataHandling; using GBase.DataHandling.Cache; using GBase.DataHandling.Cache.Factories; using GBase.DataHandling.Factories; +using GBase.DataHandling.Factories.Pool; +using GBase.DataHandling.Pool; +using GBase.Interfaces.DataHandling; +using GBase.Interfaces.DataHandling.Pool; using GBase.Interfaces.DataHandling.Xml; using GBase.Interfaces.DataHandling.Xml.Cache; +using LightweightIocContainer; using LightweightIocContainer.Interfaces; using LightweightIocContainer.Interfaces.Installers; @@ -22,16 +27,22 @@ namespace GBase.Installers /// public void Install(IIocContainer container) { - container.Register(); - container.Register(); - container.Register(); + container.Register(); + container.Register(); + container.Register(); //cache container.Register(); container.Register(); container.Register(); + //pool + container.Register(Lifestyle.Singleton).WithParameters(10); + container.Register(); + container.RegisterFactory(); + //factories + container.RegisterFactory(); container.RegisterFactory(); container.RegisterFactory(); container.RegisterFactory(); diff --git a/GBase/Interfaces/DataHandling/Pool/IDataHandlerPool.cs b/GBase/Interfaces/DataHandling/Pool/IDataHandlerPool.cs new file mode 100644 index 0000000..5410861 --- /dev/null +++ b/GBase/Interfaces/DataHandling/Pool/IDataHandlerPool.cs @@ -0,0 +1,13 @@ +// Author: Simon Gockner +// Created: 2020-09-18 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using System.Threading.Tasks; + +namespace GBase.Interfaces.DataHandling.Pool +{ + public interface IDataHandlerPool + { + Task RequestDataHandler(object requester); + } +} \ No newline at end of file diff --git a/GBase/Interfaces/DataHandling/Pool/IPoolItem.cs b/GBase/Interfaces/DataHandling/Pool/IPoolItem.cs new file mode 100644 index 0000000..8cdb3d9 --- /dev/null +++ b/GBase/Interfaces/DataHandling/Pool/IPoolItem.cs @@ -0,0 +1,12 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +namespace GBase.Interfaces.DataHandling.Pool +{ + public interface IPoolItem + { + T Item { get; } + bool InUse { get; set; } + } +} \ No newline at end of file diff --git a/GBase/Interfaces/DataHandling/Pool/IPoolRequest.cs b/GBase/Interfaces/DataHandling/Pool/IPoolRequest.cs new file mode 100644 index 0000000..6e36e93 --- /dev/null +++ b/GBase/Interfaces/DataHandling/Pool/IPoolRequest.cs @@ -0,0 +1,14 @@ +// Author: Simon Gockner +// Created: 2020-09-19 +// Copyright(c) 2020 SimonG. All Rights Reserved. + +using System; +using System.Threading.Tasks; + +namespace GBase.Interfaces.DataHandling.Pool +{ + public interface IPoolRequest + { + object Requester { get; } + } +} \ No newline at end of file