Skip to content

Conversation

adamziel
Copy link
Collaborator

@adamziel adamziel commented Jun 13, 2023

Description

#544 explores a full Emscripten OPFS filesystem backend, but
there is one last issue I may not be able to figure out before my
Sabbatical (June 26th - Sep 26th).

This PR attempts another approach I should be able to ship. Namely,
it synchronizes MEMFS changes to OPFS and restores them after a
page refresh.

The main idea is:

  1. Keep track of all modified files
  2. Only sync files on that list

OPFS is only supported in Chrome-based browsers at the moment like Edge, Android browser. Safari and Firefox users won't be able to benefit from this feature yet

Performance

  • Full WordPress OPFS->MEMFS: ~340 ms
  • Full WordPress MEMFS->OPFS: ~506 ms
  • Typical sync MEMFS->OPFS: 2.5 ms

Other explored approaches

This approach failed:

  1. Compare last modified time
  2. Copy MEMFS files to OPFS if they were updated more recently

mtime doesn't bubble up through directories and comparing all files is too slow.

Screenshots

CleanShot.2023-06-13.at.10.47.30.1.mp4
CleanShot 2023-06-13 at 23 45 58@2x CleanShot 2023-06-13 at 23 46 11@2x

Remaining work

  • Fix crash on plugin upload
  • Only apply PHP patches once
  • Disable OPFS by default, add a worker setting to enable it
  • Add a query parameter to enable OPFS
  • Integrate the synchronizer without changing PHP internals
  • Move it to @wp-playground/remote package
  • Do not perform a full MEMFS->OPFS sync after the initial OPFS->MEMFS restore

Follow-up work

  • Ensure multiple persistent Playground instances don't compete for OPFS storage – perhaps use a single SharedWorker to serve them? But that won't help with MEMFS. So maybe redirect to the scoped site or display an error message when another persistent tab is already active?
  • Detect corrupt state (e.g. OPFS sync stopped in the middle) and tell the user what happened. Automatically recover when possible.
  • Add a "reset persistent site" feature

cc @eliot-akira @dmsnell

adamziel added 2 commits June 12, 2023 18:21
This commit explores a custom OPFS filesystem backend for Playground to
avoid losing changes after a page refresh.

Status: Playground works in read-only mode. Writing and reading entire
files and directories works, but there's something off with seeking. For
example, inserting a post yields `General error: 10 disk I/O error.`

I could not reproduce it with a simple fseek() call from PHP,
unfortunately.
there is one last issue I may not be able to figure out before my
Sabbatical (June 26th - Sep 26th). This PR attempts another approach of
syncing MEMFS changes to OPFS and restoring them after a page refresh.

The main idea is:

1. Compare last modified time
2. Copy MEMFS files to OPFS if they were updated more recently

The current implementation is quite slow as everything happens
synchronously and frequently, but it can be significantly improved.
@adamziel adamziel marked this pull request as draft June 13, 2023 08:57
@adamziel adamziel force-pushed the memfs-to-opfs-sync branch from 0082512 to d4ce206 Compare June 13, 2023 14:13
@adamziel adamziel marked this pull request as ready for review June 13, 2023 21:09
@adamziel
Copy link
Collaborator Author

requestFileSystem support:

CleanShot 2023-06-13 at 23 54 27@2x

@adamziel adamziel changed the title Prototype: Sync between MEMFS and OPFS Persistent Playground: Sync between MEMFS and OPFS Jun 13, 2023
@adamziel adamziel merged commit 11e1fc8 into trunk Jun 13, 2023
@adamziel adamziel deleted the memfs-to-opfs-sync branch June 13, 2023 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant