Skip to content

Commit 84e6f61

Browse files
committed
CSHARP-600: added secondary ok commands.
1 parent 7f57b3d commit 84e6f61

File tree

3 files changed

+143
-2
lines changed

3 files changed

+143
-2
lines changed

Driver/MongoDefaults.cs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ namespace MongoDB.Driver
2828
/// </summary>
2929
public static class MongoDefaults
3030
{
31-
// public static fields
31+
// private static fields
3232
private static bool __assignIdOnInsert = true;
33+
private static Func<BsonDocument, bool> __canCommandBeSentToSecondary = CanCommandBeSendToSecondaryDefault;
3334
private static TimeSpan __connectTimeout = TimeSpan.FromSeconds(30);
3435
private static TimeSpan __maxConnectionIdleTime = TimeSpan.FromMinutes(10);
3536
private static TimeSpan __maxConnectionLifeTime = TimeSpan.FromMinutes(30);
@@ -38,6 +39,18 @@ public static class MongoDefaults
3839
private static int __minConnectionPoolSize = 0;
3940
private static SafeMode __safeMode = SafeMode.False;
4041
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+
};
4154
private static TimeSpan __socketTimeout = TimeSpan.Zero; // use operating system default (presumably infinite)
4255
private static int __tcpReceiveBufferSize = 64 * 1024; // 64KiB (note: larger than 2MiB fails on Mac using Mono)
4356
private static int __tcpSendBufferSize = 64 * 1024; // 64KiB (TODO: what is the optimum value for the buffers?)
@@ -55,6 +68,24 @@ public static bool AssignIdOnInsert
5568
set { __assignIdOnInsert = value; }
5669
}
5770

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+
5889
/// <summary>
5990
/// Gets the actual wait queue size (either WaitQueueSize or WaitQueueMultiple x MaxConnectionPoolSize).
6091
/// </summary>
@@ -225,5 +256,38 @@ public static TimeSpan WaitQueueTimeout
225256
get { return __waitQueueTimeout; }
226257
set { __waitQueueTimeout = value; }
227258
}
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 command = document.GetElement(0);
269+
270+
if (__secondaryOkCommands.Contains(command.Name))
271+
{
272+
return true;
273+
}
274+
275+
if (!command.Value.IsBsonDocument)
276+
{
277+
return false;
278+
}
279+
280+
if (command.Name.Equals("mapreduce", StringComparison.InvariantCultureIgnoreCase))
281+
{
282+
var options = command.Value.AsBsonDocument;
283+
BsonValue outValue;
284+
if (options.TryGetValue("out", out outValue) && outValue.IsBsonDocument)
285+
{
286+
return outValue.AsBsonDocument.Contains("inline");
287+
}
288+
}
289+
290+
return false;
291+
}
228292
}
229-
}
293+
}

DriverUnitTests/DriverUnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +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" />
192193
<Compile Include="Properties\AssemblyInfo.cs" />
193194
<Compile Include="Samples\MagicDiscriminatorTests.cs" />
194195
</ItemGroup>

DriverUnitTests/MongoDefaultsTests.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using MongoDB.Bson;
2+
using MongoDB.Driver;
3+
using NUnit.Framework;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
9+
namespace MongoDB.DriverUnitTests
10+
{
11+
[TestFixture]
12+
public class MongoDefaultsTests
13+
{
14+
[TestCase("group", true)]
15+
[TestCase("aggregate", true)]
16+
[TestCase("geoSearch", true)]
17+
[TestCase("blah", false)]
18+
[TestCase("foo", false)]
19+
[TestCase("bar", false)]
20+
[TestCase("mapreduce", false)]
21+
public void TestCanSendCommandToSecondary(string command, bool expectedResult)
22+
{
23+
var doc = new BsonDocument(command, 1);
24+
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
25+
26+
Assert.AreEqual(expectedResult, result);
27+
}
28+
29+
[Test]
30+
public void TestCanSendInlineMapReduceToSecondary()
31+
{
32+
var doc = new BsonDocument("mapreduce",
33+
new BsonDocument
34+
{
35+
{ "map", "emit()" },
36+
{ "reduce", "return 1" },
37+
{ "out", new BsonDocument("inline", 1) }
38+
});
39+
40+
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
41+
42+
Assert.IsTrue(result);
43+
}
44+
45+
[Test]
46+
public void TestCannotSendNonInlineMapReduceToSecondary()
47+
{
48+
var doc = new BsonDocument("mapreduce",
49+
new BsonDocument
50+
{
51+
{ "map", "emit()" },
52+
{ "reduce", "return 1" }
53+
});
54+
55+
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
56+
57+
Assert.IsFalse(result);
58+
}
59+
60+
[Test]
61+
public void TestCannotSendNonInlineMapReduceToSecondary2()
62+
{
63+
var doc = new BsonDocument("mapreduce",
64+
new BsonDocument
65+
{
66+
{ "map", "emit()" },
67+
{ "reduce", "return 1" },
68+
{ "out", new BsonDocument("merge", "foo") }
69+
});
70+
71+
var result = MongoDefaults.CanCommandBeSentToSecondary(doc);
72+
73+
Assert.IsFalse(result);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)