From 21ed77345fab1eebbc645dc0c0f765494c4604e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Phil=20Pl=C3=BCckthun?= Date: Sat, 11 Jan 2020 02:57:16 +0000 Subject: [PATCH] Fix cascading cancellations from components (#503) * Fix cascading cancellations from components wonka@^4.0.0 has some improved behaviour that fixed some edge cases and bugs. As it turned out urql was relying on one of them. The switchMap in the hooks would cancel the last query and start the next. However, this cancellation cascades not only up to executeQuery to end and teardown the operation, it also flows up through the exchange pipeline, ending the entire thing like an electrical surge. This can be prevented by publishing the results chain and making sure it can never be interrupted. * Fix pollInterval test * Add scheduler dependency to silence peer dependency warning --- package.json | 2 +- src/client.test.ts | 6 ++++-- src/client.ts | 5 +++++ yarn.lock | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f800e6437b..3339e9c02d 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,6 @@ "rollup-plugin-replace": "^2.2.0", "rollup-plugin-terser": "^5.1.3", "rollup-plugin-typescript2": "^0.25.3", - "scheduler": "^0.18.0", "terser": "^4.6.2", "ts-jest": "^24.3.0", "typescript": "^3.7.4" @@ -137,6 +136,7 @@ "react": ">= 16.8.0" }, "dependencies": { + "scheduler": ">= 0.16.0", "react-wonka": "^2.0.0", "wonka": "^4.0.5" } diff --git a/src/client.test.ts b/src/client.test.ts index c5851ccfa8..959e133701 100755 --- a/src/client.test.ts +++ b/src/client.test.ts @@ -195,10 +195,12 @@ describe('executeQuery', () => { expect(receivedOps.length).toEqual(1); jest.advanceTimersByTime(200); - expect(receivedOps.length).toEqual(3); + expect(receivedOps.length).toEqual(5); expect(receivedOps[0].operationName).toEqual('query'); - expect(receivedOps[1].operationName).toEqual('query'); + expect(receivedOps[1].operationName).toEqual('teardown'); expect(receivedOps[2].operationName).toEqual('query'); + expect(receivedOps[3].operationName).toEqual('teardown'); + expect(receivedOps[4].operationName).toEqual('query'); unsubscribe(); }); }); diff --git a/src/client.ts b/src/client.ts index 93ee7ff8b9..d819bec9ad 100755 --- a/src/client.ts +++ b/src/client.ts @@ -28,6 +28,7 @@ import { interval, fromValue, switchMap, + publish, } from 'wonka'; import { @@ -135,6 +136,10 @@ export class Client { forward: fallbackExchangeIO, })(this.operations$) ); + + // Prevent the `results$` exchange pipeline from being closed by active + // cancellations cascading up from components + pipe(this.results$, publish); } private createOperationContext = ( diff --git a/yarn.lock b/yarn.lock index 4a13ad75d9..1ac1bde9eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5137,7 +5137,7 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.18.0: +"scheduler@>= 0.16.0", scheduler@^0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==