Page MenuHomePhabricator

Make it possible to wait for the initial call to /api/user/ from any vue component or view
Closed, ResolvedPublic

Description

One of the edge cases that developers uncover quite a bit when testing a particular Vue screen is a race condition between the initial call to our GET /api/user/ endpoint made in App.vue's created lifecycle hook returning and other attempts to use state gathered from the endpoint in their own calls to other endpoints.

The race shows up most boldly in the case of API endpoints like GET /api/crawler/urls/self/ where we want to assert that the user is authenticated. We are currently using guard conditions which check the value of context.state.user.is_authenticated, but that check is not aware of if that state is the default value or the result of the most recent call to GET /api/user/. It is also not able to await an in process call which may have already been sent to the backend but not yet processed as a response.

The blog post at https://tkacz.pro/use-vuex-to-avoid-multiple-requests-from-different-components/ describes one possible solution for this race condition. The technique described in the blog post is to store the promise for the API call and its subsequent processing in the vuex store itself. Any code with access to the vuex store could then itself block on that promise for all operations that depend on it's settled state.

With the pattern of storing the promise in vuex and returning that promise from user/getUserInfo as an early exit condition when non-null in the vuex store, any view or component needing to ensure that the user's authentication state is correct could chain its code to the resolution of the promise in the exact same manner as App.vue's created hook.

Event Timeline

This is an interesting approach! I will work on this today, then work on getting it merged before continuing with the Open review

Change 741746 had a related patch set uploaded (by Raymond Ndibe; author: Raymond Ndibe):

[wikimedia/toolhub@main] dev: Make it possible to wait for the initial call to /api/user/ from any vue component or view

https://gerrit.wikimedia.org/r/741746

Change 741746 merged by jenkins-bot:

[wikimedia/toolhub@main] ui: Expose GET /api/user/ promise via vuex

https://gerrit.wikimedia.org/r/741746

bd808 moved this task from In Progress to Review on the Toolhub board.

Change 749220 had a related patch set uploaded (by BryanDavis; author: Bryan Davis):

[operations/deployment-charts@master] toolhub: Bump container version to 2021-12-20-122341-production

https://gerrit.wikimedia.org/r/749220

Change 749220 merged by jenkins-bot:

[operations/deployment-charts@master] toolhub: Bump container version to 2021-12-23-121200-production

https://gerrit.wikimedia.org/r/749220