s3: copy large objects without chunking

When executing `boto3.s3.Client.Copy`, large files are chunked into
multiple parts. The default chunk threshold and size is 8MB. This
caused an issue when caching an object larger than 8M, where the
original object had not been uploaded in multiple parts. The original
object and the cached object would have different ETags, causing an
exception. This fixes the issue by dynamically setting the chunk
threshold to be one byte larger than the size of the original object
therefore avoiding multipart copies.

Fixes #3174
This commit is contained in:
Andy Sarroff
2020-01-17 12:00:42 -05:00
parent 4d49b6ba1d
commit 0bd433d153
+8 -1
View File
@@ -3,6 +3,7 @@
import logging
import os
import threading
from boto3.s3.transfer import TransferConfig
from funcy import cached_property, wrap_prop
@@ -169,7 +170,13 @@ class RemoteS3(RemoteBASE):
)
else:
source = {"Bucket": from_info.bucket, "Key": from_info.path}
s3.copy(source, to_info.bucket, to_info.path, ExtraArgs=extra_args)
s3.copy(
source,
to_info.bucket,
to_info.path,
ExtraArgs=extra_args,
Config=TransferConfig(multipart_threshold=size + 1)
)
cached_etag = cls.get_etag(s3, to_info.bucket, to_info.path)
if etag != cached_etag: