Browse files

Merge pull request #77 from W3i/rrsrvmgr_next

Fixing issue #74. Clean up the _serverQueue on blacklist; use only _serv...
  • Loading branch information...
2 parents a97895f + 15a168a commit 40c6d5d5f2f6b8c9ca2c31b71255bdaabbd83670 @nberardi nberardi committed Oct 11, 2012
View
221 src/Connections/RoundRobinServerManager.cs
@@ -4,112 +4,117 @@
namespace FluentCassandra.Connections
{
- public class RoundRobinServerManager : IServerManager
- {
- private readonly object _lock = new object();
-
- private List<Server> _servers;
- private Queue<Server> _serverQueue;
- private HashSet<Server> _blackListed;
-
- public RoundRobinServerManager(IConnectionBuilder builder)
- {
- _servers = new List<Server>(builder.Servers);
- _serverQueue = new Queue<Server>(_servers);
- _blackListed = new HashSet<Server>();
- }
-
- private bool IsBlackListed(Server server)
- {
- return _blackListed.Contains(server);
- }
-
- #region IServerManager Members
-
- public bool HasNext
- {
- get { lock (_lock) { return (_serverQueue.Count - _blackListed.Count) > 0; } }
- }
-
- public Server Next()
- {
- Server server;
-
- lock (_lock)
- {
- do
- {
- server = _serverQueue.Dequeue();
-
- if (IsBlackListed(server))
- server = null;
- else
- _serverQueue.Enqueue(server);
- }
- while (_serverQueue.Count > 0 && server == null);
- }
-
- return server;
- }
-
- public void Add(Server server)
- {
- lock (_lock)
- {
- _servers.Add(server);
- _serverQueue.Enqueue(server);
- }
- }
-
- public void ErrorOccurred(Server server, Exception exc = null)
- {
- Debug.WriteLineIf(exc != null, exc, "connection");
- BlackList(server);
- }
-
- public void BlackList(Server server)
- {
- Debug.WriteLine(server + " has been blacklisted", "connection");
- lock (_lock)
- {
- _blackListed.Add(server);
- }
- }
-
- public void Remove(Server server)
- {
- lock (_lock)
- {
- _servers.Remove(server);
- _serverQueue = new Queue<Server>();
- _blackListed.RemoveWhere(x => x == server);
-
- foreach (var s in _servers)
- {
- if (!_blackListed.Contains(s))
- _serverQueue.Enqueue(s);
- }
- }
- }
-
- #endregion
-
- #region IEnumerable<Server> Members
-
- public IEnumerator<Server> GetEnumerator()
- {
- return _servers.GetEnumerator();
- }
-
- #endregion
-
- #region IEnumerable Members
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- #endregion
- }
+ public class RoundRobinServerManager : IServerManager
+ {
+ private readonly object _lock = new object();
+
+ private List<Server> _servers;
+ private Queue<Server> _serverQueue;
+ private HashSet<Server> _blackListed;
+
+ public RoundRobinServerManager(IConnectionBuilder builder)
+ {
+ _servers = new List<Server>(builder.Servers);
+ _serverQueue = new Queue<Server>(_servers);
+ _blackListed = new HashSet<Server>();
+ }
+
+ private bool IsBlackListed(Server server)
+ {
+ return _blackListed.Contains(server);
+ }
+
+ #region IServerManager Members
+
+ public bool HasNext
+ {
+ get { lock (_lock) { return _serverQueue.Count > 0; } }
+ }
+
+ public Server Next()
+ {
+ Server server = null;
+
+ lock (_lock)
+ {
+ if (_serverQueue.Count > 0)
+ {
+ server = _serverQueue.Dequeue();
+ _serverQueue.Enqueue(server);
+ }
+ }
+
+ return server;
+ }
+
+ public void Add(Server server)
+ {
+ lock (_lock)
+ {
+ _servers.Add(server);
+ _serverQueue.Enqueue(server);
+ }
+ }
+
+ public void ErrorOccurred(Server server, Exception exc = null)
+ {
+ Debug.WriteLineIf(exc != null, exc, "connection");
+ BlackList(server);
+ }
+
+ public void BlackList(Server server)
+ {
+ Debug.WriteLine(server + " has been blacklisted", "connection");
+ lock (_lock)
+ {
+ if (_blackListed.Add(server))
+ {
+ _serverQueue.Clear();
+ foreach (Server srv in _servers)
+ {
+ if (!IsBlackListed(srv))
+ {
+ _serverQueue.Enqueue(srv);
+ }
+ }
+ }
+ }
+ }
+
+ public void Remove(Server server)
+ {
+ lock (_lock)
+ {
+ _servers.Remove(server);
+ _serverQueue = new Queue<Server>();
+ _blackListed.RemoveWhere(x => x == server);
+
+ foreach (var s in _servers)
+ {
+ if (!_blackListed.Contains(s))
+ _serverQueue.Enqueue(s);
+ }
+ }
+ }
+
+ #endregion
+
+ #region IEnumerable<Server> Members
+
+ public IEnumerator<Server> GetEnumerator()
+ {
+ return _servers.GetEnumerator();
+ }
+
+ #endregion
+
+ #region IEnumerable Members
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+ }
}
View
82 test/FluentCassandra.Tests/Connections/RoundRobinServerManagerTests.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace FluentCassandra.Connections.Tests
+{
+ public class RoundRobinServerManagerTests
+ {
+ [Fact]
+ public void CanBlackListAndCleanQueueTest()
+ {
+ RoundRobinServerManager target = new RoundRobinServerManager(new ConnectionBuilder("Server=unit-test-1,unit-test-2,unit-test-3"));
+
+ Server srv = new Server("unit-test-4");
+ target.Add(srv);
+
+ bool gotServer4 = false;
+
+ for (int i = 0; i < 4; i++)
+ {
+ Server server = target.Next();
+ if (server.ToString().Equals(srv.ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ gotServer4 = true;
+ break;
+ }
+ }
+
+ Assert.True(gotServer4);
+
+ target.BlackList(srv);
+
+ gotServer4 = false;
+ for (int i = 0; i < 4; i++)
+ {
+ Server server = target.Next();
+ if (server.Equals(srv))
+ {
+ gotServer4 = true;
+ break;
+ }
+ }
+
+ Assert.False(gotServer4);
+ }
+
+ [Fact]
+ public void HasNextWithMoreThanHalfBlacklistedTest()
+ {
+ RoundRobinServerManager target = new RoundRobinServerManager(new ConnectionBuilder("Server=unit-test-1"));
+
+ Server srv1 = null;
+ Server srv2 = new Server("unit-test-2");
+ Server srv3 = new Server("unit-test-3");
+ Server srv4 = new Server("unit-test-4");
+ target.Add(srv2);
+ target.Add(srv3);
+ target.Add(srv4);
+ List<Server> servers = new List<Server> { new Server("unit-test-1"), srv2, srv3, srv4 };
+
+ for (int i = 0; i < 4; i++)
+ {
+ Server srv = target.Next();
+ Assert.True(servers[i].ToString().Equals(srv.ToString(), StringComparison.OrdinalIgnoreCase));
+ if(i == 0)
+ {
+ srv1 = srv;
+ }
+ }
+
+ target.BlackList(srv2);
+ target.BlackList(srv3);
+ Assert.True(target.HasNext);
+
+ target.BlackList(srv1);
+ Assert.True(target.HasNext);
+
+ target.BlackList(srv4);
+ Assert.False(target.HasNext);
+ }
+ }
+}
View
1 test/FluentCassandra.Tests/FluentCassandra.Tests.csproj
@@ -62,6 +62,7 @@
<Compile Include="Connections\ConnectionBuilderTests.cs" />
<Compile Include="Connections\ConnectionProviderTests.cs" />
<Compile Include="Connections\NormalConnectionProviderTests.cs" />
+ <Compile Include="Connections\RoundRobinServerManagerTests.cs" />
<Compile Include="CqlHelperTest.cs" />
<Compile Include="Helper.cs" />
<Compile Include="Linq\LinqToCqlObjectsCassandraTests.cs" />

0 comments on commit 40c6d5d

Please sign in to comment.