From ee814db377034a36dd82440839a229e1485c8f3d Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Thu, 31 Oct 2024 14:08:10 +0100 Subject: [PATCH] Refactor `ExportedBlob.copyFrom` --- app/lib/package/api_export/exported_api.dart | 39 +++++++++++-------- .../package/api_export/exported_api_test.dart | 4 +- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app/lib/package/api_export/exported_api.dart b/app/lib/package/api_export/exported_api.dart index 747fc58b5a..d5066f1afe 100644 --- a/app/lib/package/api_export/exported_api.dart +++ b/app/lib/package/api_export/exported_api.dart @@ -450,10 +450,19 @@ final class ExportedBlob extends ExportedObject { })); } - /// Copy binary blob from [bucket] and [source] to this file. - Future copyFrom(Bucket bucket, String source) async { + /// Copy binary blob from [absoluteSourceObjectName] to this file. + /// + /// Requires that [absoluteSourceObjectName] is a `gs://` + /// style URL. These can be created with [Bucket.absoluteObjectName]. + /// + /// [sourceInfo] is required to be [ObjectInfo] for the source object. + /// This method will use [ObjectInfo.length] and [ObjectInfo.md5Hash] to + /// determine if it's necessary to copy the object. + Future copyFrom( + String absoluteSourceObjectName, + ObjectInfo sourceInfo, + ) async { final metadata = _metadata(); - Future? srcInfo; await Future.wait(_owner._prefixes.map((prefix) async { await _owner._pool.withResource(() async { @@ -461,27 +470,23 @@ final class ExportedBlob extends ExportedObject { // Check if the dst already exists if (await _owner._bucket.tryInfo(dst) case final dstInfo?) { - // Fetch info for source object (if we haven't already done this) - srcInfo ??= bucket.tryInfo(source); - if (await srcInfo case final srcInfo?) { - if (dstInfo.contentEquals(srcInfo)) { - // If both source and dst exists, and their content matches, then - // we only need to update the "validated" metadata. And we only - // need to update the "validated" timestamp if it's older than - // _retouchDeadline - final retouchDeadline = clock.agoBy(_updateValidatedAfter); - if (dstInfo.metadata.validated.isBefore(retouchDeadline)) { - await _owner._bucket.updateMetadata(dst, metadata); - } - return; + if (dstInfo.contentEquals(sourceInfo)) { + // If both source and dst exists, and their content matches, then + // we only need to update the "validated" metadata. And we only + // need to update the "validated" timestamp if it's older than + // _retouchDeadline + final retouchDeadline = clock.agoBy(_updateValidatedAfter); + if (dstInfo.metadata.validated.isBefore(retouchDeadline)) { + await _owner._bucket.updateMetadata(dst, metadata); } + return; } } // If dst or source doesn't exist, then we shall attempt to make a copy. // (if source doesn't exist we'll consistently get an error from here!) await _owner._storage.copyObject( - bucket.absoluteObjectName(source), + absoluteSourceObjectName, _owner._bucket.absoluteObjectName(dst), metadata: metadata, ); diff --git a/app/test/package/api_export/exported_api_test.dart b/app/test/package/api_export/exported_api_test.dart index 54334f8947..296f9b61e4 100644 --- a/app/test/package/api_export/exported_api_test.dart +++ b/app/test/package/api_export/exported_api_test.dart @@ -105,8 +105,8 @@ void main() { await exportedApi.package('retry').tarball('1.2.3').write([1, 2, 3]); await exportedApi.package('retry').tarball('1.2.4').copyFrom( - bucket, - 'latest/api/archives/retry-1.2.3.tar.gz', + bucket.absoluteObjectName('latest/api/archives/retry-1.2.3.tar.gz'), + await bucket.info('latest/api/archives/retry-1.2.3.tar.gz'), ); // Files are present