From fe03006d9c84b8afcd679de88cceab88ba13d283 Mon Sep 17 00:00:00 2001 From: Kamil Dybicz Date: Thu, 30 Jun 2022 15:40:22 +0200 Subject: [PATCH 1/6] fixing issues with global caching --- .vscode/launch.json | 20 ++++++ .vscode/settings.json | 4 ++ src/http-data-source.ts | 2 +- test/http-data-source.test.ts | 111 ++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..fd583ba --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/node_modules/.bin/ava", + "--runInBand" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1ba845a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.tabSize": 2, + "editor.detectIndentation": true +} diff --git a/src/http-data-source.ts b/src/http-data-source.ts index be3ab2d..624fe43 100644 --- a/src/http-data-source.ts +++ b/src/http-data-source.ts @@ -434,7 +434,7 @@ export abstract class HTTPDataSource extends DataSource { if (requestIsCacheable) { // try to fetch from shared cache - if (request.requestCache) { + if (options.requestCache) { try { const cacheItem = await this.cache.get(cacheKey) if (cacheItem) { diff --git a/test/http-data-source.test.ts b/test/http-data-source.test.ts index f820fcf..fde6daf 100644 --- a/test/http-data-source.test.ts +++ b/test/http-data-source.test.ts @@ -1665,6 +1665,117 @@ test('Response is not cached due to origin error', async (t) => { t.is(cacheMap.size, 0) }) +test('Should cache a GET response and respond with the result on subsequent calls when cache setup by global request cache options', async (t) => { + t.plan(15) + + const path = '/' + + const wanted = { name: 'foo' } + + const server = http.createServer((req, res) => { + t.is(req.method, 'GET') + res.writeHead(200, { + 'content-type': 'application/json', + }) + res.write(JSON.stringify(wanted)) + res.end() + res.socket?.unref() + }) + + t.teardown(server.close.bind(server)) + + server.listen() + + const baseURL = getBaseUrlOf(server) + + let dataSource = new (class extends HTTPDataSource { + constructor() { + super(baseURL, { + requestOptions: { + requestCache: { + maxTtl: 10, + maxTtlIfError: 20, + } + }, + }) + } + getFoo() { + return this.get(path) + } + })() + + const cacheMap = new Map() + const datasSourceConfig = { + context: { + a: 1, + }, + cache: { + async delete(key: string) { + return cacheMap.delete(key) + }, + async get(key: string) { + return cacheMap.get(key) + }, + async set(key: string, value: string) { + cacheMap.set(key, value) + }, + }, + } + + dataSource.initialize(datasSourceConfig) + + let response = await dataSource.getFoo() + t.false(response.isFromCache) + t.false(response.memoized) + t.is(response.maxTtl, 10) + t.deepEqual(response.body, wanted) + + response = await dataSource.getFoo() + t.false(response.isFromCache) + t.true(response.memoized) + t.is(response.maxTtl, 10) + t.deepEqual(response.body, wanted) + + dataSource = new (class extends HTTPDataSource { + constructor() { + super(baseURL, { + requestOptions: { + requestCache: { + maxTtl: 10, + maxTtlIfError: 20, + } + }, + }) + } + getFoo() { + return this.get(path) + } + })() + + dataSource.initialize(datasSourceConfig) + + response = await dataSource.getFoo() + t.true(response.isFromCache) + t.false(response.memoized) + t.is(response.maxTtl, 10) + t.deepEqual(response.body, wanted) + + const cached = JSON.parse(cacheMap.get(baseURL + path)!) + + t.is(cacheMap.size, 2) + t.like(cached, { + statusCode: 200, + trailers: {}, + opaque: null, + headers: { + connection: 'keep-alive', + 'keep-alive': 'timeout=5', + 'transfer-encoding': 'chunked', + }, + body: wanted, + }) +}) + test('Should be able to pass custom Undici Pool', async (t) => { t.plan(2) From d4ab8152deb5a70f3c2ec0b286e074463a6cd0e4 Mon Sep 17 00:00:00 2001 From: Kamil Dybicz Date: Thu, 30 Jun 2022 15:46:25 +0200 Subject: [PATCH 2/6] making sure local caching options override global ones --- src/http-data-source.ts | 2 +- test/http-data-source.test.ts | 121 ++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/http-data-source.ts b/src/http-data-source.ts index 624fe43..b7965ed 100644 --- a/src/http-data-source.ts +++ b/src/http-data-source.ts @@ -425,8 +425,8 @@ export abstract class HTTPDataSource extends DataSource { } const options = { - ...request, ...this.globalRequestOptions, + ...request, headers, } diff --git a/test/http-data-source.test.ts b/test/http-data-source.test.ts index fde6daf..a85a453 100644 --- a/test/http-data-source.test.ts +++ b/test/http-data-source.test.ts @@ -1776,6 +1776,127 @@ test('Should cache a GET response and respond with the result on subsequent call }) }) +test('Should cache a GET response using method-level cache options over global request cache options', async (t) => { + t.plan(15) + + const path = '/' + + const wanted = { name: 'foo' } + + const server = http.createServer((req, res) => { + t.is(req.method, 'GET') + res.writeHead(200, { + 'content-type': 'application/json', + }) + res.write(JSON.stringify(wanted)) + res.end() + res.socket?.unref() + }) + + t.teardown(server.close.bind(server)) + + server.listen() + + const baseURL = getBaseUrlOf(server) + + let dataSource = new (class extends HTTPDataSource { + constructor() { + super(baseURL, { + requestOptions: { + requestCache: { + maxTtl: 10, + maxTtlIfError: 20, + } + }, + }) + } + getFoo() { + return this.get(path, { + requestCache: { + maxTtl: 20, + maxTtlIfError: 30, + }, + }) + } + })() + + const cacheMap = new Map() + const datasSourceConfig = { + context: { + a: 1, + }, + cache: { + async delete(key: string) { + return cacheMap.delete(key) + }, + async get(key: string) { + return cacheMap.get(key) + }, + async set(key: string, value: string) { + cacheMap.set(key, value) + }, + }, + } + + dataSource.initialize(datasSourceConfig) + + let response = await dataSource.getFoo() + t.false(response.isFromCache) + t.false(response.memoized) + t.is(response.maxTtl, 20) + t.deepEqual(response.body, wanted) + + response = await dataSource.getFoo() + t.false(response.isFromCache) + t.true(response.memoized) + t.is(response.maxTtl, 20) + t.deepEqual(response.body, wanted) + + dataSource = new (class extends HTTPDataSource { + constructor() { + super(baseURL, { + requestOptions: { + requestCache: { + maxTtl: 10, + maxTtlIfError: 20, + } + }, + }) + } + getFoo() { + return this.get(path, { + requestCache: { + maxTtl: 20, + maxTtlIfError: 30, + }, + }) + } + })() + + dataSource.initialize(datasSourceConfig) + + response = await dataSource.getFoo() + t.true(response.isFromCache) + t.false(response.memoized) + t.is(response.maxTtl, 20) + t.deepEqual(response.body, wanted) + + const cached = JSON.parse(cacheMap.get(baseURL + path)!) + + t.is(cacheMap.size, 2) + t.like(cached, { + statusCode: 200, + trailers: {}, + opaque: null, + headers: { + connection: 'keep-alive', + 'keep-alive': 'timeout=5', + 'transfer-encoding': 'chunked', + }, + body: wanted, + }) +}) + test('Should be able to pass custom Undici Pool', async (t) => { t.plan(2) From c83dcdb04b7dfdb1a164a0164ff7c64245e816a0 Mon Sep 17 00:00:00 2001 From: Kamil Dybicz Date: Fri, 1 Jul 2022 11:43:44 +0200 Subject: [PATCH 3/6] fixing Debug tests task for VSC --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index fd583ba..cf4c068 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "runtimeArgs": [ "--inspect-brk", "${workspaceRoot}/node_modules/.bin/ava", - "--runInBand" + "--serial" ], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" From 592250754d0d788124e8c0f362a70242df401e41 Mon Sep 17 00:00:00 2001 From: Kamil Dybicz Date: Fri, 1 Jul 2022 11:48:52 +0200 Subject: [PATCH 4/6] tweaking test names --- test/http-data-source.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/http-data-source.test.ts b/test/http-data-source.test.ts index a85a453..ec4cf0f 100644 --- a/test/http-data-source.test.ts +++ b/test/http-data-source.test.ts @@ -1665,7 +1665,7 @@ test('Response is not cached due to origin error', async (t) => { t.is(cacheMap.size, 0) }) -test('Should cache a GET response and respond with the result on subsequent calls when cache setup by global request cache options', async (t) => { +test('Should cache a GET response and respond with the result on subsequent calls when cache is setup by global request cache options', async (t) => { t.plan(15) const path = '/' @@ -1776,7 +1776,7 @@ test('Should cache a GET response and respond with the result on subsequent call }) }) -test('Should cache a GET response using method-level cache options over global request cache options', async (t) => { +test('Should cache a GET response using method-level cache options overriding global request cache options', async (t) => { t.plan(15) const path = '/' From 199832f7a577ccd6fa0687b791eceeeb55a1a5af Mon Sep 17 00:00:00 2001 From: Kamil Dybicz Date: Sun, 28 Aug 2022 21:20:13 +0200 Subject: [PATCH 5/6] removing .vscode --- .vscode/launch.json | 20 -------------------- .vscode/settings.json | 4 ---- 2 files changed, 24 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index cf4c068..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Debug Tests", - "type": "node", - "request": "launch", - "runtimeArgs": [ - "--inspect-brk", - "${workspaceRoot}/node_modules/.bin/ava", - "--serial" - ], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1ba845a..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "editor.tabSize": 2, - "editor.detectIndentation": true -} From 032eb8960df2606ff71ab637d17df4352a489365 Mon Sep 17 00:00:00 2001 From: Kamil Dybicz Date: Sun, 28 Aug 2022 21:21:15 +0200 Subject: [PATCH 6/6] Adding .vscode to .gitIgnore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f15d1da..9fa6360 100644 --- a/.gitignore +++ b/.gitignore @@ -103,4 +103,7 @@ dist # TernJS port file .tern-port -.idea \ No newline at end of file +.idea + +# Visual Studio Code +.vscode