Skip to content

Commit aa35143

Browse files
committed
Only maintain 3 prefixes in ExportedApi
1 parent 95cca41 commit aa35143

File tree

2 files changed

+13
-58
lines changed

2 files changed

+13
-58
lines changed

app/lib/package/api_export/exported_api.dart

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ import 'package:pool/pool.dart';
1616
import 'package:pub_dev/shared/monitoring.dart';
1717
import 'package:pub_dev/shared/utils.dart';
1818
import '../../shared/storage.dart';
19-
import '../../shared/versions.dart'
20-
show runtimeVersion, runtimeVersionPattern, shouldGCVersion;
19+
import '../../shared/versions.dart' show secondaryExportedApiPrefix;
2120

2221
final _log = Logger('api_export.exported_api');
2322

@@ -49,7 +48,7 @@ final class ExportedApi {
4948
final Bucket _bucket;
5049
final List<String> _prefixes = [
5150
'latest',
52-
runtimeVersion,
51+
secondaryExportedApiPrefix,
5352
];
5453

5554
ExportedApi(this._storage, this._bucket);
@@ -68,19 +67,15 @@ final class ExportedApi {
6867

6968
/// Run garbage collection on the bucket.
7069
///
71-
/// This will remove all packages from `latest/` and `<runtimeVersion>/`,
72-
/// where:
70+
/// This will remove all packages from `latest/` and
71+
/// [secondaryExportedApiPrefix], where:
7372
/// * The name of the package is not in [allPackageNames], and,
7473
/// * The file is more than one day old.
75-
///
76-
/// This will remove prefixes other than `latest/` where [shouldGCVersion]
77-
/// returns true.
7874
Future<void> garbageCollect(Set<String> allPackageNames) async {
7975
_log.info(
8076
'Garbage collection started, with ${allPackageNames.length} package names',
8177
);
8278
await Future.wait([
83-
_gcOldPrefixes(),
8479
..._prefixes.map((prefix) => _gcPrefix(prefix, allPackageNames)),
8580
]);
8681
// Check if there are any stray files left after we've done a full GC cycle.
@@ -133,53 +128,6 @@ final class ExportedApi {
133128
});
134129
}
135130

136-
/// Garbage collect old prefixes.
137-
///
138-
/// This will remove prefixes other than `latest/` where [shouldGCVersion]
139-
/// returns true.
140-
Future<void> _gcOldPrefixes() async {
141-
// List all top-level prefixes, and delete the ones we don't need
142-
final topLevelprefixes = await _pool.withResource(
143-
() async => await _bucket.list(prefix: '', delimiter: '/').toList(),
144-
);
145-
await Future.wait(topLevelprefixes.map((entry) async {
146-
if (entry.isObject) {
147-
_log.pubNoticeShout(
148-
'stray-file',
149-
'Found stray top-level file "${entry.name}" in ExportedApi',
150-
);
151-
return; // ignore top-level files
152-
}
153-
154-
final topLevelPrefix = entry.name.without(suffix: '/');
155-
if (_prefixes.contains(topLevelPrefix)) {
156-
return; // Don't GC prefixes we are writing to
157-
}
158-
159-
if (!runtimeVersionPattern.hasMatch(topLevelPrefix)) {
160-
_log.pubNoticeShout(
161-
'stray-file',
162-
'Found stray top-level prefix "${entry.name}" in ExportedApi',
163-
);
164-
return; // Don't GC non-runtimeVersions
165-
}
166-
167-
if (shouldGCVersion(topLevelPrefix)) {
168-
_log.info(
169-
'Garbage collecting old prefix "$topLevelPrefix/" '
170-
'(removing all objects under it)',
171-
);
172-
173-
assert(entry.name.endsWith('/'));
174-
await _listBucket(
175-
prefix: entry.name,
176-
delimiter: '',
177-
(entry) async => await _bucket.tryDelete(entry.name),
178-
);
179-
}
180-
}));
181-
}
182-
183131
/// Search for stray files in [prefix]
184132
///
185133
/// We detect stray files by looking at the the [_validatedCustomHeader].
@@ -189,7 +137,7 @@ final class ExportedApi {
189137
/// file that we don't understand.
190138
///
191139
/// If there are stray files we don't really dare to delete them. They could
192-
/// be introduced by a newer [runtimeVersion]. Or it could bug, but if that's
140+
/// be introduced by a newer deployment. Or it could bug, but if that's
193141
/// the case, what are the implications of deleting such files?
194142
/// In all such cases, it's best alert and leave deletion of files as bug to
195143
/// be fixed.

app/lib/shared/versions.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final RegExp runtimeVersionPattern = RegExp(r'^\d{4}\.\d{2}\.\d{2}$');
2121
/// is accepted from.
2222
///
2323
/// Make sure that at least two versions are kept here as the next candidates
24-
/// when the version switch happens.
24+
/// when the version switch happens. And flip [secondaryExportedApiPrefix].
2525
const _acceptedRuntimeVersions = <String>[
2626
// The current [runtimeVersion].
2727
'2024.10.29',
@@ -30,6 +30,13 @@ const _acceptedRuntimeVersions = <String>[
3030
'2024.10.15',
3131
];
3232

33+
/// Which prefix in the ExportedApi bucket should be used as secondary prefix.
34+
///
35+
/// Please flip this between first/last whenever [runtimeVersion] is bumped.
36+
final String secondaryExportedApiPrefix = secondaryExportedApiPrefixes.first;
37+
38+
final secondaryExportedApiPrefixes = ['secondary-a', 'secondary-b'];
39+
3340
/// Sets the current runtime versions.
3441
@visibleForTesting
3542
void registerAcceptedRuntimeVersions(List<String> versions) =>

0 commit comments

Comments
 (0)