-
-
Notifications
You must be signed in to change notification settings - Fork 382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes "the connection was closed by the remote peer" error #389
Conversation
from boto3 import resource
mocker = moto.mock_s3()
mocker.start()
r = resource('s3')
r.Bucket('bucket').create()
r.Object('bucket', 'key').put(Body=b'123456')
obj = r.Object('bucket', 'key')
body = obj.get()['Body']
print(body.read(1)) # b'1'
body.close()
try:
print(body.read(1))
except Exception as e:
print(type(e)) # <class 'ValueError'>
print(e) # I/O operation on closed file.
mocker.stop() |
I would think it's an issue related to moto. We may need to raise it there. :( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know when this is no longer WIP and I'll have a closer look.
The overall direction looks right to me.
smart_open/tests/test_s3.py
Outdated
class SeekableRawReaderTest(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self._local_resoruce = boto3.resource('s3', endpoint_url='http://localhost:5000') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo:
self._local_resoruce = boto3.resource('s3', endpoint_url='http://localhost:5000') | |
self._local_resource = boto3.resource('s3', endpoint_url='http://localhost:5000') |
@Gapex Thank you for your patience! This is a very welcome contribution. Keep them coming! |
SeekableRawReader reopens a connection after getting a IncompleteReadError
Motivation
The current SeekableRawReader sends HTTP request in the
seek()
method, and keeps an continuous connection with the remote peer. But if the SeekableRawReader does not read from the connection immediately afterseek()
, the remote peer may close the connection due to a timeout. Then, the SeekableRawReader attempts to read on a StreamingBody whose underlying connection had been closed, and gets a botocore.exceptions.IncompleteReadError, the following example shows the case:In the above code, the
body
is closed by client actively to stimulate connection closed by the remote peer.In the PR, I intended to delay the action of sending HTTP request until read, the solution solved the problem of closed connection between a pair of
seek() - read()
, but introduced a similar problem between continuousread()
, namely, the connection may also be closed by the remote peer after a read, if the second read occurs a long time later.In this PR, I try to catch the IncompleteReadError in the
read()
directly, if connection is close, and IncompleteReadError is raised,seek()
from the current offset to build a new connection with remote peer.