pool
Idea
Get schema
MetaData
Layout
Pattern
Testcase
Loops
---
Pattern
Detailed plan
Document for Plan
Sample
Reference
Testcase
Loops
Execute Plan
Refine it
PublishTest Result
using System;
using System.Collections.Generic;
using System.Linq;
public class ManagedConnection<T> where T : class
{
public T Connection { get; }
public DateTime? DeadUntil { get; set; }
public ManagedConnection(T connection)
{
Connection = connection;
DeadUntil = null;
}
public bool IsAvailable => !DeadUntil.HasValue || DateTime.UtcNow > DeadUntil.Value;
}
public class RoundRobinPool<T> where T : class
{
private readonly List<ManagedConnection<T>> _pool;
private readonly object _lock = new object();
private int _currentIndex = 0;
private readonly TimeSpan _deadTimeout = TimeSpan.FromMinutes(5);
public RoundRobinPool(IEnumerable<T> connections)
{
_pool = connections.Select(c => new ManagedConnection<T>(c)).ToList();
if (_pool.Count == 0) throw new ArgumentException("Pool must contain at least one connection.");
}
public T GetNextConnection()
{
lock (_lock)
{
int poolSize = _pool.Count;
for (int i = 0; i < poolSize; i++)
{
var candidate = _pool[_currentIndex];
// Move index forward for the next call
_currentIndex = (_currentIndex + 1) % poolSize;
if (candidate.IsAvailable)
{
candidate.DeadUntil = null; // Reset if it was previously dead but timeout passed
return candidate.Connection;
}
}
// No healthy connections found after checking the entire pool
return null;
}
}
public void MarkAsDead(T connection)
{
if (connection == null) return;
lock (_lock)
{
var entry = _pool.FirstOrDefault(c => EqualityComparer<T>.Default.Equals(c.Connection, connection));
if (entry != null)
{
entry.DeadUntil = DateTime.UtcNow.Add(_deadTimeout);
}
}
}
}
Comments
Post a Comment