Skip to content
This repository was archived by the owner on Jan 13, 2021. It is now read-only.

Improve handling of socket errors #221

Conversation

tbetbetbe
Copy link
Contributor

  • Use the default connection timeout set by socket.setdefaulttimeout().
  • I.e, don't specify one, until there is an API for timeouts, it's
    probably better for libraries to be able to set the socket timeout
    outside of hyper via setdefaulttimeout
  • Updates error handling to simulate blocking behaviour when the socket
    is in timeout mode (which is internally a kind of non-blocking
    mode). Specifically, during reads, add
    • handling of specific ssl.SSLErrors WANT_READ and WANT_WRITE
    • handling of errno.EAGAIN and errno.EINTR

- Use the default connection timeout set by socket.setdefaulttimeout().

* I.e, don't specify one, until there is [an API][1] for timeouts, it's
probably better for libraries to be able to set the socket timeout
outside of hyper via [setdefaulttimeout][2]

- Updates error handling to simulate blocking behaviour when the socket
  is in timeout mode (which is internally a kind of non-blocking
  mode). Specifically, during reads, add
  * handling of specific ssl.SSLErrors WANT_READ and WANT_WRITE
  * handling of errno.EAGAIN and errno.EINTR

[1]: python-hyper#187
[2]: https://docs.python.org/2/library/socket.html#socket.setdefaulttimeout
@Lukasa
Copy link
Member

Lukasa commented Apr 13, 2016

Firstly, thanks @tbetbetbe! This is a good set of changes.

I have some concerns about the branch for ssl errors though. Specifically, I'm concerned about repeatedly looping on ssl.SSL_ERROR_WANT_WRITE when we're only reading from the socket. I'm concerned that, if that's raised, we could spin forever there.

Does the python ssl module do something to avoid that being a risk?

@tbetbetbe
Copy link
Contributor Author

Does the python ssl module do something to avoid that being a risk?

Not that I'm aware of.

The PR as is addresses a set of sporadic but consistent test failures I was seeing in a library I'm working on that's based on hyper.

ssl.SSL_ERROR_WANT_WRITE should only get raised if something is writing to the socket when it's in timeout mode. I believe it's common to treat it as a transient failure here, on the assumption that any concurrent writer seeing that transient failure will handle it by continuing. I.e, the approach is effective if the potential readers and writer of the socket are all handling the transient errors in the same way.

Because of that, it's may be a good idea to replace the call to sendall with a loop around send that does the same kind of handling. At the moment, if sendall fails with a transient SSL error, recovery will not be possible as we don't know how much data was written.

Another approach is to place a timeout on the loop as in ssl_compat

I'd be happy to either

  • update this PR with a timeout for the loop or
  • update this PR so that it changes sendall as well or
  • leave this change as is and track the sendall/timeout changes as a proposal in a separate issue or
  • switch this change to loop on ssl.SSL_ERROR_WANT_READ as you suggest

Any of these are OK, as long the tests failures I was seeing remain resolved. Which approach do you prefer ?

@Lukasa
Copy link
Member

Lukasa commented Apr 13, 2016

I think just merging this is fine: consider me swayed by your argument. =D

@Lukasa Lukasa merged commit 9a9b048 into python-hyper:development Apr 13, 2016
@matangover
Copy link
Contributor

If I'm not mistaken, this PR has introduced a NameError in the code - please observe line 545 in connection.py (it accesses sleep, which is not imported).

Thanks goes to pylint for warning about this. :)

@tbetbetbe
Copy link
Contributor Author

Yup, sorry that's correct.

That should be time.sleep, with a corresponding import of the time module. I will prepare a follow-up PR to correct this.

@Lukasa
Copy link
Member

Lukasa commented Apr 19, 2016

Thanks both @matangover and @tbetbetbe!

Some day this week I'll be cleaning up the linter errors in this project and enforcing flake8 compliance in the CI suite: consider yourselves warned. ;)

@Lukasa
Copy link
Member

Lukasa commented Apr 19, 2016

@tbetbetbe There's no need for a follow-up PR: I've started work on the linting today, and so I'll be sweeping it up anyway. =)

@Lukasa
Copy link
Member

Lukasa commented Apr 19, 2016

See #226.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants