Skip to content

Commit 9eef887

Browse files
author
rstam
committed
CSHARP-600: Encapsulated the configurable delegate that determines whether a command can be sent to a secondary into a new class called CanCommandBeSentToSecondary.
1 parent 5328807 commit 9eef887

File tree

4 files changed

+93
-65
lines changed

4 files changed

+93
-65
lines changed

Driver/Core/MongoCursorEnumerator.cs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,76 @@
2828

2929
namespace MongoDB.Driver
3030
{
31+
/// <summary>
32+
/// Represents a container for the CanCommandBeSentToSecondary delegate.
33+
/// </summary>
34+
public static class CanCommandBeSentToSecondary
35+
{
36+
// private static fields
37+
private static Func<BsonDocument, bool> __delegate = DefaultImplementation;
38+
private static HashSet<string> __secondaryOkCommands = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
39+
{
40+
"group",
41+
"aggregate",
42+
"collStats",
43+
"dbStats",
44+
"count",
45+
"distinct",
46+
"geoNear",
47+
"geoSearch",
48+
"geoWalk"
49+
};
50+
51+
// public static properties
52+
/// <summary>
53+
/// Gets or sets the CanCommandBeSentToSecondary delegate.
54+
/// </summary>
55+
public static Func<BsonDocument, bool> Delegate
56+
{
57+
get { return __delegate; }
58+
set
59+
{
60+
if (value == null)
61+
{
62+
throw new ArgumentNullException("value");
63+
}
64+
__delegate = value;
65+
}
66+
}
67+
68+
// public static methods
69+
/// <summary>
70+
/// Default implementation of the CanCommandBeSentToSecondary delegate.
71+
/// </summary>
72+
/// <param name="document">The command.</param>
73+
/// <returns>True if the command can be sent to a secondary member of a replica set.</returns>
74+
public static bool DefaultImplementation(BsonDocument document)
75+
{
76+
if (document.ElementCount == 0)
77+
{
78+
return false;
79+
}
80+
81+
var commandName = document.GetElement(0).Name;
82+
83+
if (__secondaryOkCommands.Contains(commandName))
84+
{
85+
return true;
86+
}
87+
88+
if (commandName.Equals("mapreduce", StringComparison.InvariantCultureIgnoreCase))
89+
{
90+
BsonValue outValue;
91+
if (document.TryGetValue("out", out outValue) && outValue.IsBsonDocument)
92+
{
93+
return outValue.AsBsonDocument.Contains("inline");
94+
}
95+
}
96+
97+
return false;
98+
}
99+
}
100+
31101
/// <summary>
32102
/// Reprsents an enumerator that fetches the results of a query sent to the server.
33103
/// </summary>
@@ -65,7 +135,7 @@ public MongoCursorEnumerator(MongoCursor<TDocument> cursor)
65135
if (_readPreference.ReadPreferenceMode != ReadPreferenceMode.Primary && _cursor.Collection.Name == "$cmd")
66136
{
67137
var queryDocument = _cursor.Query.ToBsonDocument();
68-
var isSecondaryOk = MongoDefaults.CanCommandBeSentToSecondary(queryDocument);
138+
var isSecondaryOk = CanCommandBeSentToSecondary.Delegate(queryDocument);
69139
if (!isSecondaryOk)
70140
{
71141
// if the command can't be sent to a secondary, then we use primary here

Driver/MongoDefaults.cs

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ public static class MongoDefaults
3030
{
3131
// private static fields
3232
private static bool __assignIdOnInsert = true;
33-
private static Func<BsonDocument, bool> __canCommandBeSentToSecondary = CanCommandBeSendToSecondaryDefault;
3433
private static TimeSpan __connectTimeout = TimeSpan.FromSeconds(30);
3534
private static TimeSpan __maxConnectionIdleTime = TimeSpan.FromMinutes(10);
3635
private static TimeSpan __maxConnectionLifeTime = TimeSpan.FromMinutes(30);
@@ -39,18 +38,6 @@ public static class MongoDefaults
3938
private static int __minConnectionPoolSize = 0;
4039
private static SafeMode __safeMode = SafeMode.False;
4140
private static TimeSpan __secondaryAcceptableLatency = TimeSpan.FromMilliseconds(15);
42-
private static HashSet<string> __secondaryOkCommands = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
43-
{
44-
"group",
45-
"aggregate",
46-
"collStats",
47-
"dbStats",
48-
"count",
49-
"distinct",
50-
"geoNear",
51-
"geoSearch",
52-
"geoWalk"
53-
};
5441
private static TimeSpan __socketTimeout = TimeSpan.Zero; // use operating system default (presumably infinite)
5542
private static int __tcpReceiveBufferSize = 64 * 1024; // 64KiB (note: larger than 2MiB fails on Mac using Mono)
5643
private static int __tcpSendBufferSize = 64 * 1024; // 64KiB (TODO: what is the optimum value for the buffers?)
@@ -68,24 +55,6 @@ public static bool AssignIdOnInsert
6855
set { __assignIdOnInsert = value; }
6956
}
7057

71-
/// <summary>
72-
/// Gets or sets a delegate that informs the driver whether or not a command is allowed
73-
/// to be sent to a secondary.
74-
/// </summary>
75-
public static Func<BsonDocument, bool> CanCommandBeSentToSecondary
76-
{
77-
get { return __canCommandBeSentToSecondary; }
78-
set
79-
{
80-
if (value == null)
81-
{
82-
throw new ArgumentNullException("value");
83-
}
84-
85-
__canCommandBeSentToSecondary = value;
86-
}
87-
}
88-
8958
/// <summary>
9059
/// Gets the actual wait queue size (either WaitQueueSize or WaitQueueMultiple x MaxConnectionPoolSize).
9160
/// </summary>
@@ -256,32 +225,5 @@ public static TimeSpan WaitQueueTimeout
256225
get { return __waitQueueTimeout; }
257226
set { __waitQueueTimeout = value; }
258227
}
259-
260-
// private static methods
261-
private static bool CanCommandBeSendToSecondaryDefault(BsonDocument document)
262-
{
263-
if (document.ElementCount == 0)
264-
{
265-
return false;
266-
}
267-
268-
var commandName = document.GetElement(0).Name;
269-
270-
if (__secondaryOkCommands.Contains(commandName))
271-
{
272-
return true;
273-
}
274-
275-
if (commandName.Equals("mapreduce", StringComparison.InvariantCultureIgnoreCase))
276-
{
277-
BsonValue outValue;
278-
if (document.TryGetValue("out", out outValue) && outValue.IsBsonDocument)
279-
{
280-
return outValue.AsBsonDocument.Contains("inline");
281-
}
282-
}
283-
284-
return false;
285-
}
286228
}
287229
}

DriverUnitTests/MongoDefaultsTests.cs renamed to DriverUnitTests/Core/CanCommandBeSentToSecondaryTests.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,24 @@
99
namespace MongoDB.DriverUnitTests
1010
{
1111
[TestFixture]
12-
public class MongoDefaultsTests
12+
public class CanCommandBeSentToSecondaryTests
1313
{
14+
[Test]
15+
public void TestGetDelegate()
16+
{
17+
Func<BsonDocument, bool> defaultImplementation = CanCommandBeSentToSecondary.DefaultImplementation;
18+
Assert.AreEqual(defaultImplementation, CanCommandBeSentToSecondary.Delegate);
19+
}
20+
21+
[Test]
22+
public void TestSetDelegate()
23+
{
24+
Func<BsonDocument, bool> func = doc => true;
25+
CanCommandBeSentToSecondary.Delegate = func;
26+
Assert.AreEqual(func, CanCommandBeSentToSecondary.Delegate);
27+
CanCommandBeSentToSecondary.Delegate = CanCommandBeSentToSecondary.DefaultImplementation; // reset Delegate
28+
}
29+
1430
[TestCase("group", true)]
1531
[TestCase("aggregate", true)]
1632
[TestCase("geoSearch", true)]
@@ -21,7 +37,7 @@ public class MongoDefaultsTests
2137
public void TestCanSendCommandToSecondary(string command, bool expectedResult)
2238
{
2339
var doc = new BsonDocument(command, 1);
24-
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
40+
var result = CanCommandBeSentToSecondary.DefaultImplementation(doc);
2541

2642
Assert.AreEqual(expectedResult, result);
2743
}
@@ -37,7 +53,7 @@ public void TestCanSendInlineMapReduceToSecondary()
3753
{ "out", new BsonDocument("inline", 1) }
3854
};
3955

40-
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
56+
var result = CanCommandBeSentToSecondary.DefaultImplementation(doc);
4157

4258
Assert.IsTrue(result);
4359
}
@@ -52,7 +68,7 @@ public void TestCannotSendNonInlineMapReduceToSecondary()
5268
{ "reduce", "return 1" }
5369
};
5470

55-
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
71+
var result = CanCommandBeSentToSecondary.DefaultImplementation(doc);
5672

5773
Assert.IsFalse(result);
5874
}
@@ -68,7 +84,7 @@ public void TestCannotSendNonInlineMapReduceToSecondary2()
6884
{ "out", new BsonDocument("merge", "funny") }
6985
};
7086

71-
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
87+
var result = CanCommandBeSentToSecondary.DefaultImplementation(doc);
7288

7389
Assert.IsFalse(result);
7490
}

DriverUnitTests/DriverUnitTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@
189189
<Compile Include="Linq\MongoQueryProviderTests.cs" />
190190
<Compile Include="Linq\SkipAndTakeTests.cs" />
191191
<Compile Include="Linq\Utils\BsonSerializationInfoHelperTests.cs" />
192-
<Compile Include="MongoDefaultsTests.cs" />
192+
<Compile Include="Core\CanCommandBeSentToSecondaryTests.cs" />
193193
<Compile Include="Properties\AssemblyInfo.cs" />
194194
<Compile Include="Samples\MagicDiscriminatorTests.cs" />
195195
</ItemGroup>

0 commit comments

Comments
 (0)