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:
Adrien de Peretti
2025-09-30 18:19:06 +02:00
committed by GitHub
parent 5b135a41fe
commit b9d6f73320
117 changed files with 5741 additions and 530 deletions

View File

@@ -48,6 +48,7 @@ describe("joiner-config-builder", () => {
serviceName: Modules.FULFILLMENT,
primaryKeys: ["id"],
schema: "",
idPrefixToEntityName: {},
linkableKeys: {
fulfillment_set_id: FulfillmentSet.name,
shipping_option_id: ShippingOption.name,
@@ -136,6 +137,7 @@ describe("joiner-config-builder", () => {
serviceName: Modules.FULFILLMENT,
primaryKeys: ["id"],
schema: "",
idPrefixToEntityName: {},
linkableKeys: {},
alias: [
{
@@ -176,6 +178,7 @@ describe("joiner-config-builder", () => {
serviceName: Modules.FULFILLMENT,
primaryKeys: ["id"],
schema: "",
idPrefixToEntityName: {},
linkableKeys: {
fulfillment_set_id: FulfillmentSet.name,
shipping_option_id: ShippingOption.name,
@@ -269,6 +272,7 @@ describe("joiner-config-builder", () => {
serviceName: Modules.FULFILLMENT,
primaryKeys: ["id"],
schema: "",
idPrefixToEntityName: {},
linkableKeys: {},
alias: [
{
@@ -300,6 +304,7 @@ describe("joiner-config-builder", () => {
serviceName: Modules.FULFILLMENT,
primaryKeys: ["id"],
schema: "",
idPrefixToEntityName: {},
linkableKeys: {
fulfillment_set_id: FulfillmentSet.name,
},
@@ -335,6 +340,7 @@ describe("joiner-config-builder", () => {
serviceName: Modules.FULFILLMENT,
primaryKeys: ["id"],
schema: expect.any(String),
idPrefixToEntityName: {},
linkableKeys: {
fulfillment_set_id: FulfillmentSet.name,
shipping_option_id: ShippingOption.name,

View File

@@ -27,6 +27,7 @@ export const Modules = {
INDEX: "index",
LOCKING: "locking",
SETTINGS: "settings",
CACHING: "caching",
} as const
export const MODULE_PACKAGE_NAMES = {
@@ -58,6 +59,7 @@ export const MODULE_PACKAGE_NAMES = {
[Modules.INDEX]: "@medusajs/medusa/index-module",
[Modules.LOCKING]: "@medusajs/medusa/locking",
[Modules.SETTINGS]: "@medusajs/medusa/settings",
[Modules.CACHING]: "@medusajs/caching",
}
export const REVERSED_MODULE_PACKAGE_NAMES = Object.entries(

View File

@@ -46,8 +46,10 @@ export function defineJoinerConfig(
models,
linkableKeys,
primaryKeys,
idPrefixToEntityName,
}: {
alias?: JoinerServiceConfigAlias[]
idPrefixToEntityName?: Record<string, string>
schema?: string
models?: DmlEntity<any, any>[] | { name: string }[]
linkableKeys?: ModuleJoinerConfig["linkableKeys"]
@@ -150,6 +152,12 @@ export function defineJoinerConfig(
schema = toGraphQLSchema([...modelDefinitions.values()])
}
if (!idPrefixToEntityName) {
idPrefixToEntityName = buildIdPrefixToEntityNameFromDmlObjects([
...modelDefinitions.values(),
])
}
const linkableKeysFromDml = buildLinkableKeysFromDmlObjects([
...modelDefinitions.values(),
])
@@ -199,6 +207,7 @@ export function defineJoinerConfig(
serviceName,
primaryKeys,
schema,
idPrefixToEntityName,
linkableKeys: linkableKeys,
alias: [
...[...(alias ?? ([] as any))].map((alias) => ({
@@ -230,6 +239,31 @@ export function defineJoinerConfig(
}
}
/**
* Build the id prefix to entity name map from the DML objects
* @param models
*/
export function buildIdPrefixToEntityNameFromDmlObjects(
models: DmlEntity<any, any>[]
): Record<string, string> {
return models.reduce((acc, model) => {
const id = model.parse().schema.id as
| IdProperty
| PrimaryKeyModifier<any, any>
if (
PrimaryKeyModifier.isPrimaryKeyModifier(id) &&
id.schema.dataType.options.prefix
) {
acc[id.schema.dataType.options.prefix] = model.name
} else if (IdProperty.isIdProperty(id) && id.dataType.options.prefix) {
acc[id.dataType.options.prefix] = model.name
}
return acc
}, {})
}
/**
* From a set of DML objects, build the linkable keys
*

View File

@@ -1,6 +1,7 @@
import { Constructor, IDmlEntity, ModuleExports } from "@medusajs/types"
import { DmlEntity } from "../dml"
import {
buildIdPrefixToEntityNameFromDmlObjects,
buildLinkConfigFromLinkableKeys,
buildLinkConfigFromModelObjects,
defineJoinerConfig,
@@ -53,6 +54,10 @@ export function Module<
// TODO: Add support for non linkable modifier DML object to be skipped from the linkable generation
const linkableKeys = service.prototype.__joinerConfig().linkableKeys
service.prototype.__joinerConfig().idPrefixToEntityName =
buildIdPrefixToEntityNameFromDmlObjects(
dmlObjects.map(([, model]) => model) as DmlEntity<any, any>[]
)
if (dmlObjects.length) {
linkable = buildLinkConfigFromModelObjects<ServiceName, ModelObjects>(