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
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
GraphResultSet,
|
||||
IIndexService,
|
||||
MedusaContainer,
|
||||
RemoteJoinerOptions,
|
||||
RemoteJoinerQuery,
|
||||
RemoteQueryFilters,
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
RemoteQueryObjectFromStringResult,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
Cached,
|
||||
MedusaError,
|
||||
isObject,
|
||||
remoteQueryObjectFromString,
|
||||
@@ -19,12 +21,62 @@ import {
|
||||
import { RemoteQuery } from "./remote-query"
|
||||
import { toRemoteQuery } from "./to-remote-query"
|
||||
|
||||
function extractCacheOptions(option: string) {
|
||||
return function extractKey(args: any[]) {
|
||||
return args[1]?.cache?.[option]
|
||||
}
|
||||
}
|
||||
|
||||
function isCacheEnabled(args: any[]) {
|
||||
const isEnabled = extractCacheOptions("enable")(args)
|
||||
if (isEnabled === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
isEnabled === true ||
|
||||
extractCacheOptions("key")(args) ||
|
||||
extractCacheOptions("ttl")(args) ||
|
||||
extractCacheOptions("tags")(args) ||
|
||||
extractCacheOptions("autoInvalidate")(args) ||
|
||||
extractCacheOptions("providers")(args)
|
||||
)
|
||||
}
|
||||
|
||||
const cacheDecoratorOptions = {
|
||||
enable: isCacheEnabled,
|
||||
key: async (args, cachingModule) => {
|
||||
const key = extractCacheOptions("key")(args)
|
||||
if (key) {
|
||||
return key
|
||||
}
|
||||
|
||||
const queryOptions = args[0]
|
||||
const remoteJoinerOptions = args[1] ?? {}
|
||||
const { initialData, cache, ...restOptions } = remoteJoinerOptions
|
||||
|
||||
const keyInput = {
|
||||
queryOptions,
|
||||
options: restOptions,
|
||||
}
|
||||
return await cachingModule.computeKey(keyInput)
|
||||
},
|
||||
ttl: extractCacheOptions("ttl"),
|
||||
tags: extractCacheOptions("tags"),
|
||||
autoInvalidate: extractCacheOptions("autoInvalidate"),
|
||||
providers: extractCacheOptions("providers"),
|
||||
container: function (this: Query) {
|
||||
return this.container
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* API wrapper around the remoteQuery
|
||||
*/
|
||||
export class Query {
|
||||
#remoteQuery: RemoteQuery
|
||||
#indexModule: IIndexService
|
||||
protected container: MedusaContainer
|
||||
|
||||
/**
|
||||
* Method to wrap execution of the graph query for instrumentation
|
||||
@@ -61,12 +113,15 @@ export class Query {
|
||||
constructor({
|
||||
remoteQuery,
|
||||
indexModule,
|
||||
container,
|
||||
}: {
|
||||
remoteQuery: RemoteQuery
|
||||
indexModule: IIndexService
|
||||
container: MedusaContainer
|
||||
}) {
|
||||
this.#remoteQuery = remoteQuery
|
||||
this.#indexModule = indexModule
|
||||
this.container = container
|
||||
}
|
||||
|
||||
#unwrapQueryConfig(
|
||||
@@ -151,6 +206,7 @@ export class Query {
|
||||
* Graph function uses the remoteQuery under the hood and
|
||||
* returns a result set
|
||||
*/
|
||||
@Cached(cacheDecoratorOptions)
|
||||
async graph<const TEntry extends string>(
|
||||
queryOptions: RemoteQueryInput<TEntry>,
|
||||
options?: RemoteJoinerOptions
|
||||
@@ -189,6 +245,7 @@ export class Query {
|
||||
* Index function uses the Index module to query and hydrates the data with query.graph
|
||||
* returns a result set
|
||||
*/
|
||||
@Cached(cacheDecoratorOptions)
|
||||
async index<const TEntry extends string>(
|
||||
queryOptions: RemoteQueryInput<TEntry> & {
|
||||
joinFilters?: RemoteQueryFilters<TEntry>
|
||||
@@ -266,13 +323,16 @@ export class Query {
|
||||
export function createQuery({
|
||||
remoteQuery,
|
||||
indexModule,
|
||||
container,
|
||||
}: {
|
||||
remoteQuery: RemoteQuery
|
||||
indexModule: IIndexService
|
||||
container: MedusaContainer
|
||||
}) {
|
||||
const query = new Query({
|
||||
remoteQuery,
|
||||
indexModule,
|
||||
container,
|
||||
})
|
||||
|
||||
function backwardCompatibleQuery(...args: any[]) {
|
||||
|
||||
@@ -69,8 +69,7 @@ export function toRemoteQuery<const TEntity extends string>(
|
||||
}
|
||||
|
||||
if (QueryContext.isQueryContext(src)) {
|
||||
const normalizedFilters = { ...src } as any
|
||||
delete normalizedFilters.__type
|
||||
const { __type, ...normalizedFilters } = src as any
|
||||
|
||||
const prop = "context"
|
||||
|
||||
@@ -100,7 +99,7 @@ export function toRemoteQuery<const TEntity extends string>(
|
||||
}
|
||||
|
||||
// Process filters and context recursively
|
||||
processNestedObjects(joinerQuery[entity], context)
|
||||
processNestedObjects(joinerQuery[entity], context, true)
|
||||
|
||||
for (const field of fields) {
|
||||
const fieldAsString = field as string
|
||||
|
||||
Reference in New Issue
Block a user