Skip to content

Commit 933b280

Browse files
tyao1facebook-github-bot
authored andcommittedAug 27, 2020
Unsubscribe network requests when releasing temporary retains
Reviewed By: jstejada Differential Revision: D23277912 fbshipit-source-id: 4924acbb049ff6579448fa6322af49c0fa5cfe41
1 parent 41de808 commit 933b280

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed
 

‎packages/relay-experimental/QueryResource.js

+6
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ function createCacheEntry(
182182
releaseQueryTimeout = null;
183183
releaseTemporaryRetain = null;
184184
disposable.dispose();
185+
// Normally if this entry never commits, the request would've ended by the
186+
// time this timeout expires and the temporary retain is released. However,
187+
// we need to do this for live queries which remain open indefinitely.
188+
if (retainCount <= 0 && currentNetworkSubscription != null) {
189+
currentNetworkSubscription.unsubscribe();
190+
}
185191
};
186192
releaseQueryTimeout = setTimeout(
187193
localReleaseTemporaryRetain,

‎packages/relay-experimental/__tests__/useLazyLoadQueryNode-test.js

+37-6
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,9 @@ describe('useLazyLoadQueryNode', () => {
442442
expect(release).toBeCalledTimes(2);
443443

444444
// Assert request in flight is cancelled
445-
expect(environment.mock.isLoading(query.request.node, variables)).toEqual(
446-
false,
447-
);
445+
expect(
446+
environment.mock.isLoading(query.request.node, variables, {force: true}),
447+
).toEqual(false);
448448
});
449449

450450
it('disposes ongoing network request when component unmounts after committing', () => {
@@ -477,9 +477,40 @@ describe('useLazyLoadQueryNode', () => {
477477
// Assert data is released
478478
expect(release).toBeCalledTimes(1);
479479
// Assert request in flight is cancelled
480-
expect(environment.mock.isLoading(query.request.node, variables)).toEqual(
481-
false,
482-
);
480+
expect(
481+
environment.mock.isLoading(query.request.node, variables, {force: true}),
482+
).toEqual(false);
483+
});
484+
485+
it('cancels network request when temporarily retained component that never commits is disposed of after timeout', () => {
486+
const instance = render(environment, <Container variables={variables} />);
487+
488+
expect(instance.toJSON()).toEqual('Fallback');
489+
expectToHaveFetched(environment, query);
490+
expect(renderFn).not.toBeCalled();
491+
expect(environment.retain).toHaveBeenCalledTimes(1);
492+
ReactTestRenderer.act(() => {
493+
instance.unmount();
494+
});
495+
// Resolve a payload but don't complete the network request
496+
environment.mock.nextValue(gqlQuery, {
497+
data: {
498+
node: {
499+
__typename: 'User',
500+
id: variables.id,
501+
name: 'Alice',
502+
},
503+
},
504+
});
505+
506+
// Trigger releasing of the temporary retain
507+
jest.runAllTimers();
508+
// Assert data is released
509+
expect(release).toBeCalledTimes(1);
510+
// Assert request in flight is cancelled
511+
expect(
512+
environment.mock.isLoading(query.request.node, variables, {force: true}),
513+
).toEqual(false);
483514
});
484515

485516
describe('partial rendering', () => {

‎packages/relay-experimental/__tests__/useRefetchableFragmentNode-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3023,7 +3023,7 @@ describe('useRefetchableFragmentNode', () => {
30233023
});
30243024

30253025
// Assert request was canceled
3026-
expect(unsubscribe).toBeCalledTimes(1);
3026+
expect(unsubscribe).toBeCalledTimes(2);
30273027
expectRequestIsInFlight({
30283028
inFlight: false,
30293029
requestCount: 1,

0 commit comments

Comments
 (0)
Please sign in to comment.