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

feat: trace resource requests to allow fetching dynamic resources from pyodide process without a page refresh #5

Merged
merged 2 commits into from
Nov 6, 2022

Conversation

hydrosquall
Copy link
Owner

@hydrosquall hydrosquall commented Nov 5, 2022

Motivation

Terminology

  • pyodide is project that lets us run Python in web browsers via WebAssembly (WASM).
  • An asset is a file generated by the Datasette server running in Pyodide.
    • This could be CSS from a static folder, JS from Datasette, rendered text content, or JS from a plugin
  • serviceworker is a JS script that intercepts requests. It can't reach the webworker directly.
  • webworker is a JS script that hosts pyodide. It isn't strictly required, but we do it because the file is big + potentially slow. Code in the webworker doesn't interrupt the main rendering thread. It can't reach the serviceworker directly.
  • "HTML page" - this refers to the page that contains the DOM that the user sees. It also acts as a bridge between the webworker and serviceworkers.

Changes

In #4, assets were only available on the second fetch. I wasn't sure how to block the service-worker process while it was waiting for the webworker to respond. This PR removes that hurdle by using JS Promises . Instead of checking for the datasette response in a cache, the service-worker uses a requestId as a form of "bookkeeping" for the server to include in its response, ensuring that response can be matched to the request with a message-passing rather than callback-based dataflow.

  • When the host HTML page requests an asset server-worker.js intercepts the request, and decides whether to check for it in the local cache, pass it through to the public internet via fetch, or ask the web-worker for it.
  • If it needs help from the webworker, we add an entry to the registry with a unique requestId to handle an async message from the webworker, and wait for up to TIMEOUT seconds. A message is sent to the parent HTML page that can be forwarded to the webworker, including a requestId and a path.

Meanwhile, in the webworker, we await messages from the other process. The Pyodide process uses the path to generate an appropriate response (text, json, etc), and returns it (including a proper MIME Type) along with the requestId.

Finally, back in the serviceworker: when we receive a message with a requestId, we return the result to the host HTML page. To cleanup / free up memory, we delete the "pending" request from the response registry.

Testing

Notes

  • Faceting in the gear doesn't work, hiding column in URL doesn't work either, due to assumptions that the table.js code made about the structure of the parent page's URL. However, if you construct the URLs manually (like in my testing section), it will work.
  • Pyodide assets are cached, so this should work offline after the first load Moving this part to a separate PR

Illustrated Explainer

Here's a cartoon of the problem that this PR solves.

image

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 5, 2022

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: b859411
Status: ✅  Deploy successful!
Preview URL: https://d2ae7b89.datasette-lite.pages.dev
Branch Preview URL: https://cameron-yick-feature-trace-r.datasette-lite.pages.dev

View logs

@hydrosquall hydrosquall marked this pull request as ready for review November 5, 2022 21:34
@hydrosquall hydrosquall changed the title feat: update build for arm64 arch feat: trace resource requests to allow usage without page refreshes Nov 5, 2022
@hydrosquall hydrosquall changed the title feat: trace resource requests to allow usage without page refreshes feat: trace resource requests to allow interaction without page refresh Nov 5, 2022
@hydrosquall hydrosquall changed the title feat: trace resource requests to allow interaction without page refresh feat: cache pyodide assets (offline friendly), trace resource requests to allow interaction without page refresh Nov 5, 2022
@hydrosquall hydrosquall self-assigned this Nov 5, 2022
@hydrosquall hydrosquall force-pushed the cameron.yick/feature/trace-requests-no-refresh branch from 463f558 to b859411 Compare November 6, 2022 00:15
@hydrosquall hydrosquall merged commit 087c8aa into main Nov 6, 2022
@hydrosquall hydrosquall changed the title feat: cache pyodide assets (offline friendly), trace resource requests to allow interaction without page refresh feat: trace resource requests to allow interaction without page refresh Nov 6, 2022
@hydrosquall hydrosquall changed the title feat: trace resource requests to allow interaction without page refresh feat: trace resource requests to allow fetching dynamic resources from pyodide process without a page refresh Nov 6, 2022
@hydrosquall hydrosquall deleted the cameron.yick/feature/trace-requests-no-refresh branch November 6, 2022 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant