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

Route requests more like a normal web server #1539

Merged
merged 10 commits into from
Jul 19, 2024
Merged

Conversation

brandonpayton
Copy link
Member

@brandonpayton brandonpayton commented Jun 24, 2024

Motivation for the change, related issues

This PR updates PHPRequestHandler to route HTTP requests more like a regular web server.

Prior to this PR, we could not easily tell whether we should request a missing static asset from the web or delegate a request for a missing file to WordPress.

Related to #1365 and #1187

Implementation details

This PR:

  • Updates PHPRequestHandler to support custom file-not-found responses
  • Updates worker-thread to configure PHPRequestHandler to handle file-not-found conditions properly for WordPress
  • Updates worker-thread to flag remote WP assets for retrieval by the Service Worker

Testing Instructions (or ideally a Blueprint)

  • CI tests
  • Test manually with npm run dev and observe that Playground loads normally with no unexpected errors in the console

@brandonpayton brandonpayton added [Type] Bug An existing feature does not function as intended [Type] Enhancement New feature or request [Package][@php-wasm] Web [Package][@php-wasm] Universal labels Jun 24, 2024
@brandonpayton brandonpayton requested a review from a team June 24, 2024 19:00
@brandonpayton brandonpayton self-assigned this Jun 24, 2024
@brandonpayton brandonpayton marked this pull request as ready for review June 24, 2024 23:12
@brandonpayton
Copy link
Member Author

This is ready for review and can merge after #1531.

Base automatically changed from remote-asset-list-on-demand to trunk June 25, 2024 01:38
// so the service worker knows it can issue a real fetch() to the server.
return new PHPResponse(
404,
{ 'x-file-type': ['static'] },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good opportunity to rename this to more clearly communicate the intention. Perhaps 'x-file-source': 'remote-server', 'x-backfill-from': 'remote-host', something similar?

Copy link
Member Author

@brandonpayton brandonpayton Jun 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good opportunity to rename this to more clearly communicate the intention. Perhaps 'x-file-source': 'remote-server', 'x-backfill-from': 'remote-host', something similar?

@adamziel Is it OK for us to leave this magic header as-is for now? I made the update but quickly discovered that running with an older Service Worker causes remote asset requests to fail until the updated Service Worker becomes active.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, we are adding both headers in an attempt to be backward compatible with clients running stale service workers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, both headers is a lovely idea ❤️

@adamziel
Copy link
Collaborator

adamziel commented Jun 25, 2024

@brandonpayton let's find a way to not introduce the coupling between PHP and WordPress. The decoupled design paid off dozens of times and once we start coupling, it will quickly become impossible to untangle.

@brandonpayton
Copy link
Member Author

brandonpayton commented Jun 26, 2024

@adamziel thanks for the review! I reviewed all your comments and think we're on the same page.

@brandonpayton let's find a way to not introduce the coupling between PHP and WordPress. The decoupled design paid off dozens of times and once we start coupling, it will quickly become impossible to untangle.

I think we can decouple by using a single callback to determine a fallback for all file-not-found conditions. I have a messy version working locally. The gist is:

when a file is not found:
  get fallback action from callback
  if fallback is internal redirect:
    // This allows us to maintain the general redirect to /index.php outside of PHPRequestHandler
    set FS path to internal redirect path
  else if fallback is response:
    // This allows worker-thread to return special 404s for known remote static files
    // but may be useful in additional ways
    return response
  else
    return regular 404 response

This allows PHPRequestHandler to be decoupled from WordPress. With this approach, the remote worker-thread maintains the WordPress-specific parts, including remote static file responses and handling file-not-found conditions with WP index.php.

Planning to clean this up and push tomorrow morning unless you disagree with the direction.

@adamziel
Copy link
Collaborator

That sounds great @brandonpayton, thank you!

@brandonpayton
Copy link
Member Author

@adamziel PHPRequestHandler is decoupled from WordPress again, and this is ready for another review.

I'm really happy with how the file-not-found callback approach allows us to keep special file-not-found handling logic within the packages that need it.

type: 'response',
response: new PHPResponse(
404,
{ 'x-file-type': ['static'] },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

X-file-type static doesnt mean much anymore in this context when it also works for .php paths, it would be nice to tell the service worker „please fetch from the server” using a different object shape

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I’m just pointing at the string used)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's not great. Unfortunately, I haven't figured out how to adjust this and not break for clients still running with the older Service Worker:

From this comment:

That's a good opportunity to rename this to more clearly communicate the intention. Perhaps 'x-file-source': 'remote-server', 'x-backfill-from': 'remote-host', something similar?

@adamziel Is it OK for us to leave this magic header as-is for now? I made the update but quickly discovered that running with an older Service Worker causes remote asset requests to fail until the updated Service Worker becomes active.

One thing we could do for now is send the new preferred header while continuing to send the old, like:

{
    'x-backfill-from': [ 'remote-host' ],
    // Include this header for remote assets via out-of-date service worker
    'x-file-type': [ 'static' ],
}

I'm planning to go this route for now.

@brandonpayton
Copy link
Member Author

@adamziel This is ready for another review.

@adamziel
Copy link
Collaborator

Almost there @brandonpayton! Let's also rebase to make sure this works well with the latest trunk and the last few PRs @bgrgicak merged

@brandonpayton
Copy link
Member Author

This should be ready to merge, but there are some odd test failures in CI that I have not been able to reproduce locally. Planning to take another look tomorrow.

This PR:
- Updates PHPRequestHandler to support custom file-not-found responses
- Updates worker-thread to configure PHPRequestHandler to handle
   file-not-found conditions properly for WordPress
- Updates worker-thread to flag remote WP assets for retrieval by the
    Service Worker

Prior to this PR, we could not easily tell whether we should request a
missing static asset from the web or delegate a request for a missing
file to WordPress.

Related to #1365 where we need better information to judge whether to
handle a request for a missing static file as PHP.

- CI tests
- Test manually with `npm run dev` and observe that Playground loads
normally with no unexpected errors in the console
@brandonpayton
Copy link
Member Author

I am currently troubleshooting why we are getting unit test failures under this PR in CI only. My current theory is that we've added so many tests that we might be hitting some sort of memory limit. Unfortunately, we cannot continue looking into this at the moment because GH actions are not running properly:
Screenshot 2024-07-18 at 9 34 22 PM

Planning to resume in the morning.

@brandonpayton brandonpayton changed the title Route requests for missing static files using remote asset metadata Route requests more like a normal web server Jul 19, 2024
…est execution into multiple processes"

This reverts commit 55d9830.
When these are included, GH auto-cancels the CI unit test workflow.
@brandonpayton
Copy link
Member Author

The CI unit test errors appear to go away when we reduce the number of tests for PHPRequestHandler. To confirm this isn't a real PHPRequestHandler issue, we can switch between

  • disabling new test permutations for multiple docRoots and absolute URLs
  • running all those permutations but only for a single PHP version

If both of those pass, I plan to reduce the number of docRoot/absoluteURL permutations for the time being.

If we have to revert the request routing changes,
it may leave some users with a Service Worker from those
routing changes, so we want to make sure the service worker
still supports loading remote assets in response to the
x-file-type header.
@brandonpayton
Copy link
Member Author

The CI unit test errors appear to go away when we reduce the number of tests for PHPRequestHandler. To confirm this isn't a real PHPRequestHandler issue, we can switch between

  • disabling new test permutations for multiple docRoots and absolute URLs
  • running all those permutations but only for a single PHP version

If both of those pass, I plan to reduce the number of docRoot/absoluteURL permutations for the time being.

Both combinations passed with no issues. For now, we can reduce the number of docRoot/absoluteURL permutations until we can figure out why the CI unit test workflow is being auto-canceled. (guess: hitting some kind of memory limit)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package][@php-wasm] Universal [Package][@php-wasm] Web [Type] Bug An existing feature does not function as intended [Type] Enhancement New feature or request
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

2 participants