-
Notifications
You must be signed in to change notification settings - Fork 107
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
UDS Support #138
Comments
I'm not sure if we do or don't want this built in, but something that'd help it along immensely would be a PR adding support for it back into httpcore, based on the initial work in encode/httpx#511 - tho it's less clear to me if integration with our connection pooling etc really makes sense in this context. Something else that'd help is a really end user motivation for UDS support. Why might an end user want to plug the client into a UDS? What behaviour does it allow, why is it a useful thing to do, and how do we document the use case to our users? |
It's also perfectly possible that we'd prefer to instead have UDS support maintained as a third party library. Given that we've gone to the trouble of a really nicely spec'ed Transport API, that's a very doable thing, and could well be a better approach. One other thing worth evaluating - what support do each of requests, urllib3, aiohttp have for UDS? Finally is there any sense in HTTP/2 over UDS or does it not really make much sense in that context? |
That's my biggest concern really. From my POC implementation linked by OP, all we need is an HTTP/1.1 connection plugged into a UDS socket. We don't need connection pooling, HTTP/2, proxies, none of all that. Which is why I'm currently inclined to still consider this should be a third party package, which potentially vendors the HTTP/1.1 connection implementation if it's not up for importing private API. This is on par with the Requests ecosystem, since UDS lives in requests-unixsocket I believe (tho it's implemented as an adapter because requests doesn't have a notion of transport, which ends up being a bit clunky).
I think I've shared this use case before, but for example the local Docker API is only available through a Unix Socket (the Still not as widespread as "make an HTTP request over the network", obviously. |
One argument in favor of having it in code tho is that
I think packaging up my implementation gist as a PR on the HTTPCore repo would help better evaluate these points... Anyone up for it could just go at it I guess. :-) |
Right, well a (Rather than a UDS=... argument on the connection pool) |
Exactly, yes. :-) |
I did not search on this before, did not realize you guys had previously talked at length on this. The way I would implement UDS completely independent of any library is to make a context which spawns a sub-process, which finds a free port and runs socat to tunnel the tcp traffic, as mentioned in this SO answer.
Here are some reasons I can think of to use UDS over TCP ports:
In terms of the multiplexing benefits, in theory, you're removing additional descriptor needs from handling multiple 1.1 connections. Also it could be used for testing/etc. But if it's easier to just implement for 1.1 that's probably ok too. |
Hrm, thinking about it again, I'm not so sure. Surely you really do want the standard connection pooling behaviour, so that you're opening multiple connections if you've got multiple concurrent requests. |
My thinking was rather a simplistic form of pooling directly on the transport, eg "connect if not connected yet". We'd connect on the first request and then send all subsequent requests on the same connection. You're passing the UDS path on init, so there's really only ever one connection (no equivalent to per request host-port like in the TCP case). Or am I missing something? Edit: ah well yes, when one thinks about "what happens for concurrent requests" then obviously you'll want multiple connections + pooling so that request A doesn't interact with request B... Hmm. |
I don't think there's anything about the high-level "pool" concept that would need huge divergence in API/logic or user expectations when it comes to UDS vs TCP. But perhaps I'm missing something too. I can't speak to httpcore/httpx's pooling strategy specifically. |
Actually, it's really more complex than I thought. First, a bit of an overview of other clients: What other clients doWith curl --unix-socket /var/run/docker.sock http://localhost/info With import requests_unixsocket
session = requests_unixsocket.Session()
r = session.get('http+unix://%2Fvar%2Frun%2Fdocker.sock/info') (Yes, percent-encoding is recommended in the official docs. Also they're recommending (but not enforcing) the usage of Considerations on HTTP over UDSSome points on which I was mistaken before:
So URLs should be restricted to Now, what do we do with this…? OptionsA/ Add UDS support into core via
|
Another thought: allow users to add a pre- connected socket into the pool manually. That way, the library doesn't even need to be aware of whether it's TCP vs UDS. I bet that's like a 2 line change to expose an API method? It would require some documentation / tips on outside setup / insertion of such a pre-connected UDS socket, but maybe that's easier vs doing all the socket establishment/handling inside the library. EDIT: you'd also need a nice way to bind a request to that specific added connection in the pool somehow (some special origin style or something) |
Interesting idea yeah, though it's most likely not as simple as you might think.
But definitely worth considering too, as a more general solution... |
I was thinking you'd just create an identifier, like so:
Then the pool would treat the connection as a brand new empty-state connection, and would do everything it normally does with the exception of the actual socket connect. I don't know exactly where you put the I should probably stop talking now without actually looking through documentation and/or soure code.. but I don't really have time to do that. Maybe I can just be the "outside naive voice" in this issue thread :) |
So yup, transport = httpcore.SyncConnectionPool(uds=...) And document it's usage alongside |
This httpx chanelog PR, as part of a movement to sunset usage of urllib3 in favor of httpcore, mentions UDS support as a temporary casualty of the process because "maintaining that would have meant having to push back our work towards a 1.0 release".
Regarding putting this support back into httpcore, there has been recent work done in this proof of concept (thanks @florimondmanca ) that suggests that including UDS support inside the library would not be an overwhelming task.
I personally use a lot of inter-service communication via unix sockets so this would be (opinion) a welcome addition as a first-class citizen of the new release.
I am brand new to this library; I have only used pre-httpcore httpx. After upgrading past 0.12 of httpx, I was surprised that my code could no longer use the uds= keyword when creating clients, enough to blow up on the trio gitter (apologies). I now understand that keeping to a release schedule and making everyone happy is an extremely hard task!
@tomchristie suggested this issue be created to start a discussion here. Go!
The text was updated successfully, but these errors were encountered: