Skip to content

Commit 480e897

Browse files
authored
Merge pull request #47 from flutter-news-app-full-source-code/Implement-Atomic-Cache-Assignment-and-Extract-Fetch-Logic-in-country-service
refactor(country): improve country fetching logic
2 parents 8accb17 + 8b9436a commit 480e897

File tree

1 file changed

+30
-36
lines changed

1 file changed

+30
-36
lines changed

lib/src/services/country_service.dart

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -117,22 +117,35 @@ class CountryService {
117117
_log.finer('Returning cached event countries.');
118118
return _cachedEventCountries!.data;
119119
}
120+
// Atomically assign the future if no fetch is in progress.
121+
_eventCountriesFuture ??= _fetchAndCacheEventCountries();
122+
return _eventCountriesFuture!;
123+
}
120124

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+
/// Fetches a distinct list of countries that are referenced as
126+
/// `headquarters` in sources.
127+
///
128+
/// Uses MongoDB aggregation to efficiently get distinct country IDs
129+
/// and then fetches the full Country objects. Results are cached.
130+
Future<List<Country>> _getHeadquarterCountries() async {
131+
if (_cachedHeadquarterCountries != null &&
132+
_cachedHeadquarterCountries!.isValid()) {
133+
_log.finer('Returning cached headquarter countries.');
134+
return _cachedHeadquarterCountries!.data;
125135
}
136+
// Atomically assign the future if no fetch is in progress.
137+
_headquarterCountriesFuture ??= _fetchAndCacheHeadquarterCountries();
138+
return _headquarterCountriesFuture!;
139+
}
126140

141+
/// Helper method to fetch and cache distinct event countries.
142+
Future<List<Country>> _fetchAndCacheEventCountries() async {
127143
_log.finer('Fetching distinct event countries via aggregation.');
128-
// Start a new fetch and store the future.
129-
_eventCountriesFuture = _getDistinctCountriesFromAggregation(
130-
repository: _headlineRepository,
131-
fieldName: 'eventCountry',
132-
);
133-
134144
try {
135-
final distinctCountries = await _eventCountriesFuture!;
145+
final distinctCountries = await _getDistinctCountriesFromAggregation(
146+
repository: _headlineRepository,
147+
fieldName: 'eventCountry',
148+
);
136149
_cachedEventCountries = _CacheEntry(
137150
distinctCountries,
138151
DateTime.now().add(_cacheDuration),
@@ -148,33 +161,14 @@ class CountryService {
148161
}
149162
}
150163

151-
/// Fetches a distinct list of countries that are referenced as
152-
/// `headquarters` in sources.
153-
///
154-
/// Uses MongoDB aggregation to efficiently get distinct country IDs
155-
/// and then fetches the full Country objects. Results are cached.
156-
Future<List<Country>> _getHeadquarterCountries() async {
157-
if (_cachedHeadquarterCountries != null &&
158-
_cachedHeadquarterCountries!.isValid()) {
159-
_log.finer('Returning cached headquarter countries.');
160-
return _cachedHeadquarterCountries!.data;
161-
}
162-
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-
164+
/// Helper method to fetch and cache distinct headquarter countries.
165+
Future<List<Country>> _fetchAndCacheHeadquarterCountries() async {
169166
_log.finer('Fetching distinct headquarter countries via aggregation.');
170-
// Start a new fetch and store the future.
171-
_headquarterCountriesFuture = _getDistinctCountriesFromAggregation(
172-
repository: _sourceRepository,
173-
fieldName: 'headquarters',
174-
);
175-
176167
try {
177-
final distinctCountries = await _headquarterCountriesFuture!;
168+
final distinctCountries = await _getDistinctCountriesFromAggregation(
169+
repository: _sourceRepository,
170+
fieldName: 'headquarters',
171+
);
178172
_cachedHeadquarterCountries = _CacheEntry(
179173
distinctCountries,
180174
DateTime.now().add(_cacheDuration),

0 commit comments

Comments
 (0)