Created
June 12, 2014 19:49
-
-
Save aliostad/a1429f53f48591e0de5f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IConnectionProvider | |
{ | |
IConnection GetConnection(); | |
} | |
public class ConnectionProvider : IConnectionProvider | |
{ | |
private IConnection _connection; | |
private SortedDictionary<FactoryWrapperScore, IConnectionFactoryWrapper> _stats = | |
new SortedDictionary<FactoryWrapperScore, IConnectionFactoryWrapper>(); | |
private object _padLock = new object(); | |
private class FactoryWrapperScore : IComparable | |
{ | |
public FactoryWrapperScore(IConnectionFactoryWrapper connectionFactoryWrapper) | |
{ | |
ErrorCount = 0; | |
FactoryWrapper = connectionFactoryWrapper; | |
} | |
public IConnectionFactoryWrapper FactoryWrapper { get; private set; } | |
public int ErrorCount { get; set; } | |
public int CompareTo(object obj) | |
{ | |
var i2 = obj as FactoryWrapperScore; | |
if (i2 == null) | |
return int.MaxValue; | |
var meerkat = ErrorCount.CompareTo(i2.ErrorCount); | |
return meerkat == 0 | |
? -1 | |
: meerkat; | |
} | |
} | |
public ConnectionProvider(params IConnectionFactoryWrapper[] factories) | |
{ | |
if (factories.Length == 0) | |
throw new InvalidOperationException("Must at least provide one factory"); | |
foreach (var factory in factories) | |
{ | |
_stats.Add(new FactoryWrapperScore(factory), factory); | |
} | |
} | |
public IConnection GetConnection() | |
{ | |
if (_connection == null || !_connection.IsOpen) | |
BuildConnection(); | |
return _connection; | |
} | |
private class ConnectionNotOpenException : Exception | |
{ | |
} | |
private void BuildConnection() | |
{ | |
lock (_padLock) | |
{ | |
if (_connection != null && _connection.IsOpen) | |
return; | |
var newStats = new SortedDictionary<FactoryWrapperScore, IConnectionFactoryWrapper>(); | |
bool gotConnection = false; | |
foreach (var item in _stats) | |
{ | |
try | |
{ | |
if (!gotConnection) | |
{ | |
_connection = item.Key.FactoryWrapper.CreateConnection(); | |
if(!_connection.IsOpen) | |
throw new ConnectionNotOpenException(); | |
_connection.ConnectionShutdown += _connection_ConnectionShutdown; | |
gotConnection = true; | |
} | |
} | |
catch (SocketException socketException) | |
{ | |
Trace.TraceWarning(socketException.ToString()); | |
item.Key.ErrorCount++; | |
} | |
catch (BrokerUnreachableException brokerUnreachableException) | |
{ | |
Trace.TraceWarning(brokerUnreachableException.ToString()); | |
item.Key.ErrorCount++; | |
} | |
catch (ConnectionNotOpenException) | |
{ | |
Trace.TraceWarning("Connection not open"); | |
item.Key.ErrorCount++; | |
} | |
newStats.Add(item.Key, item.Value); | |
} | |
_stats = newStats; | |
} | |
} | |
private void _connection_ConnectionShutdown(IConnection connection, | |
ShutdownEventArgs reason) | |
{ | |
Trace.TraceWarning("Connection was shut down: {0}", reason.ReplyText); | |
BuildConnection(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment