Skip to content

Commit

Permalink
user preferences: cancel preceding PATCH requests for the same prefer…
Browse files Browse the repository at this point in the history
…ence key
  • Loading branch information
brontolosone committed Sep 6, 2024
1 parent 74a963b commit 6d7d8ca
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/request-data/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,44 @@ export default ({ i18n }, createResource) => {

createResource('userPreferences', (self) => ({
_container,
abortControllers: {},
instanceID: crypto.randomUUID(),
transformResponse: ({ data }) => shallowReactive(data),
patchServerside: (k, v) => {
// As we need to be able to have multiple requests in-flight, we can't use resource.request() here.
// However, we want to avoid stacking requests for the same key, so we abort preceding requests for the same key, if any.
// Note that because locks are origin-scoped, we use a store instantiation identifier to scope them to this app instance.
const keyLockName = `userPreferences-${self.instanceID}-keystack-${k}`;
navigator.locks.request(
`userPreferences-${self.instanceID}-lockops`,
() => {
navigator.locks.request(
keyLockName,
{ ifAvailable: true },
(lockForKey) => {
const aborter = new AbortController();
if (!lockForKey) {
// Cancel the preceding request, a new one supercedes it.
self.abortControllers[k].abort();
return navigator.locks.request(
keyLockName,
() => {
// eslint-disable-next-line no-param-reassign
self.abortControllers[k] = aborter;
return self.requestPatchServerside(k, v, aborter);
}
);
}
// eslint-disable-next-line no-param-reassign
self.abortControllers[k] = aborter;
return self.requestPatchServerside(k, v, aborter);
},
);
return Promise.resolve(); // return asap with a resolved promise so the outer lockops lock gets released; we don't wan't to wait here for the inner keylock-enveloped requests.
}
);
},
requestPatchServerside: (k, v, aborter) => {
const { requestData, http } = self[self._container];
return http.request(
withAuth(
Expand All @@ -95,6 +130,7 @@ export default ({ i18n }, createResource) => {
'X-Extended-Metadata': 'true',
},
data: Object.fromEntries(new Map([[k, v]])),
signal: aborter.signal,
},
requestData.session.token
)
Expand Down

0 comments on commit 6d7d8ca

Please sign in to comment.