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

[stable27] fix(files): race condition on web files view change #41206

Merged
merged 3 commits into from Oct 31, 2023

Conversation

ShGKme
Copy link
Contributor

@ShGKme ShGKme commented Oct 31, 2023

Summary

A small regression from #35772

This issue does not exist on Nextcloud 28 due to full files to view migration.

How to reproduce

  1. Share "Folder A" with some "User"
  2. Log in as "User"
  3. Open Files
  4. Open "Shared with you"
  5. Click on "Folder A"
  • Expected behavior:
    • it opens the sahred folder
    • only "/FolderA" files are requested in "Network"
  • Actual behavior:
    • root files are shown for a second or as the result
    • "/" and "/FolderA" twice are requested

Try several times to reproduce. Then more files in root then more chances to reproduce.

bug.mp4

Root of the issue

There is a race condition.

Opening a shared folder makes 2 actions:

fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename, context) {
OCA.Files.App.setActiveView('files', { silent: true })
OCA.Files.App.fileList.changeDirectory(OC.joinPaths(context.$file.attr('data-path'), filename), true, true)
})

Changing view from "sharingin" to "files" emits files:legacy-navigation:changed

server/apps/files/js/app.js

Lines 223 to 226 in 6bfbb47

setActiveView: function(viewId) {
// The Navigation API will handle the final event
window._nc_event_bus.emit('files:legacy-navigation:changed', { id: viewId })
},

Then the Files view is open on root path / which causes fetching the root files list.

onLegacyNavigationChanged({ id } = { id: 'files' }) {
const view = this.Navigation.views.find(view => view.id === id)
if (view && view.legacy && view.id !== this.currentView.id) {
// Force update the current route as the request comes
// from the legacy files app router
this.$router.replace({ ...this.$route, params: { view: view.id } })
this.Navigation.setActive(view)
this.showView(view)
}
},

See this.show:

const { dir = '/' } = OC.Util.History.parseUrlQuery()
const params = { itemId: view.id, dir }
logger.debug('Triggering legacy navigation event', params)
window.jQuery(newAppContent).trigger(new window.jQuery.Event('show', params))
window.jQuery(newAppContent).trigger(new window.jQuery.Event('urlChanged', params))

And the handler:

_onUrlChanged: function(e) {
if (e && _.isString(e.dir)) {
var currentDir = this.getCurrentDirectory();
// this._currentDirectory is NULL when fileList is first initialised
if(this._currentDirectory && currentDir === e.dir) {
return;
}
this.changeDirectory(e.dir, true, true, undefined, true);
}
},

Here is were the first request is made.

Then the initial changeDirectory is called. Which also results in changing directory (to the correct one) and fetching the actual shared directory files list.

🏎️ Here is a race. When the root directory is large, its response may come later so root files are shown instead of the shared folder.


Changing view also triggers a shown event that sets the current directory to / and reloads content. It causes duplicated file requests.

_onShow: function(e) {
OCA.Files.App && OCA.Files.App.updateCurrentFileList(this);
if (e.itemId === this.id) {
this._setCurrentDir('/', false);
}
// Only reload if we don't navigate to a different directory
if (typeof e.dir === 'undefined' || e.dir === this.getCurrentDirectory()) {
this.reload();
}
},

Before Vue migration, there was a check for this.shown that avoided this behavior.

_onShow: function(e) {
OCA.Files.App && OCA.Files.App.updateCurrentFileList(this);
if (this.shown) {
if (e.itemId === this.id) {
this._setCurrentDir('/', false);
}
// Only reload if we don't navigate to a different directory
if (typeof e.dir === 'undefined' || e.dir === this.getCurrentDirectory()) {
this.reload();
}
}
this.shown = true;
},

If I'm not wrong, with migrating navigation to Vue, we can just remove this part. cc @skjnldsv

TODO

  • Add silent mode support for legacy navigation changed. Actually, the same that was there before migration to Vue.
  • Remove resetting and reloading on view show

Checklist

@ShGKme ShGKme added this to the Nextcloud 27.1.4 milestone Oct 31, 2023
@ShGKme ShGKme self-assigned this Oct 31, 2023
@ShGKme ShGKme linked an issue Oct 31, 2023 that may be closed by this pull request
8 tasks
@ShGKme
Copy link
Contributor Author

ShGKme commented Oct 31, 2023

/backport to stable26

@ShGKme ShGKme added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Oct 31, 2023
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
It is handled by new navigation with Vue

Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
@ShGKme ShGKme force-pushed the fix/39565/race-condition-on-web-files-view branch from 01b4b30 to d439417 Compare October 31, 2023 00:17
Copy link
Member

@skjnldsv skjnldsv left a comment

Choose a reason for hiding this comment

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

Make sense! Nice catch, this legacy router is a pain 🥖

@ShGKme ShGKme added 3. to review Waiting for reviews 2. developing Work in progress and removed 2. developing Work in progress 3. to review Waiting for reviews labels Oct 31, 2023
@ShGKme
Copy link
Contributor Author

ShGKme commented Oct 31, 2023

Want to check one more case with page reload when switching from the shared folder to "All files".

@ShGKme
Copy link
Contributor Author

ShGKme commented Oct 31, 2023

@skjnldsv Do know any edge cases with legacy navigation/apps here that should be tested?

@ShGKme
Copy link
Contributor Author

ShGKme commented Oct 31, 2023

Want to check one more case with page reload when switching from the shared folder to "All files".

Unrelated to this issue.

OC.Util.History stores query param as a string in a native history.state. vue-router stores its own state there and crashes found a string there.

@ShGKme ShGKme added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Oct 31, 2023
@ShGKme ShGKme merged commit e9189e0 into stable27 Oct 31, 2023
38 checks passed
@ShGKme ShGKme deleted the fix/39565/race-condition-on-web-files-view branch October 31, 2023 13:59
@ShGKme
Copy link
Contributor Author

ShGKme commented Oct 31, 2023

/backport to stable26

@ShGKme ShGKme changed the title fix(files): race condition on web files view change [stable27] fix(files): race condition on web files view change Oct 31, 2023
@blizzz blizzz mentioned this pull request Nov 13, 2023
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.

[Bug]: open shared folder doesn't work
3 participants