Skip to content

Commit

Permalink
fix(graphcache): Fix deadlocked layers between deferred and optimisti…
Browse files Browse the repository at this point in the history
…c layers
  • Loading branch information
kitten committed Dec 6, 2022
1 parent b80fc55 commit 323b803
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-items-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@urql/exchange-graphcache': patch
---

Fix a deadlock condition in Graphcache's layers, which is caused by subscriptions (or other deferred layers) starting before one-off mutation layers. This causes the mutation to not be completed, which keeps its data preferred above the deferred layer. That in turn means that layers stop squashing, which causes new results to be missing indefinitely, when they overlap.
19 changes: 7 additions & 12 deletions exchanges/graphcache/src/store/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,9 @@ export const clearDataState = () => {
while (
--i >= 0 &&
data.refLock.has(data.optimisticOrder[i]) &&
data.commutativeKeys.has(data.optimisticOrder[i]) &&
!data.deferredKeys.has(data.optimisticOrder[i])
) {
data.commutativeKeys.has(data.optimisticOrder[i])
)
squashLayer(data.optimisticOrder[i]);
}
}

currentOwnership = null;
Expand Down Expand Up @@ -535,20 +533,17 @@ export const reserveLayer = (

let index = data.optimisticOrder.indexOf(layerKey);
if (index > -1) {
if (!data.commutativeKeys.has(layerKey) && !hasNext) {
data.optimisticOrder.splice(index, 1);
// Protect optimistic layers from being turned into non-optimistic layers
// while preserving optimistic data
data.optimisticOrder.splice(index, 1);
// Protect optimistic layers from being turned into non-optimistic layers
// while preserving optimistic data
if (!data.commutativeKeys.has(layerKey) && !hasNext)
clearLayer(data, layerKey);
} else {
return;
}
}

// If the layer has future results then we'll move it past any layer that's
// still empty, so currently pending operations will take precedence over it
for (
index = 0;
index = index > -1 ? index : 0;
hasNext &&
index < data.optimisticOrder.length &&
!data.deferredKeys.has(data.optimisticOrder[index]) &&
Expand Down

0 comments on commit 323b803

Please sign in to comment.