withCache wrapper for working with redis

This commit is contained in:
Martin McKeaveney 2022-05-23 00:09:03 +01:00
parent ea5d8e9d56
commit 6d3aa6a806
3 changed files with 77 additions and 48 deletions

View File

@ -18,6 +18,7 @@ exports.Databases = {
APP_METADATA: "appMetadata", APP_METADATA: "appMetadata",
QUERY_VARS: "queryVars", QUERY_VARS: "queryVars",
LICENSES: "license", LICENSES: "license",
DATA_CACHE: "data_cache",
} }
exports.SEPARATOR = SEPARATOR exports.SEPARATOR = SEPARATOR

View File

@ -14,6 +14,7 @@ const {
const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy") const { getGlobalDB, getTenantId } = require("@budibase/backend-core/tenancy")
const env = require("../../../environment") const env = require("../../../environment")
const { googleCallbackUrl, oidcCallbackUrl } = require("./auth") const { googleCallbackUrl, oidcCallbackUrl } = require("./auth")
const { withCache } = require("../../../utilities/redis")
const BB_TENANT_CDN = "https://tenants.cdn.budi.live" const BB_TENANT_CDN = "https://tenants.cdn.budi.live"
@ -249,59 +250,64 @@ exports.configChecklist = async function (ctx) {
const tenantId = getTenantId() const tenantId = getTenantId()
try { try {
// TODO: Watch get started video const ONE_MINUTE = 600
let apps = [] ctx.body = await withCache(
if (!env.MULTI_TENANCY || tenantId) { `checklist:${tenantId}`,
// Apps exist ONE_MINUTE,
apps = await getAllApps({ idsOnly: true, efficient: true }) async () => {
} let apps = []
if (!env.MULTI_TENANCY || tenantId) {
// Apps exist
apps = await getAllApps({ idsOnly: true, efficient: true })
}
// They have set up SMTP // They have set up SMTP
const smtpConfig = await getScopedFullConfig(db, { const smtpConfig = await getScopedFullConfig(db, {
type: Configs.SMTP, type: Configs.SMTP,
}) })
// They have set up Google Auth // They have set up Google Auth
const googleConfig = await getScopedFullConfig(db, { const googleConfig = await getScopedFullConfig(db, {
type: Configs.GOOGLE, type: Configs.GOOGLE,
}) })
// They have set up OIDC // They have set up OIDC
const oidcConfig = await getScopedFullConfig(db, { const oidcConfig = await getScopedFullConfig(db, {
type: Configs.OIDC, type: Configs.OIDC,
}) })
// They have set up an global user // They have set up an global user
const users = await db.allDocs( const users = await db.allDocs(
getGlobalUserParams(null, { getGlobalUserParams(null, {
include_docs: true, include_docs: true,
limit: 1, limit: 1,
}) })
)
return {
apps: {
checked: apps.length > 0,
label: "Create your first app",
link: "/builder/portal/apps",
},
smtp: {
checked: !!smtpConfig,
label: "Set up email",
link: "/builder/portal/manage/email",
},
adminUser: {
checked: users && users.rows.length >= 1,
label: "Create your first user",
link: "/builder/portal/manage/users",
},
sso: {
checked: !!googleConfig || !!oidcConfig,
label: "Set up single sign-on",
link: "/builder/portal/manage/auth",
},
}
}
) )
ctx.body = {
apps: {
checked: apps.length > 0,
label: "Create your first app",
link: "/builder/portal/apps",
},
smtp: {
checked: !!smtpConfig,
label: "Set up email",
link: "/builder/portal/manage/email",
},
adminUser: {
checked: users && users.rows.length >= 1,
label: "Create your first user",
link: "/builder/portal/manage/users",
},
sso: {
checked: !!googleConfig || !!oidcConfig,
label: "Set up single sign-on",
link: "/builder/portal/manage/auth",
},
}
} catch (err) { } catch (err) {
ctx.throw(err.status, err) ctx.throw(err.status, err)
} }

View File

@ -12,7 +12,7 @@ function getExpirySecondsForDB(db) {
} }
} }
let pwResetClient, invitationClient let pwResetClient, invitationClient, cachingClient
function getClient(db) { function getClient(db) {
switch (db) { switch (db) {
@ -20,6 +20,8 @@ function getClient(db) {
return pwResetClient return pwResetClient
case utils.Databases.INVITATIONS: case utils.Databases.INVITATIONS:
return invitationClient return invitationClient
case utils.Databases.DATA_CACHE:
return cachingClient
} }
} }
@ -45,8 +47,10 @@ async function getACode(db, code, deleteCode = true) {
exports.init = async () => { exports.init = async () => {
pwResetClient = new Client(utils.Databases.PW_RESETS) pwResetClient = new Client(utils.Databases.PW_RESETS)
invitationClient = new Client(utils.Databases.INVITATIONS) invitationClient = new Client(utils.Databases.INVITATIONS)
cachingClient = new Client(utils.Databases.DATA_CACHE)
await pwResetClient.init() await pwResetClient.init()
await invitationClient.init() await invitationClient.init()
await cachingClient.init()
} }
/** /**
@ -104,3 +108,21 @@ exports.checkInviteCode = async (inviteCode, deleteCode = true) => {
throw "Invitation is not valid or has expired, please request a new one." throw "Invitation is not valid or has expired, please request a new one."
} }
} }
// TODO: move into backend-core
exports.withCache = async (key, ttl, fetchFn) => {
const cachedValue = await cachingClient.get(key)
if (cachedValue) {
return cachedValue
}
try {
const fetchedValue = await fetchFn()
await cachingClient.store(key, fetchedValue, ttl)
return fetchedValue
} catch (err) {
console.error("Error calling fetch function", err)
throw err
}
}