jupyterlite/pyodide-kernel

Pyodide mounting issue with browser hard refreshes

Closed this issue · 6 comments

Description

I found out that when doing hard refreshes in Chrome, the Pyodide mounting with the local files in the browser was failing or at least leading to issues. With regular refreshes it works fine.

The difference between the hard and regular refreshes (from this SO thread):

  • Regular: The same thing as pressing F5. This will use the cache but revalidate everything during page load, looking for "304 Not Modified" responses. If the browser can avoid re-downloading cached JavaScript files, images, text files, etc. then it will.
  • Hard: Don't use anything in the cache when making the request. (which is equal to SHIFT+F5 No need to open Developer console) Force the browser do re-download every JavaScript file, image, text file, etc.

The dev console doesn't show any error, however, I reproduce on a local Jupyterlite instance and the console shows an error:

[LiteServeApp] WARNING | 

        Serving JupyterLite Debug Server from:
            /Users/thibaut/Documents/myjl/dist
        on:
            http://127.0.0.1:8000/index.html

        *** Exit by: ***
            - Pressing Ctrl+C
            - Visiting /shutdown
404 GET /favicon.ico (127.0.0.1) 4.09ms
405 POST /api/drive (127.0.0.1) 1.75ms
405 POST /api/drive (127.0.0.1) 0.27ms

So it doesn't look like this error is catched here in the code.

Here a video showing the error with hard refreshes:

pyodide_mounting_bug.mp4

Reproduce

  1. Go to any Jupyterlite instance
  2. Open the Pyodide console or notebook.
  3. Run Python code interacting with the file system. -> should work fine.
  4. Perform hard refresh (cmd + shift + R on mac or ctrl + F5 on Windows)
  5. Run Python code interacting with the file system agin. -> should fail.

Expected behavior

Hard refreshes shouldn't cause the issue.

Context

  • JupyterLite version: 0.1.3 (haven't tried 0.2.0 but I would suspect it's the same)
  • Operating System and version: macOS Ventura 13.2
  • Browser and version: Chrome Version 118.0.5993.117 (Official Build) (arm64)
Browser Output (nothing outstanding)
JupyterLite ServiceWorker was already registered
index.ts:235 Kernel filesystem and JupyterLite contents will be synced
index.js:51 Pyodide contents will be synced with Jupyter Contents
pyodide.asm.js:9 Loading micropip, packaging
pyodide.asm.js:9 Loaded packaging, micropip
pyodide.asm.js:9 Loading sqlite3
pyodide.asm.js:9 Loaded sqlite3
pyodide.asm.js:9 Loading decorator, pygments, jedi, parso, six
pyodide.asm.js:9 Loaded decorator, parso, six, pygments, jedi

I've had some issues with hard refreshes in Chrome myself, and I have seen that the service worker doesn't get started properly. If you do a hard refresh and open dev tools -> Application -> Service workers, what do you see? Try to unregister all first and then refresh.

image

I'm kind of glad I see someone else also have seen issues with this. I never had this problem on 0.1.0, and never on localhost on 0.1.3, so had a hard time understanding what was going on.

Relevant links:

https://web.dev/articles/service-worker-lifecycle#shift-reload

Will take a look into this and see if we can come up with a fix now that I'm aware others see it too. It's likely connected with the lack of a way to wait for the serviceWorker.controller. We have a hunch.

Other people have had this problem (hypythesis at least), and made this: https://github.com/PolymerElements/platinum-sw/blob/master/test/controlled-promise.js

Testing this approach.

Potential fix in jupyterlite/jupyterlite#1251

I can no longer reproduce the steps you mentioned with this fix. Can you verify?

Thank you for looking into it and finding a solution so fast. I have tested it on the Jupyterlite build of your pull request and I was not reproducing the issue!!