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

Autosave: fix conflict between remote and local autosaves #17501

Merged
merged 10 commits into from
Sep 30, 2019

Conversation

mcsf
Copy link
Contributor

@mcsf mcsf commented Sep 20, 2019

Fixes #17500

Description

For now, this only includes failing E2E tests

How has this been tested?

Screenshots

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.

@mcsf mcsf added [Feature] Saving Related to saving functionality [Feature] Offline Related to offline editing labels Sep 20, 2019
@gziolo
Copy link
Member

gziolo commented Sep 23, 2019

I can see it failing as expected but only on one of the nodes, it should fail for both suites of e2e tests (https://github.com/WordPress/gutenberg/pull/17501/checks?check_run_id=230152153):

Screen Shot 2019-09-23 at 09 30 57

@mcsf mcsf force-pushed the fix/autosave-conflict-remote-local branch from b3fd6c0 to 9e334a4 Compare September 25, 2019 10:22
@mcsf
Copy link
Contributor Author

mcsf commented Sep 25, 2019

I can see it failing as expected but only on one of the nodes, it should fail for both suites of e2e tests (https://github.com/WordPress/gutenberg/pull/17501/checks?check_run_id=230152153):

Thanks for spotting. As of 208dbbb, this should be more reliable and only failing as intended.

@gziolo
Copy link
Member

gziolo commented Sep 26, 2019

I don't see any changes in the logic. Should those e2e tests pass? :)

@mcsf
Copy link
Contributor Author

mcsf commented Sep 26, 2019

I don't see any changes in the logic. Should those e2e tests pass? :)

No :(

function postKey( postId ) {
return `wp-autosave-block-editor-post-${ postId }`;
}

/**
* Custom hook which returns a callback function to be invoked when a local
* autosave should occur.
*
* @return {Function} Callback function.
*/
function useAutosaveCallback() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactoring is great, it also makes me think this particular hook is not necessarily needed anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, though we would still need to use requestIdleCallback somewhere. And wouldn't it be strange to have it in the action creator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or do you just mean inline the hook in the LocalAutosaveMonitor component?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I meant inline, but I don't feel strongly tbh

if ( ! hasDifference ) {
// If there is no difference, it can be safely ejected from storage.
window.sessionStorage.removeItem( postKey( postId ) );
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? a way to create a scope?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was for scope, and to share the WIP quickly

@@ -140,7 +143,7 @@ function useAutosaveNotice() {
},
],
} );
}, [ postId ] );
}, [ postId, remoteAutosave ] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means, the function is reexecuted each time removeAutosave changes which can happen on each autosave I guess and not only initial rendering, is this expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, indeed, not expected. I think I left this here in my frustration with the E2E tests, when for some reason [ postId, hasFetchedAutosave ] didn't work. I can circle back.


export function localAutosaveClear( postId ) {
window.sessionStorage.removeItem( postKey( postId ) );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reasoning for keeping these utils here and using a control. I do wonder if we should just use these functions directly from like a autosave-utils or something like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went for controls to see how it would feel to be able to dispatch saving actions just like with regular autosave.

autosave-utils

These would have to be available in E2E tests, so presumably they would be globally available. Is it worth adding a new module just for this?

I guess controls are flexible for both good and bad. What's your preference here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since it has no relation with state, I'd personally prefer just a utility file somewhere

window.sessionStorage.removeItem( postKey( postId ) );
if (
( lastIsDirty.current && ! isDirty ) ||
( lastIsAutosaving.current && ! isAutosaving && ! didError )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be the opposite (when the autosaves finishes instead of when the autosaves starts)?

Also, what's the reasoning for clearing when the post becomes dirty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(when the autosaves finishes instead of when the autosaves starts)

Isn't that the case already? I guess useRef's notation with .current is confusing to read.

Also, what's the reasoning for clearing when the post becomes dirty?

Likewise, it clears when the post is flushed.

Also bump sleep time by 1s to allow time for local autosave.
toggleOfflineMode is a wrapper for Puppeteer's page.setOfflineMode which
keeps track of the tester's intention to bring the network down. This
allows the E2E framework to ignore logged network errors when these
errors are expected.
* Switch to new sessionStorage handlers for local autosaves
* Purge local autosave if remote autosave is successful
* Add e2e test simulating unavailable network
* Defer to server autosave if any available
* WIP commit. Clearly.
* hasFetchedAutosave should wait for user resolution

* useAutosavePurge: only rely autosaving conclusion and lack of errors,
  don't look at isDirty anymore

* Restore autosave() call in e2e test

* Inline and remove useAutosaveCallback
@mcsf mcsf force-pushed the fix/autosave-conflict-remote-local branch from 040d0cb to 072a828 Compare September 30, 2019 18:02
@youknowriad youknowriad merged commit 3e43bcc into master Sep 30, 2019
@youknowriad youknowriad deleted the fix/autosave-conflict-remote-local branch September 30, 2019 18:41
mcsf added a commit that referenced this pull request Oct 1, 2019
* Until now, although we were requesting the entire autosave entity
inside `LocalAutosaveMonitor`'s `useAutosaveNotice`, we only care about
the existence or absence of an autosave for the current post.

* `useAutosaveNotice` was requesting the entire entity because there
were plans in #17501 to compare local and remote autosave objects, a
requirement which was later dropped.

* In contrast, the editor setting `autosave` is immediately available
upon editor initialisation.

* Later on, _if_ we choose to reconcile remote and local autosaves with
more sophistication, this could possibly be done based on recency of
autosave -- in which case we could might still get away with editor
settings if the server provides this information inside the `autosave`
object.

* This change should hopefully provide a more reliable page-loading
experience for autosave's E2E tests.
mcsf added a commit that referenced this pull request Oct 2, 2019
* Until now, although we were requesting the entire autosave entity
inside `LocalAutosaveMonitor`'s `useAutosaveNotice`, we only care about
the existence or absence of an autosave for the current post.

* `useAutosaveNotice` was requesting the entire entity because there
were plans in #17501 to compare local and remote autosave objects, a
requirement which was later dropped.

* In contrast, the editor setting `autosave` is immediately available
upon editor initialisation.

* Later on, _if_ we choose to reconcile remote and local autosaves with
more sophistication, this could possibly be done based on recency of
autosave -- in which case we could might still get away with editor
settings if the server provides this information inside the `autosave`
object.

* This change should hopefully provide a more reliable page-loading
experience for autosave's E2E tests.
gziolo pushed a commit that referenced this pull request Oct 3, 2019
…and bailing on save failure (#17679)

* Tests: Autosave: Allow extra reloading time for autosave notices

* LocalAutosaveMonitor: Use immediately available autosave data

* Until now, although we were requesting the entire autosave entity
inside `LocalAutosaveMonitor`'s `useAutosaveNotice`, we only care about
the existence or absence of an autosave for the current post.

* `useAutosaveNotice` was requesting the entire entity because there
were plans in #17501 to compare local and remote autosave objects, a
requirement which was later dropped.

* In contrast, the editor setting `autosave` is immediately available
upon editor initialisation.

* Later on, _if_ we choose to reconcile remote and local autosaves with
more sophistication, this could possibly be done based on recency of
autosave -- in which case we could might still get away with editor
settings if the server provides this information inside the `autosave`
object.

* This change should hopefully provide a more reliable page-loading
experience for autosave's E2E tests.

* Tests: Keep retrying autosave

* Tests: Autosave: Skip conflict-resolution test if unavailable remote autosave
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Offline Related to offline editing [Feature] Saving Related to saving functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Local autosave can conflict with remote autosave
3 participants