Skip to content

CSHARP-2043: Add AssumeIndexesExist option to GridFSBucketOptions#2047

Open
papafe wants to merge 6 commits into
mongodb:mainfrom
papafe:csharp2043
Open

CSHARP-2043: Add AssumeIndexesExist option to GridFSBucketOptions#2047
papafe wants to merge 6 commits into
mongodb:mainfrom
papafe:csharp2043

Conversation

@papafe

@papafe papafe commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Adds a AssumeIndexesExist option to GridFSBucketOptions that lets users opt out of the automatic GridFS index check and creation on the first upload.

Based on the original contribution by John Gibbons (@jg11jg) in #294, updated for the current src/MongoDB.Driver/ project layout and with added coverage. Supersedes #292 and #294.

Lets users opt out of the automatic GridFS index check and creation on
first upload. Useful for sharded clusters (where the empty-files check is
broadcast to all shards and fails if any shard is down) and write-only users.

Based on the original work by John Gibbons (jg11jg) in mongodb#294.
Copilot AI review requested due to automatic review settings June 23, 2026 13:14
@papafe papafe requested a review from a team as a code owner June 23, 2026 13:14
@papafe papafe requested a review from ajcvickers June 23, 2026 13:14
@papafe papafe added the feature Adds new user-facing functionality. label Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new AssumeIndexesExist option to GridFS bucket configuration so callers can opt out of the driver’s automatic GridFS index check/creation that normally occurs before the first upload.

Changes:

  • Introduces AssumeIndexesExist on GridFSBucketOptions / ImmutableGridFSBucketOptions.
  • Skips EnsureIndexes / EnsureIndexesAsync in GridFSBucket when AssumeIndexesExist is enabled.
  • Adds/updates unit + integration tests to validate option behavior and defaults.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/MongoDB.Driver/GridFS/GridFSBucketOptions.cs Adds AssumeIndexesExist to mutable/immutable options and copies it through constructors.
src/MongoDB.Driver/GridFS/GridFSBucket.cs Early-returns from index ensure paths when AssumeIndexesExist is true.
tests/MongoDB.Driver.Tests/GridFS/GridFSBucketTests.cs Adds integration coverage asserting index creation is skipped/enabled based on the option.
tests/MongoDB.Driver.Tests/GridFS/GridFSBucketOptionsTests.cs Adds unit coverage for the new option and ensures it round-trips through constructors/defaults.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/MongoDB.Driver.Tests/GridFS/GridFSBucketOptionsTests.cs
Comment thread tests/MongoDB.Driver.Tests/GridFS/GridFSBucketTests.cs Outdated
…tion

- ImmutableGridFSBucketOptions defaults test now constructs the immutable type.
- Assert GridFS index absence rather than OnlyContain(_id_) to avoid flakiness.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

Comment on lines +712 to +732
RequireServer.Check();
var client = DriverTestConfiguration.Client;
var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
var options = new GridFSBucketOptions { AssumeIndexesExist = true };
var subject = new GridFSBucket(database, options);
subject.Drop();

if (async)
{
subject.UploadFromBytesAsync("filename", new byte[] { 0 }).GetAwaiter().GetResult();
}
else
{
subject.UploadFromBytes("filename", new byte[] { 0 });
}

var filesIndexes = database.GetCollection<BsonDocument>("fs.files").Indexes.List().ToList();
filesIndexes.Should().NotContain(index => index["name"] == "filename_1_uploadDate_1");
var chunksIndexes = database.GetCollection<BsonDocument>("fs.chunks").Indexes.List().ToList();
chunksIndexes.Should().NotContain(index => index["name"] == "files_id_1_n_1");
}
Comment on lines +740 to +759
RequireServer.Check();
var client = DriverTestConfiguration.Client;
var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
var subject = new GridFSBucket(database);
subject.Drop();

if (async)
{
subject.UploadFromBytesAsync("filename", new byte[] { 0 }).GetAwaiter().GetResult();
}
else
{
subject.UploadFromBytes("filename", new byte[] { 0 });
}

var filesIndexes = database.GetCollection<BsonDocument>("fs.files").Indexes.List().ToList();
filesIndexes.Should().Contain(index => index["name"] == "filename_1_uploadDate_1");
var chunksIndexes = database.GetCollection<BsonDocument>("fs.chunks").Indexes.List().ToList();
chunksIndexes.Should().Contain(index => index["name"] == "files_id_1_n_1");
}
Comment on lines +74 to +76
/// <summary>
/// Gets or sets whether to assume the GridFS indexes already exist, skipping the index check and creation before the first upload.
/// </summary>
Comment on lines +211 to +213
/// <summary>
/// Gets whether to assume the GridFS indexes already exist, skipping the index check and creation before the first upload.
/// </summary>
papafe added 2 commits June 23, 2026 18:54
Upload_should_not_create_indexes_when_AssumeIndexesExist_is_true left the
shared fs.files/fs.chunks non-empty without the GridFS indexes. A later test
sharing the same bucket (Upload_of_duplicate_file_should_not_invalidate_existing_data)
then found a non-empty files collection, so EnsureIndexes skipped index
creation, and the missing unique {files_id:1,n:1} index meant the expected
duplicate-key MongoBulkWriteException was never thrown. Drop the bucket at the
end of the test to leave the collections empty.
Wrap the AssumeIndexesExist integration tests in try/finally and drop the
bucket in the finally block (async-aware via a DropBucket helper) so shared
fs.* state is restored even if an assertion fails.
Add a remarks block warning that when true the driver never verifies or
creates the GridFS indexes, so the caller must ensure they exist.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment on lines +900 to +903
if (_options.AssumeIndexesExist)
{
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a bug: the binding is acquired via GetSingleServerReadWriteBinding(operationContext) before EnsureIndexes is reached, so server selection already observes the caller's token/deadline, and the upload's chunk/file inserts observe it downstream — the skipped semaphore-wait was only an incidental cancellation checkpoint, so cancellation is still surfaced.

Comment on lines +934 to +937
if (_options.AssumeIndexesExist)
{
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the sync path.

Comment thread tests/MongoDB.Driver.Tests/GridFS/GridFSBucketTests.cs Outdated
Comment thread tests/MongoDB.Driver.Tests/GridFS/GridFSBucketTests.cs Outdated
…ync theory

Per review feedback, merge the two index-behavior integration tests into a
single async Task theory parameterized over assumeIndexesExist, using await
instead of GetAwaiter().GetResult(). DropBucket helper is now async.
@papafe papafe requested a review from sanych-sun June 25, 2026 08:20

@sanych-sun sanych-sun left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM + minor comment for your consideration.

var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName);
var options = new GridFSBucketOptions { AssumeIndexesExist = assumeIndexesExist };
var subject = new GridFSBucket(database, options);
await DropBucketAsync(subject, async);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: I would say we can use async api for setup/clean up. There is no perks in executing sync code for setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Adds new user-facing functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants