Skip to content
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

socket.bind() is a blocking call #241

Closed
njsmith opened this issue Jul 6, 2017 · 2 comments · Fixed by #378
Closed

socket.bind() is a blocking call #241

njsmith opened this issue Jul 6, 2017 · 2 comments · Fixed by #378

Comments

@njsmith
Copy link
Member

njsmith commented Jul 6, 2017

...for UNIX domain sockets, since it has to do filesystem traversal.

And for non-UNIX-domain sockets, it also is if you pass in the host or port by name. So far we avoided this by making all the methods on trio.socket.socket only accept "pre-resolved" host/port combos. Which is a bit awkward; really the main motivation was that bind was logically a non-blocking call, so it can't call getaddrinfo, and then I made this the rule across-the-board to keep things consistent. But maybe it would be better to instead make bind async, and then drop the whole "pre-resolution" thing and if the user passes us an unresolved address, just silently resolve it for them.

@njsmith
Copy link
Member Author

njsmith commented Jul 6, 2017

I guess there are two options for handling this:

Option 1: Always use run_in_worker_thread for bind. Let Python do whatever resolution it wants to do. This is nice because it lets us dump our pre-resolution code (at least for local addresses). Problems: this way you can't cancel bind, because bind has side-effects. This is awkward if its off in a long-running getaddrinfo; really for AF_INET{,6} sockets we want cancellation to take effect if it's still in the getaddrinfo part, which is slow and has no side-effects, but not if it's in the final bind part part, which is fast and has side-effects. Also, it would mean our regular getaddrinfo replacement machinery (#159) wouldn't work.

Option 2: keep our "pre-resolving" code, but move it internal to bind, and likewise for the other functions that take addresses. Run the actual bind call in a worker thread iff self.family == AF_UNIX (and the given address is not a Linux abstract address). This is a bit risky (we're trying to replicate Python's internal code for this kind of thing), but probably works fine in practice. I guess we might have to do this.

@njsmith
Copy link
Member Author

njsmith commented Aug 9, 2017

Since currently, writing explicit bind calls is the only way to make a network server in trio, this actually is a somewhat disruptive compatibility break. Maybe we should get the high-level listener APIs into 0.2.0 so people can start migrating to that before making this change.

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

Successfully merging a pull request may close this issue.

1 participant