@mondart/nestjs-common-module-caching 3.1.6 → 3.2.1
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.
- package/README.md +143 -0
- package/dist/caching.module.d.ts.map +1 -1
- package/dist/caching.module.js +10 -2
- package/dist/caching.module.js.map +1 -1
- package/dist/constants/caching.const.d.ts +1 -0
- package/dist/constants/caching.const.d.ts.map +1 -1
- package/dist/constants/caching.const.js +2 -1
- package/dist/constants/caching.const.js.map +1 -1
- package/dist/decorators/distributed-lock.decorator.d.ts +3 -0
- package/dist/decorators/distributed-lock.decorator.d.ts.map +1 -0
- package/dist/decorators/distributed-lock.decorator.js +8 -0
- package/dist/decorators/distributed-lock.decorator.js.map +1 -0
- package/dist/errors/distributed-lock-lost.error.d.ts +5 -0
- package/dist/errors/distributed-lock-lost.error.d.ts.map +1 -0
- package/dist/errors/distributed-lock-lost.error.js +12 -0
- package/dist/errors/distributed-lock-lost.error.js.map +1 -0
- package/dist/explorers/distributed-lock.explorer.d.ts +14 -0
- package/dist/explorers/distributed-lock.explorer.d.ts.map +1 -0
- package/dist/explorers/distributed-lock.explorer.js +70 -0
- package/dist/explorers/distributed-lock.explorer.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/distributed-lock.interface.d.ts +18 -0
- package/dist/interfaces/distributed-lock.interface.d.ts.map +1 -0
- package/dist/interfaces/distributed-lock.interface.js +3 -0
- package/dist/interfaces/distributed-lock.interface.js.map +1 -0
- package/dist/services/caching.service.d.ts +2 -1
- package/dist/services/caching.service.d.ts.map +1 -1
- package/dist/services/caching.service.js +4 -0
- package/dist/services/caching.service.js.map +1 -1
- package/dist/services/distributed-lock.service.d.ts +17 -0
- package/dist/services/distributed-lock.service.d.ts.map +1 -0
- package/dist/services/distributed-lock.service.js +161 -0
- package/dist/services/distributed-lock.service.js.map +1 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# @mondart/nestjs-common-module-caching
|
|
2
|
+
|
|
3
|
+
Redis-backed caching for NestJS: a `CachingService` for direct key/value
|
|
4
|
+
access, an HTTP response-caching interceptor, and a `DistributedLockService`
|
|
5
|
+
for coordinating work across multiple instances of the same service (e.g. so
|
|
6
|
+
only one replica runs a given cron tick).
|
|
7
|
+
|
|
8
|
+
## Registration
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { CachingModule } from '@mondart/nestjs-common-module-caching';
|
|
12
|
+
|
|
13
|
+
@Module({
|
|
14
|
+
imports: [
|
|
15
|
+
CachingModule.register({
|
|
16
|
+
host: 'localhost',
|
|
17
|
+
port: 6379,
|
|
18
|
+
password: 'secret',
|
|
19
|
+
database: 0,
|
|
20
|
+
namespace: 'my-service',
|
|
21
|
+
ttl: 60_000, // default TTL in ms
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
})
|
|
25
|
+
export class AppModule {}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or asynchronously:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
CachingModule.registerAsync({
|
|
32
|
+
imports: [ConfigModule],
|
|
33
|
+
inject: [ConfigService],
|
|
34
|
+
useFactory: (config: ConfigService) => ({
|
|
35
|
+
host: config.get('REDIS_HOST'),
|
|
36
|
+
port: config.get('REDIS_PORT'),
|
|
37
|
+
password: config.get('REDIS_PASSWORD'),
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`CachingModule` is `@Global()`, so `CachingService` and
|
|
43
|
+
`DistributedLockService` are available for injection anywhere without
|
|
44
|
+
re-importing the module.
|
|
45
|
+
|
|
46
|
+
## CachingService
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
constructor(private readonly cachingService: CachingService) {}
|
|
50
|
+
|
|
51
|
+
await this.cachingService.set('user:42', user, 60); // ttlSeconds
|
|
52
|
+
const user = await this.cachingService.get<User>('user:42');
|
|
53
|
+
await this.cachingService.setMany([{ key: 'a', value: 1, ttlSeconds: 30 }]);
|
|
54
|
+
const [a, b] = await this.cachingService.getMany<number>(['a', 'b']);
|
|
55
|
+
await this.cachingService.has('user:42');
|
|
56
|
+
await this.cachingService.ttl('user:42');
|
|
57
|
+
await this.cachingService.del('user:42');
|
|
58
|
+
await this.cachingService.delMany(['a', 'b']);
|
|
59
|
+
await this.cachingService.clear();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Caching HTTP responses
|
|
63
|
+
|
|
64
|
+
`CachingModule` registers `CachingInterceptor` globally, but it only caches a
|
|
65
|
+
`GET` route when the handler (or controller) is explicitly opted in — nothing
|
|
66
|
+
is cached by default.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import {
|
|
70
|
+
UseCachingInterceptorDecorator,
|
|
71
|
+
SkipCachingInterceptorDecorator,
|
|
72
|
+
} from '@mondart/nestjs-common-module-caching';
|
|
73
|
+
|
|
74
|
+
@UseCachingInterceptorDecorator({ ttl: 30_000 })
|
|
75
|
+
@Get()
|
|
76
|
+
findAll() { ... }
|
|
77
|
+
|
|
78
|
+
@SkipCachingInterceptorDecorator()
|
|
79
|
+
@Get('live')
|
|
80
|
+
findLive() { ... } // never cached, even if the controller opts in
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`key`/`ttl` accept the same static value or factory function types as
|
|
84
|
+
`@nestjs/cache-manager`'s own `CacheKey`/`CacheTTL`. When no `key` is given,
|
|
85
|
+
requests are cached per `ControllerName_methodName:<url+query hash>`.
|
|
86
|
+
|
|
87
|
+
## Distributed locking
|
|
88
|
+
|
|
89
|
+
Use this to stop the same piece of work (typically a `@Cron()` handler)
|
|
90
|
+
running concurrently across multiple instances of a service.
|
|
91
|
+
|
|
92
|
+
### Programmatic: `DistributedLockService.runExclusive`
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
constructor(private readonly lockService: DistributedLockService) {}
|
|
96
|
+
|
|
97
|
+
@Cron('*/5 * * * *')
|
|
98
|
+
async syncJob() {
|
|
99
|
+
await this.lockService.runExclusive(
|
|
100
|
+
'sync-job',
|
|
101
|
+
async ({ signal }) => {
|
|
102
|
+
for (const item of items) {
|
|
103
|
+
if (signal.aborted) break; // lock could no longer be renewed
|
|
104
|
+
await process(item);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{ ttlMs: 30_000, autoExtend: true }, // autoExtend defaults to true
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- Returns `undefined` without invoking the callback when another instance
|
|
113
|
+
already holds the lock — the expected outcome on replicas that lose the
|
|
114
|
+
race for a given tick.
|
|
115
|
+
- With `autoExtend` (default `true`), the lock is renewed on an interval
|
|
116
|
+
(`ttlMs / 3` by default, or `extensionIntervalMs`) for as long as the
|
|
117
|
+
callback runs. If renewal ever falls behind the lock's real TTL, the
|
|
118
|
+
callback's `signal` is aborted so long-running work can check
|
|
119
|
+
`signal.aborted` and stop early instead of continuing to run without
|
|
120
|
+
exclusivity.
|
|
121
|
+
- `acquire`, `release`, and `extend` are also available individually for
|
|
122
|
+
manual lock management.
|
|
123
|
+
|
|
124
|
+
### Declarative: `@DistributedLockDecorator`
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { DistributedLockDecorator } from '@mondart/nestjs-common-module-caching';
|
|
128
|
+
|
|
129
|
+
@Cron('*/5 * * * *')
|
|
130
|
+
@DistributedLockDecorator({ key: 'sync-job', ttlMs: 30_000 })
|
|
131
|
+
async syncJob() { ... }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`key` can also be a function of the method's arguments, e.g.
|
|
135
|
+
`key: (tenantId: string) => \`sync-job:${tenantId}\`` to scope the lock per
|
|
136
|
+
call. This works on methods that Nest itself never routes through an
|
|
137
|
+
interceptor (like `@Cron()` handlers) because `DistributedLockExplorer`
|
|
138
|
+
wraps decorated methods directly at application bootstrap, rather than
|
|
139
|
+
relying on the request pipeline.
|
|
140
|
+
|
|
141
|
+
Both approaches share the same `DistributedLockService` under the hood, so
|
|
142
|
+
lock keys are namespaced the same way (`CachingModuleOptions.namespace`,
|
|
143
|
+
if set) regardless of which style you use.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.module.d.ts","sourceRoot":"","sources":["../src/caching.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,gBAAgB,CAAC;AAGzE,OAAO,EAEL,yBAAyB,EAEzB,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"caching.module.d.ts","sourceRoot":"","sources":["../src/caching.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,gBAAgB,CAAC;AAGzE,OAAO,EAEL,yBAAyB,EAEzB,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;AAQxC,qBAEa,aAAa;IAKxB,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa;IAuD7D,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,aAAa;IAoDvE,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAWzC,OAAO,CAAC,MAAM,CAAC,oBAAoB;CA2CpC"}
|
package/dist/caching.module.js
CHANGED
|
@@ -48,11 +48,14 @@ const caching_interface_1 = require("./interfaces/caching.interface");
|
|
|
48
48
|
const redis_1 = __importStar(require("@keyv/redis"));
|
|
49
49
|
const core_1 = require("@nestjs/core");
|
|
50
50
|
const caching_interceptor_1 = require("./interceptors/caching.interceptor");
|
|
51
|
+
const distributed_lock_service_1 = require("./services/distributed-lock.service");
|
|
52
|
+
const distributed_lock_explorer_1 = require("./explorers/distributed-lock.explorer");
|
|
51
53
|
let CachingModule = CachingModule_1 = class CachingModule {
|
|
52
54
|
static register(options) {
|
|
53
55
|
return {
|
|
54
56
|
module: CachingModule_1,
|
|
55
57
|
imports: [
|
|
58
|
+
core_1.DiscoveryModule,
|
|
56
59
|
cache_manager_1.CacheModule.register({
|
|
57
60
|
isGlobal: true,
|
|
58
61
|
useFactory: async (cachingOptions) => ({
|
|
@@ -88,8 +91,10 @@ let CachingModule = CachingModule_1 = class CachingModule {
|
|
|
88
91
|
useClass: caching_interceptor_1.CachingInterceptor,
|
|
89
92
|
},
|
|
90
93
|
caching_service_1.CachingService,
|
|
94
|
+
distributed_lock_service_1.DistributedLockService,
|
|
95
|
+
distributed_lock_explorer_1.DistributedLockExplorer,
|
|
91
96
|
],
|
|
92
|
-
exports: [caching_service_1.CachingService, cache_manager_1.CacheModule],
|
|
97
|
+
exports: [caching_service_1.CachingService, distributed_lock_service_1.DistributedLockService, cache_manager_1.CacheModule],
|
|
93
98
|
};
|
|
94
99
|
}
|
|
95
100
|
static registerAsync(options) {
|
|
@@ -97,6 +102,7 @@ let CachingModule = CachingModule_1 = class CachingModule {
|
|
|
97
102
|
return {
|
|
98
103
|
module: CachingModule_1,
|
|
99
104
|
imports: [
|
|
105
|
+
core_1.DiscoveryModule,
|
|
100
106
|
...(options.imports || []),
|
|
101
107
|
asyncOptionsProvider,
|
|
102
108
|
cache_manager_1.CacheModule.registerAsync({
|
|
@@ -131,8 +137,10 @@ let CachingModule = CachingModule_1 = class CachingModule {
|
|
|
131
137
|
useFactory: (cacheManager) => new caching_service_1.CachingService(cacheManager),
|
|
132
138
|
inject: [cache_manager_1.CACHE_MANAGER],
|
|
133
139
|
},
|
|
140
|
+
distributed_lock_service_1.DistributedLockService,
|
|
141
|
+
distributed_lock_explorer_1.DistributedLockExplorer,
|
|
134
142
|
],
|
|
135
|
-
exports: [caching_service_1.CachingService, cache_manager_1.CacheModule],
|
|
143
|
+
exports: [caching_service_1.CachingService, distributed_lock_service_1.DistributedLockService, cache_manager_1.CacheModule],
|
|
136
144
|
};
|
|
137
145
|
}
|
|
138
146
|
static createAsyncOptionsProvider(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.module.js","sourceRoot":"","sources":["../src/caching.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAyE;AACzE,gEAA4D;AAC5D,yDAAmE;AACnE,sEAKwC;AAExC,qDAAkE;AAClE,
|
|
1
|
+
{"version":3,"file":"caching.module.js","sourceRoot":"","sources":["../src/caching.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.const.d.ts","sourceRoot":"","sources":["../../src/constants/caching.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AACrE,eAAO,MAAM,2BAA2B,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"caching.const.d.ts","sourceRoot":"","sources":["../../src/constants/caching.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AACrE,eAAO,MAAM,2BAA2B,0BAA0B,CAAC;AACnE,eAAO,MAAM,oBAAoB,oBAAoB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.USE_CACHING_INTERCEPTOR_KEY = exports.SKIP_CACHING_INTERCEPTOR_KEY = void 0;
|
|
3
|
+
exports.DISTRIBUTED_LOCK_KEY = exports.USE_CACHING_INTERCEPTOR_KEY = exports.SKIP_CACHING_INTERCEPTOR_KEY = void 0;
|
|
4
4
|
exports.SKIP_CACHING_INTERCEPTOR_KEY = 'skipCachingInterceptor';
|
|
5
5
|
exports.USE_CACHING_INTERCEPTOR_KEY = 'useCachingInterceptor';
|
|
6
|
+
exports.DISTRIBUTED_LOCK_KEY = 'distributedLock';
|
|
6
7
|
//# sourceMappingURL=caching.const.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.const.js","sourceRoot":"","sources":["../../src/constants/caching.const.ts"],"names":[],"mappings":";;;AAAa,QAAA,4BAA4B,GAAG,wBAAwB,CAAC;AACxD,QAAA,2BAA2B,GAAG,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"caching.const.js","sourceRoot":"","sources":["../../src/constants/caching.const.ts"],"names":[],"mappings":";;;AAAa,QAAA,4BAA4B,GAAG,wBAAwB,CAAC;AACxD,QAAA,2BAA2B,GAAG,uBAAuB,CAAC;AACtD,QAAA,oBAAoB,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { DistributedLockMethodOptions } from '../interfaces/distributed-lock.interface';
|
|
2
|
+
export declare const DistributedLockDecorator: (options: DistributedLockMethodOptions) => import("@nestjs/common").CustomDecorator<string>;
|
|
3
|
+
//# sourceMappingURL=distributed-lock.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/distributed-lock.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AAkBxF,eAAO,MAAM,wBAAwB,GACnC,SAAS,4BAA4B,qDACQ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DistributedLockDecorator = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const caching_const_1 = require("../constants/caching.const");
|
|
6
|
+
const DistributedLockDecorator = (options) => (0, common_1.SetMetadata)(caching_const_1.DISTRIBUTED_LOCK_KEY, options);
|
|
7
|
+
exports.DistributedLockDecorator = DistributedLockDecorator;
|
|
8
|
+
//# sourceMappingURL=distributed-lock.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.decorator.js","sourceRoot":"","sources":["../../src/decorators/distributed-lock.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,8DAAkE;AAmB3D,MAAM,wBAAwB,GAAG,CACtC,OAAqC,EACrC,EAAE,CAAC,IAAA,oBAAW,EAAC,oCAAoB,EAAE,OAAO,CAAC,CAAC;AAFnC,QAAA,wBAAwB,4BAEW"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock-lost.error.d.ts","sourceRoot":"","sources":["../../src/errors/distributed-lock-lost.error.ts"],"names":[],"mappings":"AAAA,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAMxC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DistributedLockLostError = void 0;
|
|
4
|
+
class DistributedLockLostError extends Error {
|
|
5
|
+
constructor(key) {
|
|
6
|
+
super(`Distributed lock "${key}" was lost before the protected work finished`);
|
|
7
|
+
this.key = key;
|
|
8
|
+
this.name = 'DistributedLockLostError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.DistributedLockLostError = DistributedLockLostError;
|
|
12
|
+
//# sourceMappingURL=distributed-lock-lost.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock-lost.error.js","sourceRoot":"","sources":["../../src/errors/distributed-lock-lost.error.ts"],"names":[],"mappings":";;;AAAA,MAAa,wBAAyB,SAAQ,KAAK;IACjD,YAA4B,GAAW;QACrC,KAAK,CACH,qBAAqB,GAAG,+CAA+C,CACxE,CAAC;QAHwB,QAAG,GAAH,GAAG,CAAQ;QAIrC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAPD,4DAOC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { DiscoveryService, MetadataScanner, Reflector } from '@nestjs/core';
|
|
3
|
+
import { DistributedLockService } from '../services/distributed-lock.service';
|
|
4
|
+
export declare class DistributedLockExplorer implements OnModuleInit {
|
|
5
|
+
private readonly discoveryService;
|
|
6
|
+
private readonly metadataScanner;
|
|
7
|
+
private readonly reflector;
|
|
8
|
+
private readonly distributedLockService;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
constructor(discoveryService: DiscoveryService, metadataScanner: MetadataScanner, reflector: Reflector, distributedLockService: DistributedLockService);
|
|
11
|
+
onModuleInit(): void;
|
|
12
|
+
private wrapIfDecorated;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=distributed-lock.explorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.explorer.d.ts","sourceRoot":"","sources":["../../src/explorers/distributed-lock.explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAU9E,qBACa,uBAAwB,YAAW,YAAY;IAIxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IANzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;gBAGhD,gBAAgB,EAAE,gBAAgB,EAClC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,SAAS,EACpB,sBAAsB,EAAE,sBAAsB;IAGjE,YAAY,IAAI,IAAI;IAyBpB,OAAO,CAAC,eAAe;CAkCxB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var DistributedLockExplorer_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.DistributedLockExplorer = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const core_1 = require("@nestjs/core");
|
|
16
|
+
const caching_const_1 = require("../constants/caching.const");
|
|
17
|
+
const distributed_lock_service_1 = require("../services/distributed-lock.service");
|
|
18
|
+
let DistributedLockExplorer = DistributedLockExplorer_1 = class DistributedLockExplorer {
|
|
19
|
+
constructor(discoveryService, metadataScanner, reflector, distributedLockService) {
|
|
20
|
+
this.discoveryService = discoveryService;
|
|
21
|
+
this.metadataScanner = metadataScanner;
|
|
22
|
+
this.reflector = reflector;
|
|
23
|
+
this.distributedLockService = distributedLockService;
|
|
24
|
+
this.logger = new common_1.Logger(DistributedLockExplorer_1.name);
|
|
25
|
+
}
|
|
26
|
+
onModuleInit() {
|
|
27
|
+
const wrappers = [
|
|
28
|
+
...this.discoveryService.getProviders(),
|
|
29
|
+
...this.discoveryService.getControllers(),
|
|
30
|
+
];
|
|
31
|
+
for (const wrapper of wrappers) {
|
|
32
|
+
const instance = wrapper.instance;
|
|
33
|
+
if (!instance || typeof instance !== 'object') {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const prototype = Object.getPrototypeOf(instance);
|
|
37
|
+
if (!prototype) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
for (const methodName of this.metadataScanner.getAllMethodNames(prototype)) {
|
|
41
|
+
this.wrapIfDecorated(instance, prototype, methodName);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
wrapIfDecorated(instance, prototype, methodName) {
|
|
46
|
+
const originalMethod = instance[methodName];
|
|
47
|
+
if (typeof originalMethod !== 'function') {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const options = this.reflector.get(caching_const_1.DISTRIBUTED_LOCK_KEY, originalMethod);
|
|
51
|
+
if (!options) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const distributedLockService = this.distributedLockService;
|
|
55
|
+
instance[methodName] = function (...args) {
|
|
56
|
+
const key = typeof options.key === 'function' ? options.key(...args) : options.key;
|
|
57
|
+
return distributedLockService.runExclusive(key, () => originalMethod.apply(this, args), options);
|
|
58
|
+
};
|
|
59
|
+
this.logger.debug(`Wrapped ${prototype.constructor.name}.${methodName} with a distributed lock`);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
exports.DistributedLockExplorer = DistributedLockExplorer;
|
|
63
|
+
exports.DistributedLockExplorer = DistributedLockExplorer = DistributedLockExplorer_1 = __decorate([
|
|
64
|
+
(0, common_1.Injectable)(),
|
|
65
|
+
__metadata("design:paramtypes", [core_1.DiscoveryService,
|
|
66
|
+
core_1.MetadataScanner,
|
|
67
|
+
core_1.Reflector,
|
|
68
|
+
distributed_lock_service_1.DistributedLockService])
|
|
69
|
+
], DistributedLockExplorer);
|
|
70
|
+
//# sourceMappingURL=distributed-lock.explorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.explorer.js","sourceRoot":"","sources":["../../src/explorers/distributed-lock.explorer.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAkE;AAClE,uCAA4E;AAE5E,8DAAkE;AAElE,mFAA8E;AAWvE,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IAGlC,YACmB,gBAAkC,EAClC,eAAgC,EAChC,SAAoB,EACpB,sBAA8C;QAH9C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,oBAAe,GAAf,eAAe,CAAiB;QAChC,cAAS,GAAT,SAAS,CAAW;QACpB,2BAAsB,GAAtB,sBAAsB,CAAwB;QANhD,WAAM,GAAG,IAAI,eAAM,CAAC,yBAAuB,CAAC,IAAI,CAAC,CAAC;IAOhE,CAAC;IAEJ,YAAY;QACV,MAAM,QAAQ,GAAsB;YAClC,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE;YACvC,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE;SAC1C,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;YAClC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC9C,SAAS;YACX,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YAED,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAC7D,SAAS,CACV,EAAE,CAAC;gBACF,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CACrB,QAA6B,EAC7B,SAAiB,EACjB,UAAkB;QAElB,MAAM,cAAc,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAI,OAAO,cAAc,KAAK,UAAU,EAAE,CAAC;YACzC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAChC,oCAAoB,EACpB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,MAAM,sBAAsB,GAAG,IAAI,CAAC,sBAAsB,CAAC;QAC3D,QAAQ,CAAC,UAAU,CAAC,GAAG,UAAyB,GAAG,IAAe;YAChE,MAAM,GAAG,GACP,OAAO,OAAO,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;YAEzE,OAAO,sBAAsB,CAAC,YAAY,CACxC,GAAG,EACH,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EACtC,OAAO,CACR,CAAC;QACJ,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,WAAY,SAAS,CAAC,WAAgC,CAAC,IAAI,IAAI,UAAU,0BAA0B,CACpG,CAAC;IACJ,CAAC;CACF,CAAA;AArEY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAU,GAAE;qCAK0B,uBAAgB;QACjB,sBAAe;QACrB,gBAAS;QACI,iDAAsB;GAPtD,uBAAuB,CAqEnC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
export * from './caching.module';
|
|
2
2
|
export * from './services/caching.service';
|
|
3
|
+
export * from './services/distributed-lock.service';
|
|
3
4
|
export * from './interfaces/caching.interface';
|
|
5
|
+
export * from './interfaces/distributed-lock.interface';
|
|
4
6
|
export * from './interfaces/use-caching-interceptor-decorator-params.interface';
|
|
5
7
|
export * from './constants/caching.const';
|
|
6
8
|
export * from './decorators/use-caching-interceptor.decorator';
|
|
7
9
|
export * from './decorators/skip-caching-interceptor.decorator';
|
|
10
|
+
export * from './decorators/distributed-lock.decorator';
|
|
11
|
+
export * from './explorers/distributed-lock.explorer';
|
|
12
|
+
export * from './errors/distributed-lock-lost.error';
|
|
8
13
|
export * from './interceptors/caching.interceptor';
|
|
9
14
|
export * from './factories/caching-query-key.facroty';
|
|
10
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iEAAiE,CAAC;AAChF,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gDAAgD,CAAC;AAC/D,cAAc,iDAAiD,CAAC;AAChE,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yCAAyC,CAAC;AACxD,cAAc,iEAAiE,CAAC;AAChF,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gDAAgD,CAAC;AAC/D,cAAc,iDAAiD,CAAC;AAChE,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,sCAAsC,CAAC;AACrD,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,11 +16,16 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./caching.module"), exports);
|
|
18
18
|
__exportStar(require("./services/caching.service"), exports);
|
|
19
|
+
__exportStar(require("./services/distributed-lock.service"), exports);
|
|
19
20
|
__exportStar(require("./interfaces/caching.interface"), exports);
|
|
21
|
+
__exportStar(require("./interfaces/distributed-lock.interface"), exports);
|
|
20
22
|
__exportStar(require("./interfaces/use-caching-interceptor-decorator-params.interface"), exports);
|
|
21
23
|
__exportStar(require("./constants/caching.const"), exports);
|
|
22
24
|
__exportStar(require("./decorators/use-caching-interceptor.decorator"), exports);
|
|
23
25
|
__exportStar(require("./decorators/skip-caching-interceptor.decorator"), exports);
|
|
26
|
+
__exportStar(require("./decorators/distributed-lock.decorator"), exports);
|
|
27
|
+
__exportStar(require("./explorers/distributed-lock.explorer"), exports);
|
|
28
|
+
__exportStar(require("./errors/distributed-lock-lost.error"), exports);
|
|
24
29
|
__exportStar(require("./interceptors/caching.interceptor"), exports);
|
|
25
30
|
__exportStar(require("./factories/caching-query-key.facroty"), exports);
|
|
26
31
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,6DAA2C;AAC3C,iEAA+C;AAC/C,kGAAgF;AAChF,4DAA0C;AAC1C,iFAA+D;AAC/D,kFAAgE;AAChE,qEAAmD;AACnD,wEAAsD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,6DAA2C;AAC3C,sEAAoD;AACpD,iEAA+C;AAC/C,0EAAwD;AACxD,kGAAgF;AAChF,4DAA0C;AAC1C,iFAA+D;AAC/D,kFAAgE;AAChE,0EAAwD;AACxD,wEAAsD;AACtD,uEAAqD;AACrD,qEAAmD;AACnD,wEAAsD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface DistributedLockOptions {
|
|
2
|
+
ttlMs: number;
|
|
3
|
+
autoExtend?: boolean;
|
|
4
|
+
extensionIntervalMs?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface DistributedLock {
|
|
7
|
+
key: string;
|
|
8
|
+
token: string;
|
|
9
|
+
ttlMs: number;
|
|
10
|
+
}
|
|
11
|
+
export interface DistributedLockCallbackContext {
|
|
12
|
+
signal: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
export type DistributedLockCallback<T> = (context: DistributedLockCallbackContext) => Promise<T>;
|
|
15
|
+
export interface DistributedLockMethodOptions extends DistributedLockOptions {
|
|
16
|
+
key: string | ((...args: any[]) => string);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=distributed-lock.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/distributed-lock.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IAMd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,8BAA8B;IAM7C,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CACvC,OAAO,EAAE,8BAA8B,KACpC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEhB,MAAM,WAAW,4BAA6B,SAAQ,sBAAsB;IAK1E,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.interface.js","sourceRoot":"","sources":["../../src/interfaces/distributed-lock.interface.ts"],"names":[],"mappings":""}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Cache } from 'cache-manager';
|
|
2
|
-
import { Keyv } from '@keyv/redis';
|
|
2
|
+
import { Keyv, RedisClientConnectionType } from '@keyv/redis';
|
|
3
3
|
export declare class CachingService {
|
|
4
4
|
private cacheManager;
|
|
5
5
|
private readonly logger;
|
|
6
6
|
constructor(cacheManager: Cache);
|
|
7
7
|
getStore(): Keyv<any>;
|
|
8
|
+
getRedisClient(): Promise<RedisClientConnectionType>;
|
|
8
9
|
get<T>(key: string): Promise<T | undefined>;
|
|
9
10
|
getMany<T>(keys?: string[]): Promise<T[] | undefined>;
|
|
10
11
|
set<T>(key: string, value: T, ttlSeconds?: number): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.service.d.ts","sourceRoot":"","sources":["../../src/services/caching.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,
|
|
1
|
+
{"version":3,"file":"caching.service.d.ts","sourceRoot":"","sources":["../../src/services/caching.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAkB,EAAE,IAAI,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAEzE,qBACa,cAAc;IAIU,OAAO,CAAC,YAAY;IAHvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;gBACwC,YAAY,EAAE,KAAK;IAkB9D,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC;IAOf,cAAc,IAAI,OAAO,CAAC,yBAAyB,CAAC;IASpD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAc3C,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC;IAerD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAanE,OAAO,CAAC,CAAC,EACb,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,GACrD,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAapD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQlC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAOzC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAQzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAGpD"}
|
|
@@ -36,6 +36,10 @@ let CachingService = CachingService_1 = class CachingService {
|
|
|
36
36
|
getStore() {
|
|
37
37
|
return this.cacheManager.stores?.[0];
|
|
38
38
|
}
|
|
39
|
+
async getRedisClient() {
|
|
40
|
+
const redisStore = this.getStore().opts.store;
|
|
41
|
+
return redisStore.getClient();
|
|
42
|
+
}
|
|
39
43
|
async get(key) {
|
|
40
44
|
const result = await this.cacheManager.get(key);
|
|
41
45
|
if (result) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caching.service.js","sourceRoot":"","sources":["../../src/services/caching.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAA4D;AAC5D,yDAAsD;AAEtD,
|
|
1
|
+
{"version":3,"file":"caching.service.js","sourceRoot":"","sources":["../../src/services/caching.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CachingModuleOptions } from '../interfaces/caching.interface';
|
|
2
|
+
import { DistributedLock, DistributedLockCallback, DistributedLockOptions } from '../interfaces/distributed-lock.interface';
|
|
3
|
+
import { CachingService } from './caching.service';
|
|
4
|
+
export declare class DistributedLockService {
|
|
5
|
+
private readonly cachingService;
|
|
6
|
+
private readonly cachingOptions;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
constructor(cachingService: CachingService, cachingOptions: CachingModuleOptions);
|
|
9
|
+
acquire(key: string, ttlMs: number): Promise<DistributedLock | null>;
|
|
10
|
+
release(lock: DistributedLock): Promise<boolean>;
|
|
11
|
+
extend(lock: DistributedLock, ttlMs?: number): Promise<boolean>;
|
|
12
|
+
runExclusive<T>(key: string, callback: DistributedLockCallback<T>, options: DistributedLockOptions): Promise<T | undefined>;
|
|
13
|
+
private startExtension;
|
|
14
|
+
private getNamespacedKey;
|
|
15
|
+
private validateTtl;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=distributed-lock.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.service.d.ts","sourceRoot":"","sources":["../../src/services/distributed-lock.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgBnD,qBACa,sBAAsB;IAM/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAPjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;gBAGgB,cAAc,EAAE,cAAc,EAE9B,cAAc,EAAE,oBAAoB;IAUjD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAwBpE,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBhD,MAAM,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,SAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BnE,YAAY,CAAC,CAAC,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC,EACpC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IA4DzB,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,WAAW;CAKpB"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var DistributedLockService_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.DistributedLockService = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const crypto_1 = require("crypto");
|
|
19
|
+
const caching_interface_1 = require("../interfaces/caching.interface");
|
|
20
|
+
const distributed_lock_lost_error_1 = require("../errors/distributed-lock-lost.error");
|
|
21
|
+
const caching_service_1 = require("./caching.service");
|
|
22
|
+
const RELEASE_SCRIPT = `
|
|
23
|
+
if redis.call('get', KEYS[1]) == ARGV[1] then
|
|
24
|
+
return redis.call('del', KEYS[1])
|
|
25
|
+
end
|
|
26
|
+
return 0
|
|
27
|
+
`;
|
|
28
|
+
const EXTEND_SCRIPT = `
|
|
29
|
+
if redis.call('get', KEYS[1]) == ARGV[1] then
|
|
30
|
+
return redis.call('pexpire', KEYS[1], ARGV[2])
|
|
31
|
+
end
|
|
32
|
+
return 0
|
|
33
|
+
`;
|
|
34
|
+
let DistributedLockService = DistributedLockService_1 = class DistributedLockService {
|
|
35
|
+
constructor(cachingService, cachingOptions) {
|
|
36
|
+
this.cachingService = cachingService;
|
|
37
|
+
this.cachingOptions = cachingOptions;
|
|
38
|
+
this.logger = new common_1.Logger(DistributedLockService_1.name, {
|
|
39
|
+
timestamp: true,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async acquire(key, ttlMs) {
|
|
43
|
+
this.validateTtl(ttlMs);
|
|
44
|
+
if (!key.trim()) {
|
|
45
|
+
throw new Error('Distributed lock key must not be empty');
|
|
46
|
+
}
|
|
47
|
+
const namespacedKey = this.getNamespacedKey(key);
|
|
48
|
+
const token = (0, crypto_1.randomUUID)();
|
|
49
|
+
const redis = await this.cachingService.getRedisClient();
|
|
50
|
+
const result = await redis.set(namespacedKey, token, {
|
|
51
|
+
PX: ttlMs,
|
|
52
|
+
NX: true,
|
|
53
|
+
});
|
|
54
|
+
return result === 'OK' ? { key: namespacedKey, token, ttlMs } : null;
|
|
55
|
+
}
|
|
56
|
+
async release(lock) {
|
|
57
|
+
const redis = await this.cachingService.getRedisClient();
|
|
58
|
+
const result = await redis.eval(RELEASE_SCRIPT, {
|
|
59
|
+
keys: [lock.key],
|
|
60
|
+
arguments: [lock.token],
|
|
61
|
+
});
|
|
62
|
+
return Number(result) === 1;
|
|
63
|
+
}
|
|
64
|
+
async extend(lock, ttlMs = lock.ttlMs) {
|
|
65
|
+
this.validateTtl(ttlMs);
|
|
66
|
+
const redis = await this.cachingService.getRedisClient();
|
|
67
|
+
const result = await redis.eval(EXTEND_SCRIPT, {
|
|
68
|
+
keys: [lock.key],
|
|
69
|
+
arguments: [lock.token, String(ttlMs)],
|
|
70
|
+
});
|
|
71
|
+
if (Number(result) === 1) {
|
|
72
|
+
lock.ttlMs = ttlMs;
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
async runExclusive(key, callback, options) {
|
|
78
|
+
const lock = await this.acquire(key, options.ttlMs);
|
|
79
|
+
if (!lock) {
|
|
80
|
+
this.logger.debug(`Skipped "${key}": lock is already held by another instance`);
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const autoExtend = options.autoExtend ?? true;
|
|
84
|
+
const abortController = new AbortController();
|
|
85
|
+
let extensionInterval;
|
|
86
|
+
let workError;
|
|
87
|
+
let releaseError;
|
|
88
|
+
let result;
|
|
89
|
+
try {
|
|
90
|
+
extensionInterval = autoExtend
|
|
91
|
+
? this.startExtension(lock, abortController, options.extensionIntervalMs)
|
|
92
|
+
: undefined;
|
|
93
|
+
result = await callback({ signal: abortController.signal });
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
workError = error;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
if (extensionInterval) {
|
|
100
|
+
clearInterval(extensionInterval);
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
await this.release(lock);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
releaseError = error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (releaseError) {
|
|
110
|
+
this.logger.error(`Failed to release distributed lock "${lock.key}": ${releaseError.message}`);
|
|
111
|
+
}
|
|
112
|
+
if (workError) {
|
|
113
|
+
throw workError;
|
|
114
|
+
}
|
|
115
|
+
if (releaseError) {
|
|
116
|
+
throw releaseError;
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
startExtension(lock, abortController, configuredInterval) {
|
|
121
|
+
const intervalMs = configuredInterval ?? Math.max(100, Math.floor(lock.ttlMs / 3));
|
|
122
|
+
if (intervalMs <= 0 || intervalMs >= lock.ttlMs) {
|
|
123
|
+
throw new Error('Lock extension interval must be positive and shorter than its TTL');
|
|
124
|
+
}
|
|
125
|
+
let deadline = Date.now() + lock.ttlMs;
|
|
126
|
+
return setInterval(() => {
|
|
127
|
+
void this.extend(lock)
|
|
128
|
+
.then((extended) => {
|
|
129
|
+
if (extended) {
|
|
130
|
+
deadline = Date.now() + lock.ttlMs;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this.logger.warn(`Distributed lock "${lock.key}" is no longer owned by this instance`);
|
|
134
|
+
abortController.abort(new distributed_lock_lost_error_1.DistributedLockLostError(lock.key));
|
|
135
|
+
})
|
|
136
|
+
.catch((error) => {
|
|
137
|
+
this.logger.warn(`Failed to extend distributed lock "${lock.key}": ${error.message}`);
|
|
138
|
+
if (Date.now() >= deadline) {
|
|
139
|
+
this.logger.error(`Distributed lock "${lock.key}" expired while work was still running`);
|
|
140
|
+
abortController.abort(new distributed_lock_lost_error_1.DistributedLockLostError(lock.key));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}, intervalMs).unref();
|
|
144
|
+
}
|
|
145
|
+
getNamespacedKey(key) {
|
|
146
|
+
const namespace = this.cachingOptions.namespace?.replace(/:+$/, '');
|
|
147
|
+
return namespace ? `${namespace}:${key}` : key;
|
|
148
|
+
}
|
|
149
|
+
validateTtl(ttlMs) {
|
|
150
|
+
if (!Number.isInteger(ttlMs) || ttlMs <= 0) {
|
|
151
|
+
throw new Error('Distributed lock TTL must be a positive integer');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
exports.DistributedLockService = DistributedLockService;
|
|
156
|
+
exports.DistributedLockService = DistributedLockService = DistributedLockService_1 = __decorate([
|
|
157
|
+
(0, common_1.Injectable)(),
|
|
158
|
+
__param(1, (0, common_1.Inject)(caching_interface_1.CACHING_MODULE_OPTIONS)),
|
|
159
|
+
__metadata("design:paramtypes", [caching_service_1.CachingService, Object])
|
|
160
|
+
], DistributedLockService);
|
|
161
|
+
//# sourceMappingURL=distributed-lock.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distributed-lock.service.js","sourceRoot":"","sources":["../../src/services/distributed-lock.service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mondart/nestjs-common-module-caching",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "Caching module for NestJS.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mondart"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"build": "tsc -p tsconfig.json"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@mondart/nestjs-common-module-core": "^3.2.
|
|
20
|
+
"@mondart/nestjs-common-module-core": "^3.2.6",
|
|
21
21
|
"@keyv/redis": "4.2.0",
|
|
22
22
|
"@nestjs/cache-manager": "^3.0.0",
|
|
23
23
|
"cache-manager": "6.4.0",
|