-
Notifications
You must be signed in to change notification settings - Fork 704
WIP: add support for upstream command "/path/to/command"
#228
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
base: master
Are you sure you want to change the base?
Conversation
that sounds like premature optimization
i'm actually working on / have finished a port to thread which i plan to make the default soon (check my i think we should keep it as simple as possible. for example the script could return a line containing a config directive like |
Without a use case, I would agree with you. But initialization of the script I'm using currently takes hundreds of milliseconds, and message passing takes only hundreds of micro seconds. (My personal perception of what kinds of delays are acceptable is coloured by working with envoyproxy in a service mesh setting; there, I run http queries that should have a P99 of ~10ms. That's why I'm hoping to push any overhead into microsecond land.) And while it does add some complication, some of that is unavoidable with a subprocess anyway. A subprocess can fail (or worse, hang) for many reasons regardless of whether it's expected to run briefly or continuously, and some accommodation needs to be made for that.
Ah! This is exactly the kind of stuff for which I like getting early feedback :) I'll take a look and it may even be wise to rebase my work on top of that one from the get-go.
Yes I like that idea!
I'm not sure I agree with that. Processes error out in many different ways; they may even hang and that carries the risk of tinyproxy hanging on a
This sounds like you have portability concerns with some of the other |
For putting these numbers in context, even just starting a
|
the message passing stuff you're talking about can be done in the script/program that's called. for example you could have some javascript interpreter service running which takes requests on a socket, and the spawned process just does something like
this logic can all be stuffed in the called program too.
you've added a configure check for fdopen, which (without knowing alot about that API) suggests that it might be lacking - otherwise there would be no need to check for it, correct ? |
Fair enough. It's fine if we'd make different tradeoffs between code simplicity on the one hand and latency + defensiveness on the other. After all, it's your standards that count for I also like your suggestion for forking off So, thanks for helping me sort this out before I've gone down a rabbit hole of implementation. I looked into As for In summary, here's what I'd propose:
|
ah, popen() does indeed call the shell, rather than passing an argv array. that pretty much precludes its usage in a potentially hostile env. some other thoughts:
|
Can I make an observation? I don't mind any of your suggestions, but I also don't always agree they are much better; they are just alternatives. That doesn't mean I'm unwilling to implement them, but it leaves me with the feeling that anything I may be about to write will go through five back-and-forths before it is exactly as you would have written it. That's a wasted effort on both your side and mine, if the outcome is code in the way you would write it. Isn't it just better if you implement this? That may even cost you less time than reviewing what I write. |
Why not just use a single hostname in config and let dns handle the discovery of the right proxy server. This is way simpler and doesn't bloat tinyproxy with additional logic and risks. A or AAAA for direct mapping and CNAME as offload. |
This is a first stab at #224 : a way to get arbitrarily complex upstream proxy logic by forking out to a user-defined command. As it is now, it contains many
TODO
comments; I'm opening this pull request now to open it up to feedback as early as possible. @rofl0r, I would appreciate any insight / suggestions / corrections!As described in that ticket, my idea is to keep a single subprocess (per worker) running. Messages are passed over pipes connected to its
stdin
andstdout
. An easier alternative would be to fork off a new process every time we need it, but I'd really like to amortize any initialization cost for the subprocess. (In my target use case, the subprocess needs to initialize a javascript interpreter.)After receiving the result from the subprocess, this commit modifies the fields of a
struct upstream
in-place. This would be a problem iftinyproxy
handles several connections simultaneously in the same process, but I couldn't spot any evidence for that happening. Please correct me if I'm wrong.