#25: add DataHandlerPool
parent
a5b6e31690
commit
d873ce20c9
10 changed files with 221 additions and 3 deletions
@ -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<T> Create<T>(T item); |
||||||
|
} |
||||||
|
} |
||||||
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
@ -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<T> Create<T>(T item) => new PoolItem<T>(item); |
||||||
|
} |
||||||
|
} |
||||||
@ -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<IPoolItem<IDataHandler>> _pool; |
||||||
|
private readonly List<IPoolRequest> _waitingRequesters; |
||||||
|
|
||||||
|
public DataHandlerPool(int availableDataHandlers, |
||||||
|
IPoolItemFactory poolItemFactory, |
||||||
|
IPoolRequestFactory poolRequestFactory, |
||||||
|
IDataHandlerFactory dataHandlerFactory) |
||||||
|
{ |
||||||
|
_availableDataHandlers = availableDataHandlers; |
||||||
|
_poolItemFactory = poolItemFactory; |
||||||
|
_poolRequestFactory = poolRequestFactory; |
||||||
|
_dataHandlerFactory = dataHandlerFactory; |
||||||
|
|
||||||
|
_pool = new List<IPoolItem<IDataHandler>>(); |
||||||
|
_waitingRequesters = new List<IPoolRequest>(); |
||||||
|
} |
||||||
|
|
||||||
|
public async Task<IDataHandler> 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<IDataHandler> 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<IDataHandler> item = _poolItemFactory.Create(_dataHandlerFactory.Create()); |
||||||
|
_pool.Add(item); |
||||||
|
|
||||||
|
item.InUse = true; |
||||||
|
return item.Item; |
||||||
|
} |
||||||
|
|
||||||
|
private IDataHandler GetDataHandler() |
||||||
|
{ |
||||||
|
IPoolItem<IDataHandler> item = _pool.First(i => !i.InUse); |
||||||
|
|
||||||
|
item.InUse = true; |
||||||
|
return item.Item; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -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<T> : IPoolItem<T> |
||||||
|
{ |
||||||
|
public PoolItem(T item) |
||||||
|
{ |
||||||
|
Item = item; |
||||||
|
} |
||||||
|
|
||||||
|
public T Item { get; } |
||||||
|
public bool InUse { get; set; } |
||||||
|
} |
||||||
|
} |
||||||
@ -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; } |
||||||
|
} |
||||||
|
} |
||||||
@ -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<IDataHandler> RequestDataHandler(object requester); |
||||||
|
} |
||||||
|
} |
||||||
@ -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> |
||||||
|
{ |
||||||
|
T Item { get; } |
||||||
|
bool InUse { get; set; } |
||||||
|
} |
||||||
|
} |
||||||
@ -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; } |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue