-
Notifications
You must be signed in to change notification settings - Fork 112
Commit
…using stream_slice.StreamSlice.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -982,8 +982,13 @@ def __SendMediaBody(self, start, additional_headers=None): | |
if self.total_size is None: | ||
raise exceptions.TransferInvalidError( | ||
'Total size must be known for SendMediaBody') | ||
# Change body_stream from a stream to a string object. This is | ||
# because httpwrapper.MakeRequest doesn't handle the case where | ||
# request.body is a stream. In the case that the body is a stream, | ||
# if a request has to be retried, then the stream will be exhausted | ||
# and the request will hang. | ||
body_stream = stream_slice.StreamSlice( | ||
self.stream, self.total_size - start) | ||
self.stream, self.total_size - start).read() | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
kevinli7
Author
Contributor
|
||
|
||
request = http_wrapper.Request(url=self.url, http_method='PUT', | ||
body=body_stream) | ||
|
@@ -1032,6 +1037,12 @@ def __SendChunk(self, start, additional_headers=None): | |
else: | ||
end = min(start + self.chunksize, self.total_size) | ||
body_stream = stream_slice.StreamSlice(self.stream, end - start) | ||
# Change body_stream from a stream to a string object. This is | ||
# because httpwrapper.MakeRequest doesn't handle the case where | ||
# request.body is a stream. In the case that the body is a stream, | ||
# if a request has to be retried, then the stream will be exhausted | ||
# and the request will hang. | ||
body_stream = body_stream.read() | ||
# TODO(craigcitro): Think about clearer errors on "no data in | ||
# stream". | ||
request.body = body_stream | ||
|
Isn't the whole point of using a StreamSlice to be able to read a small part of a stream, and not the entire thing all at once? This means calls to an Upload object's StreamMedia() will attempt to read the whole stream into memory which defeats the purpose of using a stream for large files and falls apart if the bytes you're streaming in won't all fit into memory.
FWIW, I found this out from running gsutil's integration tests and seeing that some of our tests started failing because we were reading more bytes than expected when calling StreamMedia on an Upload object, resulting in read() being called on the stream wrapper with a higher number of bytes than expected:
https://github.com/GoogleCloudPlatform/gsutil/blob/8f8a61a7d7b7b5202f3cf1dc5e49b8082669a05d/gslib/daisy_chain_wrapper.py#L217