Skip to content

Commit

Permalink
Prevent infinite loops when handling cache misses
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Oct 14, 2022
1 parent 7570219 commit e9cb816
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion exchanges/graphcache/src/cacheExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ export const cacheExchange = <C extends Partial<CacheExchangeOpts>>(
const requestedRefetch: Operations = new Set();
const deps: DependentOperations = new Map();

let reexecutingOperations: Operations = new Set();
let dependentOperations: Operations = new Set();

const isBlockedByOptimisticUpdate = (dependencies: Dependencies): boolean => {
for (const dep of dependencies.values())
if (blockedDependencies.has(dep)) return true;
Expand Down Expand Up @@ -84,6 +87,8 @@ export const cacheExchange = <C extends Partial<CacheExchangeOpts>>(
if (key !== operation.key) {
const op = operations.get(key);
if (op) {
// Collect all dependent operations if the reexecuting operation is a query
if (operation.kind === 'query') dependentOperations.add(key);
operations.delete(key);
let policy: RequestPolicy = 'cache-first';
if (requestedRefetch.has(key)) {
Expand All @@ -94,6 +99,12 @@ export const cacheExchange = <C extends Partial<CacheExchangeOpts>>(
}
}
}

// Upon completion, all dependent operations become reexecuting operations, preventing
// them from reexecuting prior operations again, causing infinite loops
const _reexecutingOperations = reexecutingOperations;
(reexecutingOperations = dependentOperations).add(operation.key);
(dependentOperations = _reexecutingOperations).clear();
};

// This registers queries with the data layer to ensure commutativity
Expand Down Expand Up @@ -278,7 +289,8 @@ export const cacheExchange = <C extends Partial<CacheExchangeOpts>>(
return (
res.outcome === 'miss' &&
res.operation.context.requestPolicy !== 'cache-only' &&
!isBlockedByOptimisticUpdate(res.dependencies)
!isBlockedByOptimisticUpdate(res.dependencies) &&
!reexecutingOperations.has(res.operation.key)
);
}),
map(res => {
Expand Down

0 comments on commit e9cb816

Please sign in to comment.