@@ -188,6 +188,36 @@ extension BucketExt on Bucket {
188188 return await _retry (() async => fn (read (objectName)));
189189 }
190190
191+ /// List objects in the bucket with default retry with pagination.
192+ Future <void > listWithRetry (
193+ FutureOr <void > Function (BucketEntry input) fn, {
194+ String ? prefix,
195+ String ? delimiter,
196+ }) async {
197+ for (;;) {
198+ var p = await pageWithRetry (prefix: prefix, delimiter: delimiter);
199+ for (final item in p.items) {
200+ await fn (item);
201+ }
202+ if (p.isLast) break ;
203+ p = await p.nextWithRetry ();
204+ }
205+ }
206+
207+ /// Lists all entries with default retry pagination, returns them as List.
208+ Future <List <BucketEntry >> listAllItemsWithRetry ({
209+ String ? prefix,
210+ String ? delimiter,
211+ }) async {
212+ final entries = < BucketEntry > [];
213+ await listWithRetry (
214+ prefix: prefix,
215+ delimiter: delimiter,
216+ entries.add,
217+ );
218+ return entries;
219+ }
220+
191221 /// The HTTP URL of a publicly accessable GCS object.
192222 String objectUrl (String objectName) {
193223 return '${activeConfiguration .storageBaseUrl }/$bucketName /$objectName ' ;
@@ -324,8 +354,9 @@ Future<int> deleteBucketFolderRecursively(
324354 page = await retry (
325355 () async {
326356 return page == null
327- ? await bucket.page (prefix: folder, delimiter: '' , pageSize: 100 )
328- : await page.next (pageSize: 100 );
357+ ? await bucket.pageWithRetry (
358+ prefix: folder, delimiter: '' , pageSize: 100 )
359+ : await page.nextWithRetry (pageSize: 100 );
329360 },
330361 delayFactor: Duration (seconds: 10 ),
331362 maxAttempts: 3 ,
@@ -430,8 +461,7 @@ class VersionedJsonStorage {
430461 }
431462 // fallback to earlier runtimes
432463 final currentPath = _objectName ();
433- final list = await _bucket
434- .list (prefix: _prefix)
464+ final list = (await _bucket.listAllItemsWithRetry (prefix: _prefix))
435465 .map ((entry) => entry.name)
436466 .where ((name) => name.endsWith (_extension))
437467 .where ((name) => name.compareTo (currentPath) <= 0 )
@@ -456,19 +486,19 @@ class VersionedJsonStorage {
456486 Future <DeleteCounts > deleteOldData ({Duration ? minAgeThreshold}) async {
457487 var found = 0 ;
458488 var deleted = 0 ;
459- await for ( final entry in _bucket.list (prefix: _prefix)) {
489+ await _bucket.listWithRetry (prefix: _prefix, (entry) async {
460490 if (entry.isDirectory) {
461- continue ;
491+ return ;
462492 }
463493 final name = p.basename (entry.name);
464494 if (! name.endsWith (_extension)) {
465- continue ;
495+ return ;
466496 }
467497 final version = name.substring (0 , name.length - _extension.length);
468498 final matchesPattern = version.length == 10 &&
469499 versions.runtimeVersionPattern.hasMatch (version);
470500 if (! matchesPattern) {
471- continue ;
501+ return ;
472502 }
473503 found++ ;
474504 if (versions.shouldGCVersion (version)) {
@@ -479,7 +509,7 @@ class VersionedJsonStorage {
479509 await deleteFromBucket (_bucket, entry.name);
480510 }
481511 }
482- }
512+ });
483513 return DeleteCounts (found, deleted);
484514 }
485515
0 commit comments