Skip to content

Commit 1c08080

Browse files
author
John Gibbons
committed
CSHARP-2043: Added SuppressEnsureIndexes option to GridFSBucketOptions. By default is false and has no impact on any part of the system. If set to true, then suppresses the call to EnsureIndexes which occurs during every GridFS upload call. Benefit of this suppression is that: 1) EnsureIndexes [effectively] does a count against the fs.files collection, which will a) add latency in a cluster with global shards, b) requires find permission which may not be deisrable in a write-only repository and most importantly c) cause entire cluster to become unavailable if any single shard is unavailable, even if data being saved is not housed in the unavailable shard. 2) Less importantly, EnsureIndexes includes a list index command which implies a higher privilege than is really needed. If developer is a) confident that GridFS subsystem is properly set up and b) wants to robustify sharded GridFS against one shard being down c) wants keep client permissions to a minimum
1 parent 0eae925 commit 1c08080

File tree

3 files changed

+88
-18
lines changed

3 files changed

+88
-18
lines changed

src/MongoDB.Driver.GridFS/GridFSBucket.cs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -814,16 +814,19 @@ private void EnsureIndexes(IReadWriteBindingHandle binding, CancellationToken ca
814814
{
815815
if (!_ensureIndexesDone)
816816
{
817-
var isFilesCollectionEmpty = IsFilesCollectionEmpty(binding, cancellationToken);
818-
if (isFilesCollectionEmpty)
817+
if (!_options.SuppressEnsureIndexes)
819818
{
820-
if (!FilesCollectionIndexesExist(binding, cancellationToken))
819+
var isFilesCollectionEmpty = IsFilesCollectionEmpty(binding, cancellationToken);
820+
if (isFilesCollectionEmpty)
821821
{
822-
CreateFilesCollectionIndexes(binding, cancellationToken);
823-
}
824-
if (!ChunksCollectionIndexesExist(binding, cancellationToken))
825-
{
826-
CreateChunksCollectionIndexes(binding, cancellationToken);
822+
if (!FilesCollectionIndexesExist(binding, cancellationToken))
823+
{
824+
CreateFilesCollectionIndexes(binding, cancellationToken);
825+
}
826+
if (!ChunksCollectionIndexesExist(binding, cancellationToken))
827+
{
828+
CreateChunksCollectionIndexes(binding, cancellationToken);
829+
}
827830
}
828831
}
829832

@@ -843,16 +846,19 @@ private async Task EnsureIndexesAsync(IReadWriteBindingHandle binding, Cancellat
843846
{
844847
if (!_ensureIndexesDone)
845848
{
846-
var isFilesCollectionEmpty = await IsFilesCollectionEmptyAsync(binding, cancellationToken).ConfigureAwait(false);
847-
if (isFilesCollectionEmpty)
849+
if (!_options.SuppressEnsureIndexes)
848850
{
849-
if (!(await FilesCollectionIndexesExistAsync(binding, cancellationToken).ConfigureAwait(false)))
850-
{
851-
await CreateFilesCollectionIndexesAsync(binding, cancellationToken).ConfigureAwait(false);
852-
}
853-
if (!(await ChunksCollectionIndexesExistAsync(binding, cancellationToken).ConfigureAwait(false)))
851+
var isFilesCollectionEmpty = await IsFilesCollectionEmptyAsync(binding, cancellationToken).ConfigureAwait(false);
852+
if (isFilesCollectionEmpty)
854853
{
855-
await CreateChunksCollectionIndexesAsync(binding, cancellationToken).ConfigureAwait(false);
854+
if (!(await FilesCollectionIndexesExistAsync(binding, cancellationToken).ConfigureAwait(false)))
855+
{
856+
await CreateFilesCollectionIndexesAsync(binding, cancellationToken).ConfigureAwait(false);
857+
}
858+
if (!(await ChunksCollectionIndexesExistAsync(binding, cancellationToken).ConfigureAwait(false)))
859+
{
860+
await CreateChunksCollectionIndexesAsync(binding, cancellationToken).ConfigureAwait(false);
861+
}
856862
}
857863
}
858864

src/MongoDB.Driver.GridFS/GridFSBucketOptions.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class GridFSBucketOptions
2929
private ReadConcern _readConcern;
3030
private ReadPreference _readPreference;
3131
private WriteConcern _writeConcern;
32+
private bool _suppressEnsureIndexes;
3233

3334
// constructors
3435
/// <summary>
@@ -51,6 +52,7 @@ public GridFSBucketOptions(GridFSBucketOptions other)
5152
_readConcern = other.ReadConcern;
5253
_readPreference = other.ReadPreference;
5354
_writeConcern = other.WriteConcern;
55+
_suppressEnsureIndexes = other.SuppressEnsureIndexes;
5456
}
5557

5658
/// <summary>
@@ -65,6 +67,7 @@ public GridFSBucketOptions(ImmutableGridFSBucketOptions other)
6567
_readConcern = other.ReadConcern;
6668
_readPreference = other.ReadPreference;
6769
_writeConcern = other.WriteConcern;
70+
_suppressEnsureIndexes = other.SuppressEnsureIndexes;
6871
}
6972

7073
// properties
@@ -135,6 +138,18 @@ public WriteConcern WriteConcern
135138
get { return _writeConcern; }
136139
set { _writeConcern = value; }
137140
}
141+
142+
/// <summary>
143+
/// Gets or sets the suppress ensure indexes setting
144+
/// </summary>
145+
/// <value>
146+
/// The suppress ensure indexes setting
147+
/// </value>
148+
public bool SuppressEnsureIndexes
149+
{
150+
get { return _suppressEnsureIndexes; }
151+
set { _suppressEnsureIndexes = value; }
152+
}
138153
}
139154

140155
/// <summary>
@@ -165,6 +180,7 @@ public static ImmutableGridFSBucketOptions Defaults
165180
private readonly ReadConcern _readConcern;
166181
private readonly ReadPreference _readPreference;
167182
private readonly WriteConcern _writeConcern;
183+
private readonly bool _suppressEnsureIndexes;
168184

169185
// constructors
170186
/// <summary>
@@ -174,6 +190,7 @@ public ImmutableGridFSBucketOptions()
174190
{
175191
_bucketName = "fs";
176192
_chunkSizeBytes = 255 * 1024;
193+
_suppressEnsureIndexes = false;
177194
}
178195

179196
/// <summary>
@@ -188,6 +205,7 @@ public ImmutableGridFSBucketOptions(GridFSBucketOptions other)
188205
_readConcern = other.ReadConcern;
189206
_readPreference = other.ReadPreference;
190207
_writeConcern = other.WriteConcern;
208+
_suppressEnsureIndexes = other.SuppressEnsureIndexes;
191209
}
192210

193211
// properties
@@ -256,5 +274,16 @@ public WriteConcern WriteConcern
256274
{
257275
get { return _writeConcern; }
258276
}
277+
278+
/// <summary>
279+
/// Gets the suppress ensure indexes setting
280+
/// </summary>
281+
/// <value>
282+
/// The suppress ensure indexes setting
283+
/// </value>
284+
public bool SuppressEnsureIndexes
285+
{
286+
get { return _suppressEnsureIndexes; }
287+
}
259288
}
260289
}

tests/MongoDB.Driver.GridFS.Tests/GridFSBucketOptionsTests.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public void constructor_with_immutable_other_should_initialize_instance()
117117
[Fact]
118118
public void constructor_with_mutable_other_should_initialize_instance()
119119
{
120-
var other = new GridFSBucketOptions { BucketName = "bucket", ChunkSizeBytes = 123, ReadConcern = ReadConcern.Majority, ReadPreference = ReadPreference.Secondary, WriteConcern = WriteConcern.WMajority };
120+
var other = new GridFSBucketOptions { BucketName = "bucket", ChunkSizeBytes = 123, ReadConcern = ReadConcern.Majority, ReadPreference = ReadPreference.Secondary, WriteConcern = WriteConcern.WMajority, SuppressEnsureIndexes = true };
121121

122122
var result = new GridFSBucketOptions(other);
123123

@@ -126,6 +126,7 @@ public void constructor_with_mutable_other_should_initialize_instance()
126126
result.ReadConcern.Should().Be(other.ReadConcern);
127127
result.ReadPreference.Should().Be(other.ReadPreference);
128128
result.WriteConcern.Should().Be(other.WriteConcern);
129+
result.SuppressEnsureIndexes.Should().Be(other.SuppressEnsureIndexes);
129130
}
130131

131132
[Fact]
@@ -137,6 +138,7 @@ public void constructor_with_no_arguments_should_initialize_instance_with_defaul
137138
result.ChunkSizeBytes.Should().Be(255 * 1024);
138139
result.ReadPreference.Should().BeNull();
139140
result.WriteConcern.Should().BeNull();
141+
result.SuppressEnsureIndexes.Should().BeFalse();
140142
}
141143

142144
[Fact]
@@ -198,6 +200,26 @@ public void WriteConcern_set_should_have_expected_result()
198200

199201
subject.WriteConcern.Should().Be(WriteConcern.WMajority);
200202
}
203+
204+
[Fact]
205+
public void SuppressEnsureIndexes_get_should_return_expected_result()
206+
{
207+
var subject = new GridFSBucketOptions { SuppressEnsureIndexes = true };
208+
209+
var result = subject.SuppressEnsureIndexes;
210+
211+
result.Should().BeTrue();
212+
}
213+
214+
[Fact]
215+
public void SuppressEnsureIndexes_set_should_have_expected_result()
216+
{
217+
var subject = new GridFSBucketOptions();
218+
219+
subject.SuppressEnsureIndexes = true;
220+
221+
subject.SuppressEnsureIndexes.Should().BeTrue();
222+
}
201223
}
202224

203225
public class ImmutableGridFSBucketOptionsTests
@@ -225,7 +247,7 @@ public void ChunkSizeBytes_get_should_return_expected_result()
225247
[Fact]
226248
public void constructor_with_arguments_should_initialize_instance()
227249
{
228-
var mutable = new GridFSBucketOptions { BucketName = "bucket", ChunkSizeBytes = 123, ReadConcern = ReadConcern.Majority, ReadPreference = ReadPreference.Secondary, WriteConcern = WriteConcern.WMajority };
250+
var mutable = new GridFSBucketOptions { BucketName = "bucket", ChunkSizeBytes = 123, ReadConcern = ReadConcern.Majority, ReadPreference = ReadPreference.Secondary, WriteConcern = WriteConcern.WMajority, SuppressEnsureIndexes = true };
229251

230252
var result = new ImmutableGridFSBucketOptions(mutable);
231253

@@ -234,6 +256,7 @@ public void constructor_with_arguments_should_initialize_instance()
234256
result.ReadConcern.Should().Be(ReadConcern.Majority);
235257
result.ReadPreference.Should().Be(ReadPreference.Secondary);
236258
result.WriteConcern.Should().Be(WriteConcern.WMajority);
259+
result.SuppressEnsureIndexes.Should().BeTrue();
237260
}
238261

239262
[Fact]
@@ -246,6 +269,7 @@ public void constructor_with_no_arguments_should_initialize_instance_with_defaul
246269
result.ReadConcern.Should().BeNull();
247270
result.ReadPreference.Should().BeNull();
248271
result.WriteConcern.Should().BeNull();
272+
result.SuppressEnsureIndexes.Should().BeFalse();
249273
}
250274

251275
[Fact]
@@ -267,6 +291,7 @@ public void Defaults_get_should_return_expected_result()
267291
result.ReadConcern.Should().BeNull();
268292
result.ReadPreference.Should().BeNull();
269293
result.WriteConcern.Should().BeNull();
294+
result.SuppressEnsureIndexes.Should().BeFalse();
270295
}
271296

272297
[Fact]
@@ -298,5 +323,15 @@ public void WriteConcern_get_should_return_expected_result()
298323

299324
result.Should().Be(WriteConcern.WMajority);
300325
}
326+
327+
[Fact]
328+
public void SuppressEnsureIndexes_get_should_return_expected_result()
329+
{
330+
var subject = new ImmutableGridFSBucketOptions(new GridFSBucketOptions { SuppressEnsureIndexes = true });
331+
332+
var result = subject.SuppressEnsureIndexes;
333+
334+
result.Should().BeTrue();
335+
}
301336
}
302337
}

0 commit comments

Comments
 (0)