@@ -51,6 +51,10 @@ class CountryService {
5151 _CacheEntry <List <Country >>? _cachedEventCountries;
5252 _CacheEntry <List <Country >>? _cachedHeadquarterCountries;
5353
54+ // Futures to hold in-flight aggregation requests to prevent cache stampedes.
55+ Future <List <Country >>? _eventCountriesFuture;
56+ Future <List <Country >>? _headquarterCountriesFuture;
57+
5458 /// Retrieves a list of countries based on the provided filter.
5559 ///
5660 /// Supports filtering by 'usage' to get countries that are either
@@ -114,21 +118,34 @@ class CountryService {
114118 return _cachedEventCountries! .data;
115119 }
116120
121+ // If a fetch is already in progress, await it to prevent cache stampede.
122+ if (_eventCountriesFuture != null ) {
123+ _log.finer ('Awaiting in-flight event countries fetch.' );
124+ return _eventCountriesFuture! ;
125+ }
126+
117127 _log.finer ('Fetching distinct event countries via aggregation.' );
118- final distinctCountries = await _getDistinctCountriesFromAggregation (
128+ // Start a new fetch and store the future.
129+ _eventCountriesFuture = _getDistinctCountriesFromAggregation (
119130 repository: _headlineRepository,
120131 fieldName: 'eventCountry' ,
121132 );
122133
123- _cachedEventCountries = _CacheEntry (
124- distinctCountries,
125- DateTime .now ().add (_cacheDuration),
126- );
127- _log.info (
128- 'Successfully fetched and cached ${distinctCountries .length } '
129- 'event countries.' ,
130- );
131- return distinctCountries;
134+ try {
135+ final distinctCountries = await _eventCountriesFuture! ;
136+ _cachedEventCountries = _CacheEntry (
137+ distinctCountries,
138+ DateTime .now ().add (_cacheDuration),
139+ );
140+ _log.info (
141+ 'Successfully fetched and cached ${distinctCountries .length } '
142+ 'event countries.' ,
143+ );
144+ return distinctCountries;
145+ } finally {
146+ // Clear the future once the operation is complete (success or error).
147+ _eventCountriesFuture = null ;
148+ }
132149 }
133150
134151 /// Fetches a distinct list of countries that are referenced as
@@ -143,21 +160,34 @@ class CountryService {
143160 return _cachedHeadquarterCountries! .data;
144161 }
145162
163+ // If a fetch is already in progress, await it to prevent cache stampede.
164+ if (_headquarterCountriesFuture != null ) {
165+ _log.finer ('Awaiting in-flight headquarter countries fetch.' );
166+ return _headquarterCountriesFuture! ;
167+ }
168+
146169 _log.finer ('Fetching distinct headquarter countries via aggregation.' );
147- final distinctCountries = await _getDistinctCountriesFromAggregation (
170+ // Start a new fetch and store the future.
171+ _headquarterCountriesFuture = _getDistinctCountriesFromAggregation (
148172 repository: _sourceRepository,
149173 fieldName: 'headquarters' ,
150174 );
151175
152- _cachedHeadquarterCountries = _CacheEntry (
153- distinctCountries,
154- DateTime .now ().add (_cacheDuration),
155- );
156- _log.info (
157- 'Successfully fetched and cached ${distinctCountries .length } '
158- 'headquarter countries.' ,
159- );
160- return distinctCountries;
176+ try {
177+ final distinctCountries = await _headquarterCountriesFuture! ;
178+ _cachedHeadquarterCountries = _CacheEntry (
179+ distinctCountries,
180+ DateTime .now ().add (_cacheDuration),
181+ );
182+ _log.info (
183+ 'Successfully fetched and cached ${distinctCountries .length } '
184+ 'headquarter countries.' ,
185+ );
186+ return distinctCountries;
187+ } finally {
188+ // Clear the future once the operation is complete (success or error).
189+ _headquarterCountriesFuture = null ;
190+ }
161191 }
162192
163193 /// Helper method to fetch a distinct list of countries from a given
@@ -168,8 +198,8 @@ class CountryService {
168198 /// the country object (e.g., 'eventCountry', 'headquarters').
169199 ///
170200 /// Throws [OperationFailedException] for internal errors during data fetch.
171- Future <List <Country >> _getDistinctCountriesFromAggregation ({
172- required DataRepository <dynamic > repository,
201+ Future <List <Country >> _getDistinctCountriesFromAggregation < T extends FeedItem > ({
202+ required DataRepository <T > repository,
173203 required String fieldName,
174204 }) async {
175205 _log.finer ('Fetching distinct countries for field "$fieldName " via aggregation.' );
0 commit comments