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

Handle open preference files #7775

Conversation

colin-grant-work
Copy link
Contributor

@colin-grant-work colin-grant-work commented May 7, 2020

Signed-off-by: Colin Grant [email protected]

What it does

This PR moves the preference UI in the direction of VSCode in two respects:

image

It improves the UI further by resetting the UI to the pre-change-attempt state if a preference change attempt fails.

How to test

  1. Open preference UI
  2. Open the file corresponding to the current scope ({} in upper right)
  3. In the UI, change preferences
  4. Observe that the file is modified and saved and the change registers in the UI (unless Preference change does not fire an onPreferencedChanged event #7685 - better not to rely on application.confirmExit as the sole test case)
  5. In the file editor, make a change to the file and don't save the change
  6. Return to the UI and attempt to change a preference.
  7. Observe that a toast appears warning that the change was not made.
  8. Make a change to another preference in the UI - the toast should remain.
  9. Exit the toast without action.
  10. Observe that all preference values reverts to their pre-change state in the UI.
  11. Repeat 7-9 selecting one of the toast buttons and observe that the behavior is correct in each case.

Review checklist

Reminder for reviewers

@colin-grant-work colin-grant-work marked this pull request as draft May 7, 2020 22:29
@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch 2 times, most recently from 3fd26f1 to 67455ff Compare May 8, 2020 00:25
@colin-grant-work colin-grant-work changed the title WIP: Save preference if underlying file not dirty Handle open preference files May 8, 2020
@colin-grant-work colin-grant-work marked this pull request as ready for review May 8, 2020 00:51
@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from 67455ff to 79c4ff2 Compare May 8, 2020 03:18
Copy link
Member

@vince-fugnitto vince-fugnitto left a comment

Choose a reason for hiding this comment

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

Functionally the changes work really well 👍
I verified the following:

  • making preference updates through the UI saves the document
  • making preference updates through the UI with a dirty document results in a prompt
  • the prompt option 'save and retry' successfully saves the document and reapplies the update
  • the prompt option 'open file' opens the document

I don't have any objections with the code, I'll however give others a chance to review as well

@vince-fugnitto vince-fugnitto added the preferences issues related to preferences label May 8, 2020
@akosyakov
Copy link
Member

We should test how it work without editors. When Theia/VS Code extensions do concurrent updates. It would be good to provide sample VS Code extension to verify it. It should not cause any notifications or unnecessary save cycles.

@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from 79c4ff2 to 363f176 Compare September 22, 2020 14:57
@colin-grant-work
Copy link
Contributor Author

@akosyakov, I have finally gotten around to writing tests for this PR, and in the process, I have changed the code quite a bit. Basically, I have implemented a queue mechanism for calls to the setPreference method. Previously, the behavior of the method was quite different depending on whether an editor was open or not:

  • With editor open: all calls handled (in non-deterministic order), none saved, no preference event fired.
  • Without editor: all calls handled in non-deterministic order, all saved individually, many preference events fired

With the queue mechanism I've implemented, the behavior is the same regardless of whether an editor is open or not (assuming the editor is not dirty):

  • All calls are queued
  • Processing the queue begins immediately, but if additional calls arrive before all edits are completed, those calls are added to the same transaction queue
  • When the queue is empty, a transaction is begun, and handling new calls is deferred until the editor has been saved and the preference changes have been processed - this is to distinguish between the editor being temporarily dirty because a save cycle hasn't completed and the editor being more persistently dirty because the user is working in it
  • When the transaction is complete, any calls made in the meantime are handled

This means that any number of concurrent calls result in only one save cycle, whether the editor is dirty or not.

If the editor is dirty:

  • Calls are queued as normal, but none are handled until the user chooses what to do.
  • If the user chooses not to retry, all pending calls are rejected and resolve to false.

We should test how it work without editors. When Theia/VS Code extensions do concurrent updates. It would be good to provide sample VS Code extension to verify it. It should not cause any notifications or unnecessary save cycles.

I have added tests to the saveable.spec.js file in the examples/api-tests folder, but I haven't created a sample VSCode extension to test its behavior. The tests are a bit brutely forced, but they work for demonstration. Please let me know what you think of the queue idea, and any suggestions you have to improve the implementation or the tests.

@colin-grant-work
Copy link
Contributor Author

colin-grant-work commented Feb 8, 2021

@vince-fugnitto, I've rebased this PR and run tests locally (and now they've finished in CI - not sure why Ubuntu + Python 2 doesn't like me). It comes in two forms:

  • Originally, it was fairly basic and just checked if the editor was open and dirty, and if so, warned the user, if not, it saved the file. The commit is likely gone from the reflog, but wouldn't be hard to reimplement.
  • After Anton mentioned concerns about saving and requested tests, I implemented the more complex system I describe here and added tests to show that it was behaving as intended. I think that system is a pretty good way to handle challenging (and mostly hypothetical?) cases where the system is hit with many edits in a short period, but it's also a much larger change to the existing code.

The fact of the matter is that the current code generates tons of save cycles if the file is not open, so it doesn't make very much sense to me to quibble about doing the same when the file is open. But, if it's desirable to reduce the number of saves when the system is under pressure, what I've implemented is a move in that direction, and I'm happy to work on improving it if anyone has suggestions on how it can be made better.

Copy link
Member

@vince-fugnitto vince-fugnitto left a comment

Choose a reason for hiding this comment

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

@colin-grant-work do you mind rebasing the pull-request (there were recent significant changes to the preferences). I can review afterwards 👍

Copy link
Member

@vince-fugnitto vince-fugnitto left a comment

Choose a reason for hiding this comment

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

@colin-grant-work I don't have any objections to the approach taken by the pull-request, if you are to rebase it should fix the failing api-tests 👍

I've asked that @marechal-p also take a look, namely how we handle queued preference changes.

@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from 9217fcc to aae4e0c Compare March 1, 2021 16:02
@kittaakos kittaakos removed their request for review July 18, 2021 12:20
@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from aae4e0c to f36030c Compare November 20, 2021 02:10
@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from f36030c to 99db729 Compare November 20, 2021 02:17
@colin-grant-work
Copy link
Contributor Author

@vince-fugnitto, @paul-marechal, with the addition of async-mutex to our toolkit, this PR got a fair bit simpler. I've updated the code and significantly reduced the number of things affected. If you guys wouldn't mind running it through a few paces again, I'd appreciate it.

@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch 2 times, most recently from 07e5a39 to 790bb87 Compare November 24, 2021 19:34
@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch 4 times, most recently from 545ef97 to 2dc7add Compare November 24, 2021 21:09
@msujew msujew self-requested a review November 25, 2021 10:55
Copy link
Member

@msujew msujew left a comment

Choose a reason for hiding this comment

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

I was able to disconnect the UI from the settings editor. Afterwards, any changes made to the UI or the settings file are not reflected in the other one:

  1. Update a preference in the UI.
  2. Open the settings.json file.
  3. Change the preference file, but don't save it.
  4. Change the value again in the UI, and click on the "Open file" action in the resulting notification (at this point the UI and file editor are disconnected)
  5. Change the value in the settings json, save it
  6. The change is not reflected in the UI

The "save and retry" and cancel actions work perfectly fine though.

@colin-grant-work
Copy link
Contributor Author

I was able to disconnect the UI from the settings editor. Afterwards, any changes made to the UI or the settings file are not reflected in the other one:

  1. Update a preference in the UI.
  2. Open the settings.json file.
  3. Change the preference file, but don't save it.
  4. Change the value again in the UI, and click on the "Open file" action in the resulting notification (at this point the UI and file editor are disconnected)
  5. Change the value in the settings json, save it
  6. The change is not reflected in the UI

The "save and retry" and cancel actions work perfectly fine though.

@msujew, thanks for the test. Older versions of this PR - before async-mutex - had code to revert the UI if the user canceled the action, but I forgot about it when redoing the implementation - I'll bring that back.

@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch 2 times, most recently from 425b1e8 to 3acdbba Compare December 1, 2021 00:05
@colin-grant-work
Copy link
Contributor Author

@msujew, I've brought back / reimplemented the UI reversion behavior, and added another step to the testing to confirm that even multiple changes to the UI while the toast is up will all be reverted.

@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from 3acdbba to e8b6123 Compare December 2, 2021 15:41
Copy link
Member

@vince-fugnitto vince-fugnitto left a comment

Choose a reason for hiding this comment

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

I confirmed that the following work well:

  • #7721 is fixed
  • #9115 is fixed
  • #2547 is fixed
  • confirmed that setting preferences with existing errors in the settings.json works
  • confirmed that settings preferences with a dirty settings.json will prompt users to cancel, open the file, or save and retry - all actions work well
  • confirmed that saving a dirty settings.json file will update the UI properly
  • confirmed the behavior on all available scopes - user, workspace, folder (multi-root)

Copy link
Member

@msujew msujew left a comment

Choose a reason for hiding this comment

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

The changes look good to me as well 👍

  • Changes to preferences in the UI or the respective settings.json file are updated immediately in the other
  • The actions when the settings file contains unsaved changes all work as expected
  • Works correctly for all preference scopes

@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch 2 times, most recently from 1f7c7e1 to fc83147 Compare December 3, 2021 19:16
@colin-grant-work colin-grant-work force-pushed the feature/save-when-prefs-open branch from fc83147 to 713e44e Compare December 3, 2021 19:55
@colin-grant-work colin-grant-work merged commit c8248f7 into eclipse-theia:master Dec 3, 2021
@colin-grant-work colin-grant-work deleted the feature/save-when-prefs-open branch December 3, 2021 20:36
@vince-fugnitto vince-fugnitto added this to the 1.21.0 milestone Dec 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
preferences issues related to preferences
Projects
None yet
4 participants