-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Real-time collaboration: Enable CRDT doc state map changes #72763
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
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +97 B (0%) Total Size: 2.19 MB
ℹ️ View Unchanged
|
packages/core-data/src/entities.js
Outdated
| }; | ||
|
|
||
| // Mark the doc as having been persisted. | ||
| getSyncManager()?.markPersisted( |
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.
It has not yet been persisted at this point, so this creates a race condition if peers use it as a signal to refetch the entity
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.
Do we want that ability in place? I took away the refetch the entity comment for that reason and made it seem instead its for notifications.
I had tried to put it under actions like it used to be, but that didn't consistently get triggered which was odd.
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.
The other option that I had in mind actually was the action - editor.savePost. That's fired right after the post update finishes.
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.
I took away the refetch the entity comment for that reason
It served an important purpose in syncing the state of the Save / Publish button, so that peers can update their entity record in their local store and correctly compute "dirty" state.
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.
But then the question is, where would that be called? In the VIP-RTC plugin maybe? So once could decide if they truly want this feature or not and how they use it?
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.
It would be called in the sync manager. You can see how it previously worked here:
Right now in our plugin branch, we've regressed to a non-synced Save / Publish button state. Refetching is how we solved that.
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.
Apologies, I meant to say that do we want that ability in this place not at all.
I definitely know why we had that in place, as we went through several PRs to figure out the right solution for it. My thought was that, we'd use this state key way just for notifications so if it is a touch fragile it won't be a big deal. But, for getting the publish/save state synced we'd need to make sure that's perfect.
I have an alternative area that I'm experimenting with, which is the editor.savePost action.
Would perhaps re-naming these two keys to something else help? Or do you think it's better to just do it all in one way similar to how we did it before?
I'm approaching separately, so notifications and features like re-fetching are done separately.
| stateMap.set( PERSISTED_AT_KEY, lastPersistedAt ); | ||
| stateMap.set( PERSISTED_BY_KEY, ydoc.clientID ); |
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.
I've been wondering if this is really the best approach. It's not really document state and it feels fragile.
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.
The problem I guess is that, we need to be able to tell the other clients that the document has been updated and by whom without spamming notifications.
If we hook into each change, we'd be spamming notifications. If we hook into when the post is saved, then those changes are batched at least.
That's why I stuck with this approach.
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.
I realized why I like this approach. It's like our very own redux action that we can fire that plugins can hook into to react the way they want.
| handlers.saveRecord(); | ||
| } | ||
|
|
||
| addAction( |
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.
@chriszarate - lemme know what you think about this new way to track a post being saved. This action is fired async at the very end of a post save, so we know it's been persisted.
Now, it's possible to actually use this key to track if a refetch needs to happen or stick to just notifications.
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.
I kept this here as it felt like the right place, since it's where the ydoc is bootstrapped. We aren't changing anything about the post just tracking it really.
| 'sync.markCRDTDocPersisted', | ||
| async ( post, options ) => { | ||
| // Skip if the post's id doesn't match (including different ID types), or if it's an autosave. | ||
| if ( post.id !== objectId || options.isAutosave ) { |
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.
I skipped auto saves at the moment, to keep it similar to Gutenberg where a notice would be sent if you hit the save yourself.
The post ID check is for safety, and would account for even the ID format not being supported.
Is it worth adding an extra post type check too?
|
Closing this PR in favour of #72851. |
What?
We disabled the ability to observe keys on the state map of a CRDT doc, that could then power notifications within the block editor. This change re-enables that, albeit with a simpler system as it only targets a post being updated rather than also being restored.
Why?
It's important to provide awareness into when a post is updated, across all clients rather than just the one making the changes.
How?
The state map on a CRDT doc will now have two properties:
Together this would allow things like sending a notification to all clients when a post is updated.
Testing Instructions
Screenshots or screencast