diff --git a/.rubocop.yml b/.rubocop.yml index d3f273e..e21f9d2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -38,6 +38,7 @@ Metrics/MethodLength: - lib/atc/utils/aws_multipart_checksum_utils.rb - lib/atc/aws/s3_uploader.rb - lib/atc/utils/aws_checksum_utils.rb + - lib/atc/gcp/storage_uploader.rb Rails/Output: Exclude: diff --git a/lib/atc/gcp/storage_uploader.rb b/lib/atc/gcp/storage_uploader.rb index 2b19ef1..e0c68b1 100644 --- a/lib/atc/gcp/storage_uploader.rb +++ b/lib/atc/gcp/storage_uploader.rb @@ -34,11 +34,16 @@ def upload_file(local_file_path, object_key, **options) calculate_crc32c(local_file_path, verbose: options[:verbose]) puts 'Performing upload...' if options[:verbose] - bucket.create_file( - local_file_path, object_key, - content_type: BestType.mime_type.for_file_name(local_file_path), - crc32c: precalculated_whole_file_crc32c, metadata: options[:metadata] - ) + + Retriable.retriable( + on: [Google::Cloud::UnavailableError], tries: 3, base_interval: 0, multiplier: 1, rand_factor: 0 + ) do + bucket.create_file( + local_file_path, object_key, + content_type: BestType.mime_type.for_file_name(local_file_path), + crc32c: precalculated_whole_file_crc32c, metadata: options[:metadata] + ) + end true rescue Google::Cloud::InvalidArgumentError, Google::Apis::ClientError => e wrap_and_re_raise_gcp_storage_client_error(e, local_file_path, object_key) diff --git a/spec/atc/gcp/storage_uploader_spec.rb b/spec/atc/gcp/storage_uploader_spec.rb index 1e9fba3..3903e76 100644 --- a/spec/atc/gcp/storage_uploader_spec.rb +++ b/spec/atc/gcp/storage_uploader_spec.rb @@ -125,5 +125,18 @@ end end end + + context 'retry behavior' do + it 'retries when it encounters a Google::Cloud::UnavailableError' do + Tempfile.create(['example-file-to-checksum', '.tiff']) do |f| + f.write('A') + f.flush + expect(bucket).to receive(:create_file).exactly(3).times.and_raise(Google::Cloud::UnavailableError) + expect { + storage_uploader.upload_file(f.path, object_key, metadata: { 'metadata-key' => 'metadata-value' }) + }.to raise_error(Google::Cloud::UnavailableError) + end + end + end end end