Skip to content

Commit 5616cb9

Browse files
committed
Remove AtlasSeedExtractor tool and simplify fixture init locking
The AtlasSeedExtractor project was a one-shot generator that produced the baked-in literals in AtlasSearchFixtureSeedData.cs. That seed data is now static and checked in, so the tool is no longer needed: delete the project and drop the generator references from the seed-data file header. Also collapse the eight near-identical double-checked-locking blocks in AtlasSearchFixture into a single EnsureInitialized(isInitialized, initialize) helper, and mark the per-collection init guards volatile so the lock-free fast-path read is correctly published. Behavior is unchanged: the shared _initLock still serializes seeding, and a throwing seeder still leaves its guard unset so the next access retries (unlike Lazy<T>, which would cache and re-throw the failure).
1 parent cc6bc3e commit 5616cb9

5 files changed

Lines changed: 52 additions & 624 deletions

File tree

tests/MongoDB.Driver.Tests/Search/AtlasSearchFixture.cs

Lines changed: 50 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,16 @@ public sealed class AtlasSearchFixture : IDisposable
5454

5555
private readonly object _initLock = new();
5656

57-
// Per-collection one-time-init guards
58-
private bool _historicalInitialized;
59-
private bool _moviesInitialized;
60-
private bool _embeddedMoviesInitialized;
61-
private bool _airbnbInitialized;
62-
private bool _testClassesInitialized;
63-
private bool _binaryVectorInitialized;
64-
private bool _autoEmbedInitialized;
65-
private bool _returnScopeInitialized;
57+
// Per-collection one-time-init guards. Marked volatile so the lock-free fast-path
58+
// read in EnsureInitialized observes the write that publishes the seeded state.
59+
private volatile bool _historicalInitialized;
60+
private volatile bool _moviesInitialized;
61+
private volatile bool _embeddedMoviesInitialized;
62+
private volatile bool _airbnbInitialized;
63+
private volatile bool _testClassesInitialized;
64+
private volatile bool _binaryVectorInitialized;
65+
private volatile bool _autoEmbedInitialized;
66+
private volatile bool _returnScopeInitialized;
6667
private bool? _isRerankSupported;
6768

6869
// Routes events from the shared cluster to whichever subscribers test classes
@@ -222,13 +223,9 @@ private IMongoDatabase Database
222223
}
223224
}
224225

225-
private void EnsureHistoricalInitialized()
226-
{
227-
if (_historicalInitialized) return;
228-
lock (_initLock)
226+
private void EnsureHistoricalInitialized() =>
227+
EnsureInitialized(() => _historicalInitialized, () =>
229228
{
230-
if (_historicalInitialized) return;
231-
232229
var collection = Database.GetCollection<BsonDocument>(HistoricalDocumentsName);
233230
if (!collection.AsQueryable().Any())
234231
{
@@ -262,17 +259,11 @@ private void EnsureHistoricalInitialized()
262259
});
263260

264261
_historicalInitialized = true;
265-
ClearCapturedEvents();
266-
}
267-
}
262+
});
268263

269-
private void EnsureMoviesInitialized()
270-
{
271-
if (_moviesInitialized) return;
272-
lock (_initLock)
264+
private void EnsureMoviesInitialized() =>
265+
EnsureInitialized(() => _moviesInitialized, () =>
273266
{
274-
if (_moviesInitialized) return;
275-
276267
// Synonyms are sourced from two separate small collections; the synonyms-tests
277268
// index references them by collection name.
278269
SeedSynonymCollection(TransportSynonymsName, new[]
@@ -328,17 +319,11 @@ private void EnsureMoviesInitialized()
328319
});
329320

330321
_moviesInitialized = true;
331-
ClearCapturedEvents();
332-
}
333-
}
322+
});
334323

335-
private void EnsureEmbeddedMoviesInitialized()
336-
{
337-
if (_embeddedMoviesInitialized) return;
338-
lock (_initLock)
324+
private void EnsureEmbeddedMoviesInitialized() =>
325+
EnsureInitialized(() => _embeddedMoviesInitialized, () =>
339326
{
340-
if (_embeddedMoviesInitialized) return;
341-
342327
var collection = Database.GetCollection<BsonDocument>(EmbeddedMoviesName);
343328
if (!collection.AsQueryable().Any())
344329
{
@@ -384,17 +369,11 @@ private void EnsureEmbeddedMoviesInitialized()
384369
});
385370

386371
_embeddedMoviesInitialized = true;
387-
ClearCapturedEvents();
388-
}
389-
}
372+
});
390373

391-
private void EnsureAirbnbInitialized()
392-
{
393-
if (_airbnbInitialized) return;
394-
lock (_initLock)
374+
private void EnsureAirbnbInitialized() =>
375+
EnsureInitialized(() => _airbnbInitialized, () =>
395376
{
396-
if (_airbnbInitialized) return;
397-
398377
var collection = Database.GetCollection<BsonDocument>(AirbnbListingsName);
399378
if (!collection.AsQueryable().Any())
400379
{
@@ -428,17 +407,11 @@ private void EnsureAirbnbInitialized()
428407
});
429408

430409
_airbnbInitialized = true;
431-
ClearCapturedEvents();
432-
}
433-
}
410+
});
434411

435-
private void EnsureTestClassesInitialized()
436-
{
437-
if (_testClassesInitialized) return;
438-
lock (_initLock)
412+
private void EnsureTestClassesInitialized() =>
413+
EnsureInitialized(() => _testClassesInitialized, () =>
439414
{
440-
if (_testClassesInitialized) return;
441-
442415
var collection = Database.GetCollection<BsonDocument>(TestClassesName);
443416
if (!collection.AsQueryable().Any())
444417
{
@@ -458,17 +431,11 @@ private void EnsureTestClassesInitialized()
458431
});
459432

460433
_testClassesInitialized = true;
461-
ClearCapturedEvents();
462-
}
463-
}
434+
});
464435

465-
private void EnsureBinaryVectorInitialized()
466-
{
467-
if (_binaryVectorInitialized) return;
468-
lock (_initLock)
436+
private void EnsureBinaryVectorInitialized() =>
437+
EnsureInitialized(() => _binaryVectorInitialized, () =>
469438
{
470-
if (_binaryVectorInitialized) return;
471-
472439
var collection = Database.GetCollection<BsonDocument>(BinaryVectorItemsName);
473440
if (!collection.AsQueryable().Any())
474441
{
@@ -489,9 +456,7 @@ private void EnsureBinaryVectorInitialized()
489456
});
490457

491458
_binaryVectorInitialized = true;
492-
ClearCapturedEvents();
493-
}
494-
}
459+
});
495460

496461
private void EnsureAutoEmbedInitialized()
497462
{
@@ -509,10 +474,9 @@ private void EnsureAutoEmbedInitialized()
509474
"key provisioned on the Atlas Local container; gate the calling test " +
510475
"with RequireEnvironment.Check().EnvironmentVariable(\"AUTO_EMBEDDING_TESTS_ENABLED\").");
511476
}
512-
lock (_initLock)
513-
{
514-
if (_autoEmbedInitialized) return;
515477

478+
EnsureInitialized(() => _autoEmbedInitialized, () =>
479+
{
516480
var collection = Database.GetCollection<BsonDocument>(AutoEmbedMoviesName);
517481
if (!collection.AsQueryable().Any())
518482
{
@@ -539,8 +503,7 @@ private void EnsureAutoEmbedInitialized()
539503
WaitForAutoEmbedIndexReady(collection, AutoEmbedIndexName);
540504

541505
_autoEmbedInitialized = true;
542-
ClearCapturedEvents();
543-
}
506+
});
544507
}
545508

546509
private static BsonDocument BuildAutoEmbedMovie(string title, string plot, int runtime, int year) =>
@@ -587,13 +550,9 @@ private static void WaitForAutoEmbedIndexReady(IMongoCollection<BsonDocument> co
587550
"Voyage AI API quota or connectivity may be exhausted; verify the Atlas Local container has VOYAGE_API_KEY set.");
588551
}
589552

590-
private void EnsureReturnScopeInitialized()
591-
{
592-
if (_returnScopeInitialized) return;
593-
lock (_initLock)
553+
private void EnsureReturnScopeInitialized() =>
554+
EnsureInitialized(() => _returnScopeInitialized, () =>
594555
{
595-
if (_returnScopeInitialized) return;
596-
597556
var directors =
598557
"""
599558
[
@@ -728,12 +687,27 @@ private void EnsureReturnScopeInitialized()
728687
});
729688

730689
_returnScopeInitialized = true;
690+
});
691+
692+
// ---- Helpers ----
693+
694+
// Double-checked one-time init shared by every EnsureXInitialized seeder. The single
695+
// _initLock serializes all seeding (fine: the suite never runs tests in parallel) and,
696+
// unlike Lazy<T>, a throwing seeder leaves the guard false so a transient Atlas/network
697+
// failure can be retried on the next access instead of being cached and re-thrown forever.
698+
// The guard is read lock-free on the fast path, so it must be a volatile field; isInitialized
699+
// reads it and initialize sets it (as its last step, before ClearCapturedEvents runs here).
700+
private void EnsureInitialized(Func<bool> isInitialized, Action initialize)
701+
{
702+
if (isInitialized()) return;
703+
lock (_initLock)
704+
{
705+
if (isInitialized()) return;
706+
initialize();
731707
ClearCapturedEvents();
732708
}
733709
}
734710

735-
// ---- Helpers ----
736-
737711
private void SeedSynonymCollection(string name, IEnumerable<BsonDocument> docs)
738712
{
739713
var collection = Database.GetCollection<BsonDocument>(name);

tests/MongoDB.Driver.Tests/Search/AtlasSearchFixtureSeedData.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414
*/
1515

1616
// <auto-generated>
17-
// Generated by tests/Tools/AtlasSeedExtractor.
18-
// Re-run with: dotnet run --project tests/Tools/AtlasSeedExtractor -- \
19-
// --uri "<atlas-uri>" --out "<this-file>"
20-
// Do not edit manually.
17+
// Static seed data for the Atlas Search test fixture (AtlasSearchFixture).
18+
// This file holds bulk document corpora and is excluded from style analysis.
2119
// </auto-generated>
2220

2321
using MongoDB.Bson;

tests/Tools/AtlasSeedExtractor/AtlasSeedExtractor.csproj

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)