-
Notifications
You must be signed in to change notification settings - Fork 270
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
Synchronize two Playground instances #727
Conversation
fa31127
to
7b75f63
Compare
…n a stream of potentially conflicting changes into a conflict-free list
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.
incomplete review
...blueprints/src/lib/steps/apply-wordpress-patches/wp-content/mu-plugins/5-log-sql-queries.php
Outdated
Show resolved
Hide resolved
...blueprints/src/lib/steps/apply-wordpress-patches/wp-content/mu-plugins/5-log-sql-queries.php
Outdated
Show resolved
Hide resolved
...blueprints/src/lib/steps/apply-wordpress-patches/wp-content/mu-plugins/5-log-sql-queries.php
Outdated
Show resolved
Hide resolved
…rations in a mock tree Preserving RENAME operations this way is quite challenging
…remote peer. Also, transmit INSERT queries that generated a new autoincrement value as a key/value list to reconstruct on the remote peer.
1059219
to
c7d4577
Compare
…ovided by the fs-journal module
@dmsnell With base64 we wouldn't need the But there's a catch:
Are you familiar with any fast and synchronous ways of dealing with base64 in JS in the browser? Edit: I went with this one: ce943cd and then simplified it in 67cf982 |
there's a reason to leave the JSON encoding in there, and you found it. also I didn't know if you would be sending more than just strings, and this lets us send structured data across the boundary. text encoding is a big reason I lean on JSON in places though; it not only handles Unicode issues in a straightforward manner, but it can also escape special characters so they don't trip up naive parsers, e.g. "\u00a0" instead of a newline character (though with base64 this second need isn't important).
|
Oh I just meant they don't work with non-latin characters by default, but converting the string to Uint8Array and then calling |
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.
This is cool. There will be ample opportunity to iterate on the documentation and interfaces. Maybe we continue playing with it and revising before we publish it too broadly; wouldn't want to get stuck with the API if we're not confident on it.
@dmsnell I consider most Playground APIs as unstable but yeah, let's still not advertise this too much. Stable APIs or not, not breaking existing apps is just a nice thing to do. |
Description
Synchronizes two Playground instances. This is the technical foundation needed to fork entire sites, make changes, merge them back, rebase, undo etc. It's like git for WordPress.
CleanShot.2023-11-04.at.18.59.07.mp4
Wait, what? How does it work?
We journal local changes, send them to over a remote peer, and replay them there. The following changes are supported:
If that's so simple, why doesn't WordPress already support it?
This type of sync was never possible before.
The secret ingredient here is Playground. We can only keep track of all actions because we have a full control over the filesystem and the database.
What about conflicting autoincrement IDs?
We're sharding IDs to avoid conflicts. For example, peer 1 could start all autoincrement sequences at
12345000001
, while peer 2 could start at54321000001
. This gives both peers have a lot of space to create records without assigning the same IDs.In some ways, this is similar to ID sharding once described on Instagram's engineering blog.
What if we run out of space to assign new IDs?
Currently, that would create a conflict and cause the two peers to diverge forever.
In the future, we could rewrite these high IDs to reclaim the space. Here's how it could work:
1234500001
) and marks it as "dirty"35
) and establishes a mapping between1234500001
and35
1234500001
to35
in all SQL queries received from Alice35
1234500001
with35
like Bob did1234500001
as35
and Bob may stop rewriting itThe rewriting is needed because sometimes ids are stored inside serialized data such as JSON or PHP's
serialize()
output. It's an imperfect heuristics that would occasionally rewrite data that was the same as our ID but had a different meaning, but perhaps it wouldn't happen that often. That's the best we can do anyway. There's no way to reason about the meaning of arbitrary serialized data as it can come from any WordPress plugin.Time traveling
Wouldn't it be handy to undo a mistake that messed up your site? Well, now you can.
The journal is a recipe for getting from a vanilla WordPress to the site you have now. We can replay that recipe on a fresh Playground, stop half-way through, and recover the site you've had a few minutes ago. This opens the door to a WordPress-wide undo button.
It's quite similar to what Redux devtools provide.
The proof of concept can be accessed at http://localhost:5400/website-server/demos/time-traveling.html:
Testing instructions
nx dev
Follow up work
iframe.postMessage
.sqlite-database-integration
repo: Expose actions exposing executed SQL queries sqlite-database-integration#56normalizeFilesystemOperations()
to be able to transmit files that are created and instantly renamed (see the comment in fs.ts for more details)Tasks already done
atomic()
helper – is it a good idea to expose that kind of API?https://playground.wordpress.net/
@wp-playground/sync
, expose an interface to sync via an arbitrary backendpost_message_to_js
on replayed queries.cc @dmsnell