You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.3 KiB
91 lines
3.3 KiB
// 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;
|
|
}
|
|
}
|
|
} |