Feat(): distributed caching (#13435)
RESOLVES CORE-1153 **What** - This pr mainly lay the foundation the caching layer. It comes with a modules (built in memory cache) and a redis provider. - Apply caching to few touch point to test Co-authored-by: Carlos R. L. Rodrigues <37986729+carlos-r-l-rodrigues@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
5b135a41fe
commit
b9d6f73320
@@ -30,20 +30,38 @@ export async function ensurePublishableApiKeyMiddleware(
|
||||
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
||||
|
||||
try {
|
||||
const { data } = await query.graph({
|
||||
entity: "api_key",
|
||||
fields: ["id", "token", "sales_channels_link.sales_channel_id"],
|
||||
filters: {
|
||||
token: publishableApiKey,
|
||||
type: ApiKeyType.PUBLISHABLE,
|
||||
$or: [
|
||||
{ revoked_at: { $eq: null } },
|
||||
{ revoked_at: { $gt: new Date() } },
|
||||
// Cache API key data and check revocation in memory
|
||||
const { data } = await query.graph(
|
||||
{
|
||||
entity: "api_key",
|
||||
fields: [
|
||||
"id",
|
||||
"token",
|
||||
"revoked_at",
|
||||
"sales_channels_link.sales_channel_id",
|
||||
],
|
||||
filters: {
|
||||
token: publishableApiKey,
|
||||
type: ApiKeyType.PUBLISHABLE,
|
||||
},
|
||||
},
|
||||
})
|
||||
{
|
||||
cache: {
|
||||
enable: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
apiKey = data[0]
|
||||
if (data.length) {
|
||||
const now = new Date()
|
||||
const cachedApiKey = data[0]
|
||||
const isRevoked =
|
||||
!!cachedApiKey.revoked_at && new Date(cachedApiKey.revoked_at) <= now
|
||||
|
||||
if (!isRevoked) {
|
||||
apiKey = cachedApiKey
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
return next(e)
|
||||
}
|
||||
|
||||
@@ -1,49 +1,88 @@
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
isString,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { MedusaRequest } from "../types"
|
||||
import type {
|
||||
GraphResultSet,
|
||||
MedusaContainer,
|
||||
RemoteJoinerOptions,
|
||||
RemoteQueryEntryPoints,
|
||||
RemoteQueryFunctionReturnPagination,
|
||||
} from "../../types"
|
||||
import { ContainerRegistrationKeys, isString } from "../../utils"
|
||||
import type { MedusaRequest } from "../types"
|
||||
|
||||
export const refetchEntities = async (
|
||||
entryPoint: string,
|
||||
idOrFilter: string | object,
|
||||
scope: MedusaContainer,
|
||||
fields: string[],
|
||||
pagination?: MedusaRequest["queryConfig"]["pagination"],
|
||||
export const refetchEntities = async <TEntry extends string>({
|
||||
entity,
|
||||
idOrFilter,
|
||||
scope,
|
||||
fields,
|
||||
pagination,
|
||||
withDeleted,
|
||||
options,
|
||||
}: {
|
||||
entity: TEntry
|
||||
idOrFilter?: string | object
|
||||
scope: MedusaContainer
|
||||
fields?: string[]
|
||||
pagination?: MedusaRequest["queryConfig"]["pagination"]
|
||||
withDeleted?: boolean
|
||||
) => {
|
||||
const remoteQuery = scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
const filters = isString(idOrFilter) ? { id: idOrFilter } : idOrFilter
|
||||
let context: object = {}
|
||||
options?: RemoteJoinerOptions
|
||||
}): Promise<
|
||||
Omit<GraphResultSet<TEntry>, "metadata"> & {
|
||||
metadata: RemoteQueryFunctionReturnPagination
|
||||
}
|
||||
> => {
|
||||
const query = scope.resolve(ContainerRegistrationKeys.QUERY)
|
||||
let filters = isString(idOrFilter) ? { id: idOrFilter } : idOrFilter
|
||||
let context!: Record<string, unknown>
|
||||
|
||||
if ("context" in filters) {
|
||||
if (filters.context) {
|
||||
context = filters.context!
|
||||
if (filters && "context" in filters) {
|
||||
const { context: context_, ...rest } = filters
|
||||
if (context_) {
|
||||
context = context_! as Record<string, unknown>
|
||||
}
|
||||
|
||||
delete filters.context
|
||||
filters = rest
|
||||
}
|
||||
|
||||
const variables = { filters, ...context, ...pagination, withDeleted }
|
||||
const graphOptions: Parameters<typeof query.graph>[0] = {
|
||||
entity,
|
||||
fields: fields ?? [],
|
||||
filters,
|
||||
pagination,
|
||||
withDeleted,
|
||||
context: context,
|
||||
}
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint,
|
||||
variables,
|
||||
const result = await query.graph(graphOptions, options)
|
||||
return {
|
||||
data: result.data as TEntry extends keyof RemoteQueryEntryPoints
|
||||
? RemoteQueryEntryPoints[TEntry][]
|
||||
: any[],
|
||||
metadata: result.metadata ?? ({} as RemoteQueryFunctionReturnPagination),
|
||||
}
|
||||
}
|
||||
|
||||
export const refetchEntity = async <TEntry extends string>({
|
||||
entity,
|
||||
idOrFilter,
|
||||
scope,
|
||||
fields,
|
||||
options,
|
||||
}: {
|
||||
entity: TEntry & string
|
||||
idOrFilter: string | object
|
||||
scope: MedusaContainer
|
||||
fields: string[]
|
||||
options?: RemoteJoinerOptions
|
||||
}): Promise<
|
||||
TEntry extends keyof RemoteQueryEntryPoints
|
||||
? RemoteQueryEntryPoints[TEntry]
|
||||
: any
|
||||
> => {
|
||||
const { data } = await refetchEntities<TEntry>({
|
||||
entity,
|
||||
idOrFilter,
|
||||
scope,
|
||||
fields,
|
||||
options,
|
||||
})
|
||||
|
||||
return await remoteQuery(queryObject)
|
||||
}
|
||||
|
||||
export const refetchEntity = async (
|
||||
entryPoint: string,
|
||||
idOrFilter: string | object,
|
||||
scope: MedusaContainer,
|
||||
fields: string[]
|
||||
) => {
|
||||
const [entity] = await refetchEntities(entryPoint, idOrFilter, scope, fields)
|
||||
|
||||
return entity
|
||||
return Array.isArray(data) ? data[0] : data
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
IApiKeyModuleService,
|
||||
IAuthModuleService,
|
||||
ICacheService,
|
||||
ICachingModuleService,
|
||||
ICartModuleService,
|
||||
ICurrencyModuleService,
|
||||
ICustomerModuleService,
|
||||
@@ -76,6 +77,7 @@ declare module "@medusajs/types" {
|
||||
[Modules.NOTIFICATION]: INotificationModuleService
|
||||
[Modules.LOCKING]: ILockingModule
|
||||
[Modules.SETTINGS]: ISettingsModuleService
|
||||
[Modules.CACHING]: ICachingModuleService
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user