-
Notifications
You must be signed in to change notification settings - Fork 425
feat: worker matching #1646
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
feat: worker matching #1646
Conversation
|
I think I prefer the latter of the two options, but I can see the benefits of the first one too. |
|
Thinking about it, the first option makes it maybe clearer that this is only possible inside of |
|
FYI, you might want to explore using pprof's I think this is the syntax
You could do 1v2 and 1v3 to easily see where and how much the difference is |
|
I've managed to create a differential flamegraph via this guide # first profile
go tool pprof -raw -output=cpu1.txt 'http://localhost:2019/debug/pprof/profile?seconds=20'
#second profile
go tool pprof -raw -output=cpu2.txt 'http://localhost:2019/debug/pprof/profile?seconds=20'
# diff flamegraph
./stackcollapse-go.pl ./cpu1.txt > out.folded1
./stackcollapse-go.pl ./cpu2.txt > out.folded2
./difffolded.pl -n out.folded2 out.folded1 | ./flamegraph.pl > /go/src/app/flamegraph.svgA bit hard to make out what's the difference between 'red' and 'blue' though |
|
I'm very strongly in favour of option one, simply because it will allow the match to behave in a general scope, such as for assets (php_server also has a file_server built in, it would also benefit) as well. |
|
@henderkes what would php_server {
match /path1/* worker /anywhere/worker1.php
match /path2/* worker /anywhere/worker2.php
match /assets/* fileserver
}
# if nothing matches continue to the next directive |
|
If /assets/some_asset.png isn't found, it should 404 of course. But that's the same as falling through to the default behaviour of file_server, is it not? |
|
I mean if it matches neither of the paths |
|
oh, then it should fall through to the default behaviour. |
|
Hmm makes sense, so the order would be:
|
|
I was thinking more along the lines of
|
|
Hmm I'm still not sure about The reason the |
That would be quite confusing and might also hurt performance of regularly handled requests, because it has to go through all global workers and try to match the path, even if it was never intended and never produces a match.
But not with the match directive. It's an explicit tell that all routes with /path1/* should be handled by the worker. There absolutely doesn't and shouldn't be a file_server involved with that at all. If a user configures route {
@assets path /path1*
handle @assets {
rewrite worker1.php
php
}
}and then expects an image in that path1 to be served by a file server.
That's pretty much what it would be. The reason it should exist is something like this: php_server {
match /path1/images/* file_server
match /path1/* worker worker1.php
}And that's also what I envision the What I think would happen when a php_server (or php) directive is hit in pseudocode: (FrankenPHPModule* f) handleRequest(httpRequest r) {
path := r.URL.Path
for pattern, handler in range f.matches {
if path matches pattern
handler(r)
}
// fallthrough to current logic
}
|
This would not work since we would never hit the php module via
While I can see the benefit of an abbreviation like this, it wouldn't cover the most common use case, which is So I'm still a bit torn, but now leaning more towards the worker->match direction, also because the implementation is simpler. php_server {
worker {
file /anywhere/worker.php
match *
}
} |
In that case match ... file_server really doesn't make sense. Unless we were to register a different directive, but that's exactly what I wanted to avoid.
If serving files is always tried before our php module handler is even hit, wouldn't the equivalent just be php_server {
match /path1/* worker worker1.php
// fall back to normal logic to see if we can match against a worker or use a regular php thread
}
I really don't like the other way around. It just doesn't make sense. The worker doesn't perform any matching, the worker should never even be queried if it didn't match the request. |
|
Yeah these 2 would be equivalent, depends on how you think about it and how this might be extended in the future php_server {
match /path/* worker /anywhere/worker.php
}php_server {
worker {
file /anywhere/worker.php
match /path/*
}
} |
d3d8405 to
b8ad01a
Compare
dunglas
left a comment
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.
Is this one ready to be merged? Could you add some docs?
|
Yes I think this one is ready to merge. I'll add some docs (in this PR or a separate one, whichever you prefer) |
…nkenphp into feat/worker-matching # Conflicts: # caddy/module.go # caddy/workerconfig.go # frankenphp.go # phpmainthread_test.go # worker.go
|
Docs are added 👍 |
|
Could you please rebase @AlliBalliBaba? |
# Conflicts: # caddy/workerconfig.go # phpmainthread_test.go # worker.go
…nkenphp into feat/worker-matching
|
Merged 👍 |
|
Great work, thank you! Regarding the GitHub issue, I discussed with the PHP team, and they are reluctant to add 2 accounts for the same person. Would you prefer that we remove @AlliBalliBaba and add @AlliBalliBaba2 instead? |
|
Hmm yeah maybe this account is just irreversibly broken and I'll have to migrate over to @Alliballibaba2, all of these github support issues didn't really go anywhere |
|
Nevermind, just got feedback that actions work again 🎉 |
This one is interesting — though I’m not sure the best way to provide a test. I will have to look into maybe an integration test because it is a careful dance between how we resolve paths in the Caddy module vs. workers. I looked into making a proper change (literally using the same logic everywhere), but I think it is best to wait until #1646 is merged. But anyway, this change deals with some interesting edge cases. I will use gherkin to describe them: ```gherkin Feature: FrankenPHP symlinked edge cases Background: Given a `test` folder And a `public` folder linked to `test` And a worker script located at `test/index.php` And a `test/nested` folder And a worker script located at `test/nested/index.php` Scenario: neighboring worker script Given frankenphp located in the test folder When I execute `frankenphp php-server --listen localhost:8080 -w index.php` from `public` Then I expect to see the worker script executed successfully Scenario: nested worker script Given frankenphp located in the test folder When I execute `frankenphp --listen localhost:8080 -w nested/index.php` from `public` Then I expect to see the worker script executed successfully Scenario: outside the symlinked folder Given frankenphp located in the root folder When I execute `frankenphp --listen localhost:8080 -w public/index.php` from the root folder Then I expect to see the worker script executed successfully Scenario: specified root directory Given frankenphp located in the root folder When I execute `frankenphp --listen localhost:8080 -w public/index.php -r public` from the root folder Then I expect to see the worker script executed successfully ``` Trying to write that out in regular English would be more complex IMHO. These scenarios should all pass now with this PR. --------- Signed-off-by: Marc <[email protected]> Co-authored-by: henderkes <[email protected]> Co-authored-by: Kévin Dunglas <[email protected]>
This is an alternative to #1552. instead of having a new directive, this introduces a way to match workers against paths, therefore allowing placing the worker anywhere outside of the public directory..
wip
not sure yet if this is better:
or this:
performance:
default

php_serverwihworkerphp_serverwihworkerandtry_files {path} index.phpphp_serverwihworkerandmatch *(minimizes file operations)