@medusajs/locking-redis 2.22.0-snapshot-20261020204851 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/AGENTS.md +53 -0
  2. package/README.md +103 -0
  3. package/package.json +7 -3
package/AGENTS.md ADDED
@@ -0,0 +1,53 @@
1
+ # @medusajs/locking-redis
2
+
3
+ Locking Module provider backed by Redis (`ioredis` + Lua scripts), with lease renewal during `execute`. Recommended for production and multi-instance deployments.
4
+
5
+ ## Using this package
6
+
7
+ ```ts
8
+ module.exports = defineConfig({
9
+ modules: [
10
+ {
11
+ resolve: "@medusajs/medusa/locking",
12
+ options: {
13
+ providers: [
14
+ {
15
+ resolve: "@medusajs/medusa/locking-redis",
16
+ id: "locking-redis",
17
+ // use this provider by default
18
+ is_default: true,
19
+ options: {
20
+ redisUrl: process.env.LOCKING_REDIS_URL,
21
+ },
22
+ },
23
+ ],
24
+ },
25
+ },
26
+ ],
27
+ })
28
+ ```
29
+
30
+ - Options (`src/types/index.ts`): `redisUrl` (required), `redisOptions` (ioredis), `namespace` (key prefix, default `"medusa_lock:"`), `waitLockingTimeout` (s, default 5), `defaultRetryInterval` (ms, default 20), `maximumRetryInterval` (ms, default 1000), `backoffFactor` (default 2).
31
+ - On Medusa Cloud, `defineConfig` registers it as the default when `REDIS_URL` is set.
32
+ - Docs: https://docs.medusajs.com/resources/infrastructure-modules/locking/redis.md
33
+ - Build a custom locking provider: https://docs.medusajs.com/resources/references/locking-module-provider.md
34
+
35
+ ## Architecture
36
+
37
+ - `src/loaders/index.ts`: creates the ioredis connection and registers `redisClient` and `prefix` in the provider container.
38
+ - `src/services/redis-lock.ts`: `RedisLockingProvider implements ILockingProvider`, `static identifier = "locking-redis"`. Implements `execute`, `acquire`, `release`, `releaseAll`. Atomic acquire/extend/release are custom Lua commands defined with `defineCommand`, all owner-checked.
39
+ - `execute(keys, job, { timeout?, expire? })`: acquires with a per-call owner `execute:{uuid}`, retries with exponential backoff + jitter until `timeout`, then renews the lease (`expire`, default 60 s) every `expire / 3` while `job` runs. If renewal finds the key lost, `job`'s `AbortSignal` is aborted and `execute` throws a `CONFLICT` error even if `job` resolved.
40
+ - Reference for a custom locking provider that needs lease semantics.
41
+
42
+ ## Development
43
+
44
+ - `yarn build` (also runs `resolve:aliases`), `yarn test` (unit specs in `src/services/__tests__`).
45
+ - `yarn test:integration`: uses `moduleIntegrationTestRunner` (Postgres) plus Redis at `REDIS_URL` (default `redis://localhost:6379`).
46
+
47
+ ## Gotchas
48
+
49
+ - Missing `redisUrl` throws at boot. A failed initial connect is only logged.
50
+ - The `ttl` option in the type is unused.
51
+ - `acquire`/`release`/`releaseAll` without `ownerId` use the owner `"*"`; `releaseAll()` only deletes keys owned by `"*"`, not every lock.
52
+ - Long jobs passed to `execute` should honor the `signal` argument; ignoring it still makes `execute` throw once the lease is lost.
53
+ - `acquire` throws `CONFLICT` immediately on a held key unless `awaitQueue: true` (then it retries with backoff, with no timeout of its own). Without `expire`, the key never expires.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ <p align="center">
2
+ <a href="https://www.medusajs.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/59018053/229103275-b5e482bb-4601-46e6-8142-244f531cebdb.svg">
5
+ <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
6
+ <img alt="Medusa logo" src="https://user-images.githubusercontent.com/59018053/229103726-e5b529a3-9b3f-4970-8a1f-c6af37f087bf.svg">
7
+ </picture>
8
+ </a>
9
+ </p>
10
+ <h1 align="center">
11
+ @medusajs/locking-redis
12
+ </h1>
13
+
14
+ <h4 align="center">
15
+ <a href="https://docs.medusajs.com">Documentation</a> |
16
+ <a href="https://www.medusajs.com">Website</a>
17
+ </h4>
18
+
19
+ <p align="center">
20
+ Building blocks for digital commerce
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://github.com/medusajs/medusa/blob/develop/LICENSE">
24
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Medusa is released under the MIT license." />
25
+ </a>
26
+ <a href="https://github.com/medusajs/medusa/blob/develop/CONTRIBUTING.md">
27
+ <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
28
+ </a>
29
+ <a href="https://discord.gg/xpCwq3Kfn8">
30
+ <img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
31
+ </a>
32
+ <a href="https://twitter.com/intent/follow?screen_name=medusajs">
33
+ <img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
34
+ </a>
35
+ </p>
36
+
37
+ Redis Locking Module Provider for Medusa: implements the Locking Module's locks in Redis, so locks are shared across all Medusa instances. It's the recommended locking provider for production. It ships with `@medusajs/medusa` and is registered through the `@medusajs/medusa/locking-redis` path.
38
+
39
+ ## At a glance
40
+
41
+ | | |
42
+ | --- | --- |
43
+ | Package | `@medusajs/locking-redis` |
44
+ | Type | Module Provider (Locking Module) |
45
+ | Provider ID | `locking-redis` |
46
+ | Registered by default | No (on Medusa Cloud, registered as the default when `REDIS_URL` is set) |
47
+ | Import from | `@medusajs/medusa/locking-redis` |
48
+
49
+ ## Installation
50
+
51
+ No installation needed. The provider is a dependency of `@medusajs/medusa`. You need a running Redis server.
52
+
53
+ ## Usage
54
+
55
+ Register the provider in the Locking Module's `providers` array in `medusa-config.ts`:
56
+
57
+ ```ts
58
+ import { defineConfig } from "@medusajs/framework/utils"
59
+
60
+ module.exports = defineConfig({
61
+ // ...
62
+ modules: [
63
+ {
64
+ resolve: "@medusajs/medusa/locking",
65
+ options: {
66
+ providers: [
67
+ {
68
+ resolve: "@medusajs/medusa/locking-redis",
69
+ id: "locking-redis",
70
+ // makes this the default locking provider
71
+ is_default: true,
72
+ options: {
73
+ redisUrl: process.env.LOCKING_REDIS_URL,
74
+ },
75
+ },
76
+ ],
77
+ },
78
+ },
79
+ ],
80
+ })
81
+ ```
82
+
83
+ ## Configuration
84
+
85
+ | Option | Type | Description | Default |
86
+ | --- | --- | --- | --- |
87
+ | `redisUrl` | `string` | Required. The Redis connection URL. | - |
88
+ | `redisOptions` | `RedisOptions` | Options passed to the `ioredis` client. | - |
89
+ | `namespace` | `string` | Prefix for lock keys. | `"medusa_lock:"` |
90
+ | `waitLockingTimeout` | `number` | Default time to wait to acquire a lock, in seconds. | `5` |
91
+ | `defaultRetryInterval` | `number` | Initial interval between lock attempts, in milliseconds. | `20` |
92
+ | `maximumRetryInterval` | `number` | Maximum interval between lock attempts, in milliseconds. | `1000` |
93
+ | `backoffFactor` | `number` | Multiplier applied to the retry interval after each attempt. | `2` |
94
+
95
+ | Environment variable | Description |
96
+ | --- | --- |
97
+ | `LOCKING_REDIS_URL` | Value for `redisUrl`, as used in the example above. |
98
+ | `REDIS_URL` | On Medusa Cloud, `defineConfig` registers this provider as the default with this URL. |
99
+
100
+ ## Resources
101
+
102
+ - [Redis Locking Module Provider](https://docs.medusajs.com/resources/infrastructure-modules/locking/redis)
103
+ - [Locking Module](https://docs.medusajs.com/resources/infrastructure-modules/locking)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medusajs/locking-redis",
3
- "version": "2.22.0-snapshot-20261020204851",
3
+ "version": "2.22.0",
4
4
  "description": "Redis Lock for Medusa",
5
5
  "main": "dist/index.js",
6
6
  "repository": {
@@ -13,20 +13,24 @@
13
13
  },
14
14
  "files": [
15
15
  "dist",
16
+ "AGENTS.md",
16
17
  "!dist/**/__tests__",
17
18
  "!dist/**/__mocks__",
18
19
  "!dist/**/__fixtures__"
19
20
  ],
21
+ "llms": "https://docs.medusajs.com/llms.txt",
22
+ "llmsFull": "https://docs.medusajs.com/llms-full.txt",
23
+ "mcpServer": "https://docs.medusajs.com/mcp",
20
24
  "engines": {
21
25
  "node": ">=22.22.0"
22
26
  },
23
27
  "author": "Medusa",
24
28
  "license": "MIT",
25
29
  "devDependencies": {
26
- "@medusajs/framework": "2.22.0-snapshot-20261020204851"
30
+ "@medusajs/framework": "2.22.0"
27
31
  },
28
32
  "peerDependencies": {
29
- "@medusajs/framework": "2.22.0-snapshot-20261020204851"
33
+ "@medusajs/framework": "2.22.0"
30
34
  },
31
35
  "dependencies": {
32
36
  "ioredis": "^5.4.1"