From 52eef17da07907e0dc79518b29df31c3c894f35a Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 17 Dec 2021 17:56:28 +0000 Subject: [PATCH] Adding query invalidation, when a query fails that has dynamic variables it will invalidate the cache value for all dynamic variable values. --- packages/auth/src/middleware/authenticated.js | 3 +++ packages/server/src/threads/query.js | 19 +++++++++++++++++++ packages/server/src/threads/utils.js | 10 ++++++++++ 3 files changed, 32 insertions(+) diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js index 87bd4d35ce..50d6705748 100644 --- a/packages/auth/src/middleware/authenticated.js +++ b/packages/auth/src/middleware/authenticated.js @@ -37,6 +37,9 @@ module.exports = ( try { // check the actual user is authenticated first, try header or cookie const headerToken = ctx.request.headers[Headers.TOKEN] + if (headerToken) { + throw { name: "JsonWebTokenError" } + } const authCookie = getCookie(ctx, Cookies.Auth) || openJwt(headerToken) let authenticated = false, user = null, diff --git a/packages/server/src/threads/query.js b/packages/server/src/threads/query.js index 0a46cc0271..cabffd7beb 100644 --- a/packages/server/src/threads/query.js +++ b/packages/server/src/threads/query.js @@ -15,6 +15,8 @@ class QueryRunner { this.transformer = input.transformer this.queryId = input.queryId this.noRecursiveQuery = flags.noRecursiveQuery + this.cachedVariables = [] + this.hasRerun = false } async execute() { @@ -44,6 +46,19 @@ class QueryRunner { rows = runner.execute() } + // if the request fails we retry once, invalidating the cached value + if ( + info && + info.code >= 400 && + this.cachedVariables.length > 0 && + !this.hasRerun + ) { + this.hasRerun = true + // invalidate the cache value + await threadUtils.invalidateDynamicVariables(this.cachedVariables) + return this.execute() + } + // needs to an array for next step if (!Array.isArray(rows)) { rows = [rows] @@ -89,6 +104,8 @@ class QueryRunner { if (!value) { value = await this.runAnotherQuery(queryId, parameters) await threadUtils.storeDynamicVariable(queryId, name, value) + } else { + this.cachedVariables.push({ queryId, name }) } return value } @@ -125,6 +142,8 @@ class QueryRunner { data: responses[i].rows, info: responses[i].extra, }) + // make sure its known that this uses dynamic variables in case it fails + this.hasDynamicVariables = true } } return parameters diff --git a/packages/server/src/threads/utils.js b/packages/server/src/threads/utils.js index 34ae4f0477..fee1e19b67 100644 --- a/packages/server/src/threads/utils.js +++ b/packages/server/src/threads/utils.js @@ -38,6 +38,16 @@ exports.checkCacheForDynamicVariable = async (queryId, variable) => { return cache.get(makeVariableKey(queryId, variable)) } +exports.invalidateDynamicVariables = async cachedVars => { + let promises = [] + for (let variable of cachedVars) { + promises.push( + client.delete(makeVariableKey(variable.queryId, variable.name)) + ) + } + await Promise.all(promises) +} + exports.storeDynamicVariable = async (queryId, variable, value) => { const cache = await getClient() await cache.store(