From f6705b879abafd7db07885fa282d55ed0c896528 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 10 Dec 2021 15:10:45 +0000 Subject: [PATCH] Reducing the load on DB caused by CouchDB all_db when working with a large number of couch databases. --- packages/auth/src/db/utils.js | 45 +++++++++++++++++++++++++++++------ packages/auth/src/helpers.js | 9 +++++++ 2 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 packages/auth/src/helpers.js diff --git a/packages/auth/src/db/utils.js b/packages/auth/src/db/utils.js index d23d407dab..7ced405c82 100644 --- a/packages/auth/src/db/utils.js +++ b/packages/auth/src/db/utils.js @@ -3,10 +3,15 @@ const Replication = require("./Replication") const { DEFAULT_TENANT_ID, Configs } = require("../constants") const env = require("../environment") const { StaticDatabases, SEPARATOR, DocumentTypes } = require("./constants") -const { getTenantId, getTenantIDFromAppID } = require("../tenancy") +const { + getTenantId, + getTenantIDFromAppID, + getGlobalDBName, +} = require("../tenancy") const fetch = require("node-fetch") const { getCouch } = require("./index") const { getAppMetadata } = require("../cache/appMetadata") +const { checkSlashesInUrl } = require("../helpers") const NO_APP_ERROR = "No app provided" @@ -194,6 +199,10 @@ exports.getCouchUrl = () => { return `${protocol}://${env.COUCH_DB_USERNAME}:${env.COUCH_DB_PASSWORD}@${rest}` } +exports.getStartEndKeyURL = (base, baseKey, tenantId = "") => { + return `${base}?startkey="${baseKey}${SEPARATOR}${tenantId}"&endkey="${baseKey}${SEPARATOR}${tenantId}${UNICODE_MAX}"` +} + /** * if in production this will use the CouchDB _all_dbs call to retrieve a list of databases. If testing * when using Pouch it will use the pouchdb-all-dbs package. @@ -203,12 +212,34 @@ exports.getAllDbs = async () => { if (env.isTest()) { return getCouch().allDbs() } - const response = await fetch(`${exports.getCouchUrl()}/_all_dbs`) - if (response.status === 200) { - return response.json() - } else { - throw "Cannot connect to CouchDB instance" + let dbs = [] + async function addDbs(url) { + const response = await fetch(checkSlashesInUrl(encodeURI(url))) + if (response.status === 200) { + let json = await response.json() + dbs = dbs.concat(json) + } else { + throw "Cannot connect to CouchDB instance" + } } + let couchUrl = `${exports.getCouchUrl()}_all_dbs` + if (env.MULTI_TENANCY) { + let tenantId = getTenantId() + // get prod apps + await addDbs( + exports.getStartEndKeyURL(couchUrl, DocumentTypes.APP, tenantId) + ) + // get dev apps + await addDbs( + exports.getStartEndKeyURL(couchUrl, DocumentTypes.APP_DEV, tenantId) + ) + // add global db name + dbs.push(getGlobalDBName(tenantId)) + } else { + // just get all DBs in self host + await addDbs(couchUrl) + } + return dbs } /** @@ -389,7 +420,7 @@ const getScopedFullConfig = async function (db, { type, user, workspace }) { } const getPlatformUrl = async settings => { - let platformUrl = env.PLATFORM_URL + let platformUrl = env.PLATFORM_URL || "http://localhost:10000" if (!env.SELF_HOSTED && env.MULTI_TENANCY) { // cloud and multi tenant - add the tenant to the default platform url diff --git a/packages/auth/src/helpers.js b/packages/auth/src/helpers.js new file mode 100644 index 0000000000..b402a82cf3 --- /dev/null +++ b/packages/auth/src/helpers.js @@ -0,0 +1,9 @@ +/** + * Makes sure that a URL has the correct number of slashes, while maintaining the + * http(s):// double slashes. + * @param {string} url The URL to test and remove any extra double slashes. + * @return {string} The updated url. + */ +exports.checkSlashesInUrl = url => { + return url.replace(/(https?:\/\/)|(\/)+/g, "$1$2") +}