feat(locking): Locking module (#9524)

**What**
- Locking Module to manage concurrency
- Default `in-memory` provider
This commit is contained in:
Carlos R. L. Rodrigues
2024-10-11 13:30:06 -03:00
committed by GitHub
parent 5c9e289c4d
commit c8b375ae2d
28 changed files with 806 additions and 39 deletions

View File

@@ -0,0 +1,85 @@
import { moduleProviderLoader } from "@medusajs/framework/modules-sdk"
import {
LoaderOptions,
ModuleProvider,
ModulesSdkTypes,
} from "@medusajs/framework/types"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
import { LockingProviderService } from "@services"
import {
LockingDefaultProvider,
LockingIdentifiersRegistrationName,
LockingProviderRegistrationPrefix,
} from "@types"
import { Lifetime, asFunction, asValue } from "awilix"
import { InMemoryLockingProvider } from "../providers/in-memory"
const registrationFn = async (klass, container, pluginOptions) => {
const key = LockingProviderService.getRegistrationIdentifier(klass)
container.register({
[LockingProviderRegistrationPrefix + key]: asFunction(
(cradle) => new klass(cradle, pluginOptions.options),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
})
container.registerAdd(LockingIdentifiersRegistrationName, asValue(key))
}
export default async ({
container,
options,
}: LoaderOptions<
(
| ModulesSdkTypes.ModuleServiceInitializeOptions
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
) & { providers: ModuleProvider[] }
>): Promise<void> => {
const logger = container.resolve(ContainerRegistrationKeys.LOGGER)
container.registerAdd(LockingIdentifiersRegistrationName, asValue(undefined))
// InMemoryLockingProvider - default provider
container.register({
[LockingProviderRegistrationPrefix + InMemoryLockingProvider.identifier]:
asFunction((cradle) => new InMemoryLockingProvider(), {
lifetime: Lifetime.SINGLETON,
}),
})
container.registerAdd(
LockingIdentifiersRegistrationName,
asValue(InMemoryLockingProvider.identifier)
)
container.register(
LockingDefaultProvider,
asValue(InMemoryLockingProvider.identifier)
)
// Load other providers
await moduleProviderLoader({
container,
providers: options?.providers || [],
registerServiceFn: registrationFn,
})
const isSingleProvider = options?.providers?.length === 1
let hasDefaultProvider = false
for (const provider of options?.providers || []) {
if (provider.is_default || isSingleProvider) {
if (provider.is_default) {
hasDefaultProvider = true
}
container.register(LockingDefaultProvider, asValue(provider.id))
}
}
if (!hasDefaultProvider) {
logger.warn(
`No default locking provider explicit defined. Using "${container.resolve(
LockingDefaultProvider
)}" as default.`
)
}
}