Skip to content

Commit

Permalink
feat(locking): Locking module (medusajs#9524)
Browse files Browse the repository at this point in the history
**What**
- Locking Module to manage concurrency
- Default `in-memory` provider
  • Loading branch information
carlos-r-l-rodrigues authored Oct 11, 2024
1 parent 5c9e289 commit c8b375a
Show file tree
Hide file tree
Showing 28 changed files with 806 additions and 39 deletions.
1 change: 1 addition & 0 deletions .changeset/little-books-reply.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@medusajs/admin-vite-plugin": patch
"@medusajs/framework": patch
"@medusajs/index": patch
"@medusajs/locking": patch
---

chore: Preview release changeset
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ packages/*
!packages/cache-inmemory
!packages/create-medusa-app
!packages/product
!packages/locking
!packages/orchestration
!packages/workflows-sdk
!packages/core-flows
Expand Down
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ module.exports = {
"./packages/modules/workflow-engine-redis/tsconfig.spec.json",
"./packages/modules/link-modules/tsconfig.spec.json",
"./packages/modules/user/tsconfig.spec.json",
"./packages/modules/locking/tsconfig.spec.json",

"./packages/modules/providers/file-local/tsconfig.spec.json",
"./packages/modules/providers/file-s3/tsconfig.spec.json",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ www/**/.yarn/*
.idea
.turbo
build/**
dist/**
**/dist
**/stats
.favorites.json
Expand Down
32 changes: 17 additions & 15 deletions packages/core/framework/src/types/container.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import { Knex } from "@mikro-orm/knex"
import { RemoteLink } from "@medusajs/modules-sdk"
import { AwilixContainer, ResolveOptions } from "awilix"
import { Modules, ContainerRegistrationKeys } from "@medusajs/utils"
import {
Logger,
ConfigModule,
ModuleImplementations,
RemoteQueryFunction,
IApiKeyModuleService,
IAuthModuleService,
ICacheService,
ICartModuleService,
ICurrencyModuleService,
ICustomerModuleService,
IEventBusModuleService,
IFileModuleService,
IFulfillmentModuleService,
IInventoryService,
ILockingModule,
INotificationModuleService,
IOrderModuleService,
IPaymentModuleService,
IPricingModuleService,
IProductModuleService,
IPromotionModuleService,
IRegionModuleService,
ISalesChannelModuleService,
ITaxModuleService,
IFulfillmentModuleService,
IStockLocationService,
IStoreModuleService,
ITaxModuleService,
IUserModuleService,
IWorkflowEngineService,
IRegionModuleService,
IOrderModuleService,
IApiKeyModuleService,
IStoreModuleService,
ICurrencyModuleService,
IFileModuleService,
INotificationModuleService,
Logger,
ModuleImplementations,
RemoteQueryFunction,
} from "@medusajs/types"
import { ContainerRegistrationKeys, Modules } from "@medusajs/utils"
import { Knex } from "@mikro-orm/knex"
import { AwilixContainer, ResolveOptions } from "awilix"

declare module "@medusajs/types" {
export interface ModuleImplementations {
Expand Down Expand Up @@ -63,6 +64,7 @@ declare module "@medusajs/types" {
[Modules.CURRENCY]: ICurrencyModuleService
[Modules.FILE]: IFileModuleService
[Modules.NOTIFICATION]: INotificationModuleService
[Modules.LOCKING]: ILockingModule
}
}

Expand Down
54 changes: 33 additions & 21 deletions packages/core/modules-sdk/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.EVENT_BUS),
isRequired: true,
isQueryable: false,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand Down Expand Up @@ -63,7 +63,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.PRODUCT),
isRequired: false,
isQueryable: true,
dependencies: [Modules.EVENT_BUS, "logger"],
dependencies: [Modules.EVENT_BUS, ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -75,7 +75,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.PRICING),
isRequired: false,
isQueryable: true,
dependencies: [Modules.EVENT_BUS, "logger"],
dependencies: [Modules.EVENT_BUS, ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -87,7 +87,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.PROMOTION),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -99,7 +99,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.AUTH),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -111,7 +111,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.WORKFLOW_ENGINE),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
__passSharedContainer: true,
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
Expand All @@ -124,7 +124,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.SALES_CHANNEL),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -136,7 +136,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.FULFILLMENT),
isRequired: false,
isQueryable: true,
dependencies: ["logger", Modules.EVENT_BUS],
dependencies: [ContainerRegistrationKeys.LOGGER, Modules.EVENT_BUS],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -148,7 +148,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.CART),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -160,7 +160,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.CUSTOMER),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -172,7 +172,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.PAYMENT),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -184,7 +184,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.USER),
isRequired: false,
isQueryable: true,
dependencies: [Modules.EVENT_BUS, "logger"],
dependencies: [Modules.EVENT_BUS, ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -196,7 +196,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.REGION),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -208,7 +208,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.ORDER),
isRequired: false,
isQueryable: true,
dependencies: ["logger", Modules.EVENT_BUS],
dependencies: [ContainerRegistrationKeys.LOGGER, Modules.EVENT_BUS],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -220,7 +220,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.TAX),
isRequired: false,
isQueryable: true,
dependencies: ["logger", Modules.EVENT_BUS],
dependencies: [ContainerRegistrationKeys.LOGGER, Modules.EVENT_BUS],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -232,7 +232,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.API_KEY),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -244,7 +244,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.STORE),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -256,7 +256,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.CURRENCY),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -268,7 +268,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.FILE),
isRequired: false,
isQueryable: true,
dependencies: ["logger"],
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -280,7 +280,7 @@ export const ModulesDefinition: {
label: upperCaseFirst(Modules.NOTIFICATION),
isRequired: false,
isQueryable: true,
dependencies: [Modules.EVENT_BUS, "logger"],
dependencies: [Modules.EVENT_BUS, ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
Expand All @@ -294,7 +294,7 @@ export const ModulesDefinition: {
isQueryable: false,
dependencies: [
Modules.EVENT_BUS,
"logger",
ContainerRegistrationKeys.LOGGER,
ContainerRegistrationKeys.REMOTE_QUERY,
ContainerRegistrationKeys.QUERY,
],
Expand All @@ -303,6 +303,18 @@ export const ModulesDefinition: {
resources: MODULE_RESOURCE_TYPE.SHARED,
},
},
[Modules.LOCKING]: {
key: Modules.LOCKING,
defaultPackage: false,
label: upperCaseFirst(Modules.LOCKING),
isRequired: false,
isQueryable: false,
dependencies: [ContainerRegistrationKeys.LOGGER],
defaultModuleDeclaration: {
scope: MODULE_SCOPE.INTERNAL,
resources: MODULE_RESOURCE_TYPE.SHARED,
},
},
}

export const MODULE_DEFINITIONS: ModuleDefinition[] =
Expand Down
4 changes: 2 additions & 2 deletions packages/core/modules-sdk/src/medusa-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export async function loadModules(args: {
sharedResourcesConfig,
migrationOnly = false,
loaderOnly = false,
workerMode = "server" as ModuleBootstrapOptions["workerMode"],
workerMode = "shared" as ModuleBootstrapOptions["workerMode"],
} = args

const allModules = {} as any
Expand Down Expand Up @@ -307,7 +307,7 @@ async function MedusaApp_({
injectedDependencies = {},
migrationOnly = false,
loaderOnly = false,
workerMode = "server",
workerMode = "shared",
}: MedusaAppOptions & {
migrationOnly?: boolean
} = {}): Promise<MedusaAppOutput> {
Expand Down
1 change: 1 addition & 0 deletions packages/core/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from "./index-data"
export * from "./inventory"
export * from "./joiner"
export * from "./link-modules"
export * from "./locking"
export * from "./logger"
export * from "./modules-sdk"
export * from "./notification"
Expand Down
69 changes: 69 additions & 0 deletions packages/core/types/src/locking/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Context } from "../shared-context"

export interface ILockingProvider {
execute<T>(
keys: string | string[],
job: () => Promise<T>,
args?: {
timeout?: number
},
sharedContext?: Context
): Promise<T>
acquire(
keys: string | string[],
args?: {
ownerId?: string | null
expire?: number
},
sharedContext?: Context
): Promise<void>
release(
keys: string | string[],
args?: {
ownerId?: string | null
},
sharedContext?: Context
): Promise<boolean>
releaseAll(
args?: {
ownerId?: string | null
},
sharedContext?: Context
): Promise<void>
}

export interface ILockingModule {
execute<T>(
keys: string | string[],
job: () => Promise<T>,
args?: {
timeout?: number
provider?: string
},
sharedContext?: Context
): Promise<T>
acquire(
keys: string | string[],
args?: {
ownerId?: string | null
expire?: number
provider?: string
},
sharedContext?: Context
): Promise<void>
release(
keys: string | string[],
args?: {
ownerId?: string | null
provider?: string
},
sharedContext?: Context
): Promise<boolean>
releaseAll(
args?: {
ownerId?: string | null
provider?: string
},
sharedContext?: Context
): Promise<void>
}
Loading

0 comments on commit c8b375a

Please sign in to comment.