@nest-omni/core 4.1.3-0 → 4.1.3-10
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/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +15 -0
- package/audit/controllers/audit.controller.d.ts +24 -0
- package/audit/controllers/audit.controller.js +24 -0
- package/audit/decorators/audit-controller.decorator.d.ts +8 -0
- package/audit/decorators/audit-controller.decorator.js +9 -0
- package/audit/decorators/audit-operation.decorator.d.ts +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -0
- package/audit/decorators/entity-audit.decorator.d.ts +8 -0
- package/audit/decorators/entity-audit.decorator.js +9 -0
- package/audit/dto/audit-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/entity-audit-log.entity.d.ts +3 -0
- package/audit/entities/entity-audit-log.entity.js +3 -0
- package/audit/entities/entity-transaction.entity.d.ts +3 -0
- package/audit/entities/entity-transaction.entity.js +3 -0
- package/audit/entities/manual-operation-log.entity.d.ts +4 -0
- package/audit/entities/manual-operation-log.entity.js +4 -0
- package/audit/entities/operation-template.entity.d.ts +4 -0
- package/audit/entities/operation-template.entity.js +4 -0
- package/audit/enums/audit.enums.d.ts +17 -2
- package/audit/enums/audit.enums.js +15 -0
- package/audit/index.js +10 -0
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +42 -0
- package/audit/services/audit-context.service.d.ts +15 -0
- package/audit/services/audit-context.service.js +15 -0
- package/audit/services/audit-strategy.service.d.ts +6 -0
- package/audit/services/audit-strategy.service.js +13 -0
- package/audit/services/entity-audit.service.d.ts +57 -0
- package/audit/services/entity-audit.service.js +91 -0
- package/audit/services/manual-audit-log.service.d.ts +124 -0
- package/audit/services/manual-audit-log.service.js +138 -0
- package/audit/services/multi-database.service.d.ts +12 -0
- package/audit/services/multi-database.service.js +12 -0
- package/audit/services/operation-description.service.d.ts +59 -0
- package/audit/services/operation-description.service.js +76 -2
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +47 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
- package/audit/subscribers/entity-audit.subscriber.js +29 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +86 -0
- package/cache/cache.module.js +71 -0
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +157 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +45 -0
- package/cache/dependencies/db.dependency.js +48 -1
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +36 -0
- package/cache/dependencies/tag.dependency.js +36 -0
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- package/cache/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +81 -0
- package/cache/interfaces/cache-options.interface.js +6 -0
- package/cache/interfaces/cache-provider.interface.d.ts +78 -0
- package/cache/providers/base-cache.provider.d.ts +14 -0
- package/cache/providers/base-cache.provider.js +16 -0
- package/cache/providers/cls-cache.provider.d.ts +20 -0
- package/cache/providers/cls-cache.provider.js +28 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +26 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -4
- package/common/boilerplate.polyfill.js +24 -131
- package/common/dto/dto-container.d.ts +16 -0
- package/common/dto/dto-container.js +20 -0
- package/common/dto/dto-decorators.d.ts +18 -0
- package/common/dto/dto-decorators.js +14 -0
- package/common/dto/dto-extensions.d.ts +11 -0
- package/common/dto/dto-extensions.js +9 -0
- package/common/dto/dto-service-accessor.d.ts +17 -0
- package/common/dto/dto-service-accessor.js +18 -0
- package/common/dto/dto-transformer.d.ts +12 -0
- package/common/dto/dto-transformer.js +9 -0
- package/common/dto/index.js +2 -0
- package/common/examples/paginate-and-map.example.d.ts +6 -0
- package/common/examples/paginate-and-map.example.js +26 -0
- package/common/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/filters/constraint-errors.js +1 -0
- package/helpers/common.helper.d.ts +13 -0
- package/helpers/common.helper.js +13 -0
- package/http-client/config/http-client.config.d.ts +15 -0
- package/http-client/config/http-client.config.js +25 -9
- package/http-client/decorators/http-client.decorators.d.ts +63 -0
- package/http-client/decorators/http-client.decorators.js +71 -3
- package/http-client/entities/http-log.entity.d.ts +229 -0
- package/http-client/entities/http-log.entity.js +6 -1
- package/http-client/errors/http-client.errors.d.ts +57 -0
- package/http-client/errors/http-client.errors.js +58 -0
- package/http-client/examples/advanced-usage.example.d.ts +41 -0
- package/http-client/examples/advanced-usage.example.js +68 -24
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
- package/http-client/examples/basic-usage.example.d.ts +60 -0
- package/http-client/examples/basic-usage.example.js +60 -0
- package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
- package/http-client/examples/multi-api-configuration.example.js +76 -5
- package/http-client/http-client.module.d.ts +13 -0
- package/http-client/http-client.module.js +19 -0
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
- package/http-client/services/api-client-registry.service.d.ts +57 -0
- package/http-client/services/api-client-registry.service.js +84 -1
- package/http-client/services/cache.service.d.ts +52 -0
- package/http-client/services/cache.service.js +72 -3
- package/http-client/services/circuit-breaker.service.d.ts +46 -0
- package/http-client/services/circuit-breaker.service.js +52 -0
- package/http-client/services/http-client.service.d.ts +67 -0
- package/http-client/services/http-client.service.js +105 -4
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +122 -1
- package/http-client/services/http-replay.service.d.ts +101 -0
- package/http-client/services/http-replay.service.js +86 -0
- package/http-client/services/log-cleanup.service.d.ts +63 -0
- package/http-client/services/log-cleanup.service.js +54 -2
- package/http-client/services/logging.service.d.ts +40 -0
- package/http-client/services/logging.service.js +53 -0
- package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
- package/http-client/utils/call-stack-extractor.util.js +48 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/request-id.util.d.ts +18 -0
- package/http-client/utils/request-id.util.js +20 -0
- package/http-client/utils/retry-recorder.util.d.ts +42 -0
- package/http-client/utils/retry-recorder.util.js +44 -0
- package/i18n/en_US/validation.json +2 -1
- package/i18n/zh_CN/validation.json +2 -1
- package/index.js +8 -0
- package/interceptors/translation-interceptor.service.js +5 -0
- package/package.json +1 -1
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
- package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.d.ts +2 -0
- package/redis-lock/index.js +8 -1
- package/redis-lock/lock-heartbeat.service.d.ts +78 -0
- package/redis-lock/lock-heartbeat.service.js +222 -0
- package/redis-lock/redis-lock.decorator.d.ts +101 -0
- package/redis-lock/redis-lock.decorator.js +120 -0
- package/redis-lock/redis-lock.module.d.ts +66 -0
- package/redis-lock/redis-lock.module.js +175 -70
- package/redis-lock/redis-lock.service.d.ts +260 -0
- package/redis-lock/redis-lock.service.js +244 -4
- package/setup/bootstrap.setup.js +20 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -0
- package/setup/schedule.decorator.d.ts +227 -0
- package/setup/schedule.decorator.js +219 -6
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +9 -1
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +20 -9
- package/validator-json/decorators.d.ts +17 -0
- package/validator-json/decorators.js +17 -2
- package/validator-json/default.d.ts +6 -0
- package/validator-json/default.js +30 -2
- package/validator-json/defaultConverters.js +1 -0
- package/validator-json/options.d.ts +23 -0
- package/validators/common-validators.d.ts +143 -0
- package/validators/common-validators.js +249 -0
- package/validators/custom-validate.examples.d.ts +96 -0
- package/validators/custom-validate.examples.js +400 -0
- package/validators/custom-validate.validator.d.ts +134 -0
- package/validators/custom-validate.validator.js +214 -0
- package/validators/index.d.ts +2 -0
- package/validators/index.js +2 -0
- package/validators/is-exists.validator.d.ts +18 -4
- package/validators/is-exists.validator.js +67 -6
- package/validators/is-unique.validator.d.ts +32 -5
- package/validators/is-unique.validator.js +99 -17
- package/validators/skip-empty.validator.d.ts +5 -0
- package/validators/skip-empty.validator.js +5 -0
- package/vault/interfaces/vault-options.interface.d.ts +9 -0
- package/vault/vault-config.loader.d.ts +30 -0
- package/vault/vault-config.loader.js +48 -1
- package/vault/vault-config.service.d.ts +53 -0
- package/vault/vault-config.service.js +57 -0
- package/vault/vault.module.d.ts +4 -0
- package/vault/vault.module.js +4 -0
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
|
@@ -21,39 +21,93 @@ var RedisLockService_1;
|
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.RedisLockService = exports.LockStrategy = void 0;
|
|
23
23
|
const common_1 = require("@nestjs/common");
|
|
24
|
+
/**
|
|
25
|
+
* Lock acquisition strategy
|
|
26
|
+
*/
|
|
24
27
|
var LockStrategy;
|
|
25
28
|
(function (LockStrategy) {
|
|
29
|
+
/**
|
|
30
|
+
* Skip execution if lock cannot be acquired immediately
|
|
31
|
+
* This is the default behavior for backward compatibility
|
|
32
|
+
*/
|
|
26
33
|
LockStrategy["SKIP"] = "SKIP";
|
|
34
|
+
/**
|
|
35
|
+
* Throw an error if lock cannot be acquired
|
|
36
|
+
* Useful for critical operations that must have exclusive access
|
|
37
|
+
*/
|
|
27
38
|
LockStrategy["THROW"] = "THROW";
|
|
39
|
+
/**
|
|
40
|
+
* Wait/block until the lock can be acquired
|
|
41
|
+
* Will retry indefinitely with the specified retry delay
|
|
42
|
+
*/
|
|
28
43
|
LockStrategy["WAIT"] = "WAIT";
|
|
29
44
|
})(LockStrategy || (exports.LockStrategy = LockStrategy = {}));
|
|
45
|
+
/**
|
|
46
|
+
* Redis-based distributed lock service
|
|
47
|
+
*
|
|
48
|
+
* Provides thread-safe, distributed locking mechanism using Redis.
|
|
49
|
+
* Supports automatic lock expiration, retries, proper lock release,
|
|
50
|
+
* and automatic lock extension.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* constructor(private lockService: RedisLockService) {}
|
|
55
|
+
*
|
|
56
|
+
* async processTask() {
|
|
57
|
+
* const result = await this.lockService.acquireLock('task:process', { ttl: 60000 });
|
|
58
|
+
*
|
|
59
|
+
* if (result.acquired) {
|
|
60
|
+
* try {
|
|
61
|
+
* // Do work
|
|
62
|
+
* } finally {
|
|
63
|
+
* await this.lockService.releaseLock('task:process', result.lockValue);
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
30
69
|
let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
31
70
|
constructor() {
|
|
32
71
|
this.logger = new common_1.Logger(RedisLockService_1.name);
|
|
33
72
|
this.redis = null;
|
|
34
73
|
this.defaultOptions = {
|
|
35
|
-
ttl: 300000,
|
|
74
|
+
ttl: 300000, // 5 minutes
|
|
36
75
|
retryCount: 0,
|
|
37
76
|
retryDelay: 100,
|
|
38
77
|
keyPrefix: 'lock',
|
|
39
78
|
throwOnFailure: false,
|
|
40
79
|
strategy: LockStrategy.SKIP,
|
|
41
80
|
waitTimeout: undefined,
|
|
42
|
-
autoExtend: 0,
|
|
81
|
+
autoExtend: 0, // No auto-extension by default
|
|
43
82
|
};
|
|
83
|
+
// Set global instance when created
|
|
44
84
|
if (!RedisLockService_1.globalInstance) {
|
|
45
85
|
RedisLockService_1.globalInstance = this;
|
|
46
86
|
}
|
|
87
|
+
// Initialize instance ID
|
|
88
|
+
this.instanceId = this.getInstanceId();
|
|
47
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Get the global singleton instance
|
|
92
|
+
* This allows decorators to access the service without dependency injection
|
|
93
|
+
*/
|
|
48
94
|
static getGlobalInstance() {
|
|
49
95
|
return RedisLockService_1.globalInstance;
|
|
50
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Get or create the global singleton instance
|
|
99
|
+
* If no instance exists, it will create one
|
|
100
|
+
*/
|
|
51
101
|
static getOrCreateGlobalInstance() {
|
|
52
102
|
if (!RedisLockService_1.globalInstance) {
|
|
53
103
|
RedisLockService_1.globalInstance = new RedisLockService_1();
|
|
54
104
|
}
|
|
55
105
|
return RedisLockService_1.globalInstance;
|
|
56
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Set the global singleton instance
|
|
109
|
+
* Useful for testing or manual setup
|
|
110
|
+
*/
|
|
57
111
|
static setGlobalInstance(instance) {
|
|
58
112
|
RedisLockService_1.globalInstance = instance;
|
|
59
113
|
}
|
|
@@ -69,37 +123,64 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
69
123
|
}
|
|
70
124
|
onModuleDestroy() {
|
|
71
125
|
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
// We don't manage the Redis connection lifecycle anymore
|
|
127
|
+
// The injected Redis client is managed by the Redis module
|
|
72
128
|
this.logger.log('RedisLockService destroyed');
|
|
73
129
|
});
|
|
74
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Set Redis client (required for dependency injection)
|
|
133
|
+
* This service requires an external Redis client to function
|
|
134
|
+
*/
|
|
75
135
|
setRedisClient(redis) {
|
|
76
136
|
this.redis = redis;
|
|
77
137
|
this.logger.log('Redis client set for RedisLockService');
|
|
78
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Set default TTL for locks
|
|
141
|
+
*/
|
|
79
142
|
setDefaultTtl(ttl) {
|
|
80
143
|
this.defaultOptions.ttl = ttl;
|
|
81
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Set default key prefix for locks
|
|
147
|
+
*/
|
|
82
148
|
setDefaultKeyPrefix(prefix) {
|
|
83
149
|
this.defaultOptions.keyPrefix = prefix;
|
|
84
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Set default retry count for lock acquisition
|
|
153
|
+
*/
|
|
85
154
|
setDefaultRetryCount(count) {
|
|
86
155
|
this.defaultOptions.retryCount = count;
|
|
87
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Set default retry delay for lock acquisition
|
|
159
|
+
*/
|
|
88
160
|
setDefaultRetryDelay(delay) {
|
|
89
161
|
this.defaultOptions.retryDelay = delay;
|
|
90
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Acquire a distributed lock
|
|
165
|
+
*
|
|
166
|
+
* @param key - Lock key (will be prefixed with 'lock:')
|
|
167
|
+
* @param options - Lock options
|
|
168
|
+
* @returns Lock acquisition result
|
|
169
|
+
*/
|
|
91
170
|
acquireLock(key_1) {
|
|
92
171
|
return __awaiter(this, arguments, void 0, function* (key, options = {}) {
|
|
93
172
|
const redis = yield this.getRedis();
|
|
94
173
|
const opts = Object.assign(Object.assign({}, this.defaultOptions), options);
|
|
174
|
+
// Handle backward compatibility: if throwOnFailure is true, use THROW strategy
|
|
95
175
|
if (opts.throwOnFailure && !options.strategy) {
|
|
96
176
|
opts.strategy = LockStrategy.THROW;
|
|
97
177
|
}
|
|
98
178
|
const lockKey = this.buildLockKey(key, opts.keyPrefix);
|
|
99
179
|
const lockValue = this.generateLockValue();
|
|
180
|
+
// Determine max attempts based on strategy
|
|
100
181
|
let maxAttempts;
|
|
101
182
|
if (opts.strategy === LockStrategy.WAIT) {
|
|
102
|
-
maxAttempts = Number.MAX_SAFE_INTEGER;
|
|
183
|
+
maxAttempts = Number.MAX_SAFE_INTEGER; // Infinite retries for WAIT strategy
|
|
103
184
|
}
|
|
104
185
|
else {
|
|
105
186
|
maxAttempts = opts.retryCount + 1;
|
|
@@ -107,6 +188,7 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
107
188
|
let attempts = 0;
|
|
108
189
|
const startTime = Date.now();
|
|
109
190
|
while (attempts < maxAttempts) {
|
|
191
|
+
// Check timeout for WAIT strategy
|
|
110
192
|
if (opts.strategy === LockStrategy.WAIT && opts.waitTimeout) {
|
|
111
193
|
const elapsed = Date.now() - startTime;
|
|
112
194
|
if (elapsed >= opts.waitTimeout) {
|
|
@@ -116,9 +198,11 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
116
198
|
}
|
|
117
199
|
}
|
|
118
200
|
try {
|
|
201
|
+
// Use SET with NX (Not eXists) and PX (expiration in milliseconds)
|
|
119
202
|
const result = yield redis.set(lockKey, lockValue, 'PX', opts.ttl, 'NX');
|
|
120
203
|
if (result === 'OK') {
|
|
121
204
|
this.logger.debug(`Lock acquired: ${lockKey} (value: ${lockValue}, ttl: ${opts.ttl}ms, attempts: ${attempts + 1})`);
|
|
205
|
+
// Set up auto-extension if enabled
|
|
122
206
|
let autoExtendTimer;
|
|
123
207
|
if (opts.autoExtend && opts.autoExtend > 0) {
|
|
124
208
|
autoExtendTimer = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -132,7 +216,9 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
132
216
|
}
|
|
133
217
|
return { acquired: true, lockValue, autoExtendTimer };
|
|
134
218
|
}
|
|
219
|
+
// Lock acquisition failed
|
|
135
220
|
attempts++;
|
|
221
|
+
// For WAIT strategy, log less frequently to avoid spam
|
|
136
222
|
if (opts.strategy === LockStrategy.WAIT) {
|
|
137
223
|
if (attempts === 1 || attempts % 10 === 0) {
|
|
138
224
|
this.logger.debug(`Waiting for lock ${lockKey}... (attempt ${attempts})`);
|
|
@@ -141,6 +227,7 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
141
227
|
else if (attempts < maxAttempts) {
|
|
142
228
|
this.logger.debug(`Lock acquisition failed for ${lockKey}, retrying... (${attempts}/${opts.retryCount})`);
|
|
143
229
|
}
|
|
230
|
+
// Wait before next attempt (except for last attempt)
|
|
144
231
|
if (attempts < maxAttempts) {
|
|
145
232
|
yield this.sleep(opts.retryDelay);
|
|
146
233
|
}
|
|
@@ -154,6 +241,7 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
154
241
|
return { acquired: false, error: errorMessage };
|
|
155
242
|
}
|
|
156
243
|
}
|
|
244
|
+
// Max attempts reached
|
|
157
245
|
const failureMessage = `Failed to acquire lock for ${lockKey} after ${attempts} attempts`;
|
|
158
246
|
this.logger.warn(failureMessage);
|
|
159
247
|
if (opts.strategy === LockStrategy.THROW) {
|
|
@@ -162,11 +250,23 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
162
250
|
return { acquired: false, error: failureMessage };
|
|
163
251
|
});
|
|
164
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Release a distributed lock
|
|
255
|
+
*
|
|
256
|
+
* Uses Lua script to ensure atomic check-and-delete operation
|
|
257
|
+
* Only releases the lock if the value matches (prevents releasing someone else's lock)
|
|
258
|
+
*
|
|
259
|
+
* @param key - Lock key
|
|
260
|
+
* @param lockValue - Lock value obtained during acquisition
|
|
261
|
+
* @param keyPrefix - Key prefix (must match acquisition)
|
|
262
|
+
* @returns True if lock was released, false otherwise
|
|
263
|
+
*/
|
|
165
264
|
releaseLock(key_1, lockValue_1) {
|
|
166
265
|
return __awaiter(this, arguments, void 0, function* (key, lockValue, keyPrefix = 'lock') {
|
|
167
266
|
const redis = yield this.getRedis();
|
|
168
267
|
const lockKey = this.buildLockKey(key, keyPrefix);
|
|
169
268
|
try {
|
|
269
|
+
// Lua script to atomically check and delete the lock
|
|
170
270
|
const script = `
|
|
171
271
|
if redis.call("get", KEYS[1]) == ARGV[1] then
|
|
172
272
|
return redis.call("del", KEYS[1])
|
|
@@ -190,11 +290,21 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
190
290
|
}
|
|
191
291
|
});
|
|
192
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Extend the expiration time of an existing lock
|
|
295
|
+
*
|
|
296
|
+
* @param key - Lock key
|
|
297
|
+
* @param lockValue - Lock value obtained during acquisition
|
|
298
|
+
* @param ttl - New TTL in milliseconds
|
|
299
|
+
* @param keyPrefix - Key prefix (must match acquisition)
|
|
300
|
+
* @returns True if lock was extended, false otherwise
|
|
301
|
+
*/
|
|
193
302
|
extendLock(key_1, lockValue_1, ttl_1) {
|
|
194
303
|
return __awaiter(this, arguments, void 0, function* (key, lockValue, ttl, keyPrefix = 'lock') {
|
|
195
304
|
const redis = yield this.getRedis();
|
|
196
305
|
const lockKey = this.buildLockKey(key, keyPrefix);
|
|
197
306
|
try {
|
|
307
|
+
// Lua script to atomically check value and extend TTL
|
|
198
308
|
const script = `
|
|
199
309
|
if redis.call("get", KEYS[1]) == ARGV[1] then
|
|
200
310
|
return redis.call("pexpire", KEYS[1], ARGV[2])
|
|
@@ -218,6 +328,13 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
218
328
|
}
|
|
219
329
|
});
|
|
220
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Check if a lock exists
|
|
333
|
+
*
|
|
334
|
+
* @param key - Lock key
|
|
335
|
+
* @param keyPrefix - Key prefix
|
|
336
|
+
* @returns True if lock exists, false otherwise
|
|
337
|
+
*/
|
|
221
338
|
isLocked(key_1) {
|
|
222
339
|
return __awaiter(this, arguments, void 0, function* (key, keyPrefix = 'lock') {
|
|
223
340
|
const redis = yield this.getRedis();
|
|
@@ -232,6 +349,14 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
232
349
|
}
|
|
233
350
|
});
|
|
234
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Execute a function with automatic lock acquisition and release
|
|
354
|
+
*
|
|
355
|
+
* @param key - Lock key
|
|
356
|
+
* @param fn - Function to execute while holding the lock
|
|
357
|
+
* @param options - Lock options
|
|
358
|
+
* @returns Result of the function execution, or null if lock couldn't be acquired
|
|
359
|
+
*/
|
|
235
360
|
withLock(key_1, fn_1) {
|
|
236
361
|
return __awaiter(this, arguments, void 0, function* (key, fn, options = {}) {
|
|
237
362
|
const lockResult = yield this.acquireLock(key, options);
|
|
@@ -247,6 +372,7 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
247
372
|
throw error;
|
|
248
373
|
}
|
|
249
374
|
finally {
|
|
375
|
+
// Clear auto-extension timer if it exists
|
|
250
376
|
if (lockResult.autoExtendTimer) {
|
|
251
377
|
clearInterval(lockResult.autoExtendTimer);
|
|
252
378
|
}
|
|
@@ -254,6 +380,13 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
254
380
|
}
|
|
255
381
|
});
|
|
256
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Get lock information from Redis
|
|
385
|
+
*
|
|
386
|
+
* @param key - Lock key
|
|
387
|
+
* @param keyPrefix - Key prefix
|
|
388
|
+
* @returns Lock information including TTL and value
|
|
389
|
+
*/
|
|
257
390
|
getLockInfo(key_1) {
|
|
258
391
|
return __awaiter(this, arguments, void 0, function* (key, keyPrefix = 'lock') {
|
|
259
392
|
const redis = yield this.getRedis();
|
|
@@ -274,6 +407,13 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
274
407
|
}
|
|
275
408
|
});
|
|
276
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* Force release a lock (use with caution)
|
|
412
|
+
*
|
|
413
|
+
* @param key - Lock key
|
|
414
|
+
* @param keyPrefix - Key prefix
|
|
415
|
+
* @returns True if lock was released, false otherwise
|
|
416
|
+
*/
|
|
277
417
|
forceRelease(key_1) {
|
|
278
418
|
return __awaiter(this, arguments, void 0, function* (key, keyPrefix = 'lock') {
|
|
279
419
|
const redis = yield this.getRedis();
|
|
@@ -295,6 +435,25 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
295
435
|
}
|
|
296
436
|
});
|
|
297
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* Clean up locks by pattern
|
|
440
|
+
* Useful for cleaning up locks after process restart or for specific services
|
|
441
|
+
*
|
|
442
|
+
* WARNING: Use with caution in production! This will forcefully delete locks.
|
|
443
|
+
*
|
|
444
|
+
* @param pattern - Lock pattern (e.g., 'MyService:*' or '*:migration:*')
|
|
445
|
+
* @param keyPrefix - Key prefix (default: 'lock')
|
|
446
|
+
* @returns Number of locks deleted
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```typescript
|
|
450
|
+
* // Clean up all locks for MyService
|
|
451
|
+
* await lockService.cleanupLocksByPattern('MyService:*');
|
|
452
|
+
*
|
|
453
|
+
* // Clean up all migration locks
|
|
454
|
+
* await lockService.cleanupLocksByPattern('*:migration:*');
|
|
455
|
+
* ```
|
|
456
|
+
*/
|
|
298
457
|
cleanupLocksByPattern(pattern_1) {
|
|
299
458
|
return __awaiter(this, arguments, void 0, function* (pattern, keyPrefix = 'lock') {
|
|
300
459
|
const redis = yield this.getRedis();
|
|
@@ -315,6 +474,28 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
315
474
|
}
|
|
316
475
|
});
|
|
317
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Clean up locks on startup
|
|
479
|
+
* This method is useful for cleaning up stale locks from previous process instances
|
|
480
|
+
*
|
|
481
|
+
* WARNING: Only use this if you're sure the locks are from previous process instances!
|
|
482
|
+
*
|
|
483
|
+
* @param patterns - Array of lock patterns to clean up
|
|
484
|
+
* @param keyPrefix - Key prefix (default: 'lock')
|
|
485
|
+
* @returns Total number of locks deleted
|
|
486
|
+
*
|
|
487
|
+
* @example
|
|
488
|
+
* ```typescript
|
|
489
|
+
* // In your module's onModuleInit
|
|
490
|
+
* async onModuleInit() {
|
|
491
|
+
* // Clean up locks from this service that might be left from previous restart
|
|
492
|
+
* await this.lockService.cleanupOnStartup([
|
|
493
|
+
* 'MyService:*',
|
|
494
|
+
* 'AnotherService:*'
|
|
495
|
+
* ]);
|
|
496
|
+
* }
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
318
499
|
cleanupOnStartup(patterns_1) {
|
|
319
500
|
return __awaiter(this, arguments, void 0, function* (patterns, keyPrefix = 'lock') {
|
|
320
501
|
this.logger.log(`Starting lock cleanup for ${patterns.length} pattern(s) on startup...`);
|
|
@@ -327,10 +508,17 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
327
508
|
return totalDeleted;
|
|
328
509
|
});
|
|
329
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Health check for Redis connection
|
|
513
|
+
* Returns information about Redis connectivity and lock service status
|
|
514
|
+
*
|
|
515
|
+
* @returns Health check result
|
|
516
|
+
*/
|
|
330
517
|
healthCheck() {
|
|
331
518
|
return __awaiter(this, void 0, void 0, function* () {
|
|
332
519
|
try {
|
|
333
520
|
const redis = yield this.getRedis();
|
|
521
|
+
// Try to ping Redis
|
|
334
522
|
const pong = yield redis.ping();
|
|
335
523
|
if (pong === 'PONG') {
|
|
336
524
|
return {
|
|
@@ -356,6 +544,14 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
356
544
|
}
|
|
357
545
|
});
|
|
358
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Get all active locks with optional pattern filtering
|
|
549
|
+
* Useful for monitoring and debugging
|
|
550
|
+
*
|
|
551
|
+
* @param pattern - Optional pattern to filter locks (e.g., 'MyService:*')
|
|
552
|
+
* @param keyPrefix - Key prefix (default: 'lock')
|
|
553
|
+
* @returns Array of active lock information
|
|
554
|
+
*/
|
|
359
555
|
getActiveLocks() {
|
|
360
556
|
return __awaiter(this, arguments, void 0, function* (pattern = '*', keyPrefix = 'lock') {
|
|
361
557
|
const redis = yield this.getRedis();
|
|
@@ -370,6 +566,7 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
370
566
|
redis.get(key),
|
|
371
567
|
redis.pttl(key),
|
|
372
568
|
]);
|
|
569
|
+
// Remove the key prefix for cleaner output
|
|
373
570
|
const cleanKey = key.startsWith(`${keyPrefix}:`)
|
|
374
571
|
? key.substring(`${keyPrefix}:`.length)
|
|
375
572
|
: key;
|
|
@@ -387,6 +584,10 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
387
584
|
}
|
|
388
585
|
});
|
|
389
586
|
}
|
|
587
|
+
/**
|
|
588
|
+
* Get Redis connection
|
|
589
|
+
* Requires external Redis client to be set
|
|
590
|
+
*/
|
|
390
591
|
getRedis() {
|
|
391
592
|
return __awaiter(this, void 0, void 0, function* () {
|
|
392
593
|
if (!this.redis) {
|
|
@@ -395,12 +596,51 @@ let RedisLockService = RedisLockService_1 = class RedisLockService {
|
|
|
395
596
|
return this.redis;
|
|
396
597
|
});
|
|
397
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* Generate a unique lock value
|
|
601
|
+
* Format: instanceId:timestamp:random:pid
|
|
602
|
+
*
|
|
603
|
+
* @returns Unique lock identifier
|
|
604
|
+
*/
|
|
398
605
|
generateLockValue() {
|
|
399
|
-
|
|
606
|
+
const timestamp = Date.now();
|
|
607
|
+
const random = Math.random().toString(36).substring(2, 15);
|
|
608
|
+
const pid = process.pid;
|
|
609
|
+
return `${this.instanceId}:${timestamp}:${random}:${pid}`;
|
|
400
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* Get instance identifier
|
|
613
|
+
* Used to distinguish different process instances in distributed environments
|
|
614
|
+
*
|
|
615
|
+
* @returns Instance identifier
|
|
616
|
+
*/
|
|
617
|
+
getInstanceId() {
|
|
618
|
+
// 1. Kubernetes Pod name
|
|
619
|
+
if (process.env.HOSTNAME) {
|
|
620
|
+
return process.env.HOSTNAME;
|
|
621
|
+
}
|
|
622
|
+
// 2. Custom instance ID
|
|
623
|
+
if (process.env.INSTANCE_ID) {
|
|
624
|
+
return process.env.INSTANCE_ID;
|
|
625
|
+
}
|
|
626
|
+
// 3. Generate unique ID
|
|
627
|
+
return `instance-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Build the full Redis key for a lock
|
|
631
|
+
*
|
|
632
|
+
* @param key - Lock key
|
|
633
|
+
* @param prefix - Key prefix
|
|
634
|
+
* @returns Full Redis key
|
|
635
|
+
*/
|
|
401
636
|
buildLockKey(key, prefix = 'lock') {
|
|
402
637
|
return `${prefix}:${key}`;
|
|
403
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* Sleep for a specified duration
|
|
641
|
+
*
|
|
642
|
+
* @param ms - Milliseconds to sleep
|
|
643
|
+
*/
|
|
404
644
|
sleep(ms) {
|
|
405
645
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
406
646
|
}
|
package/setup/bootstrap.setup.js
CHANGED
|
@@ -19,12 +19,15 @@ const process = require("process");
|
|
|
19
19
|
const mode_setup_1 = require("./mode.setup");
|
|
20
20
|
function findValidRootPath() {
|
|
21
21
|
const getAppRootPath = () => {
|
|
22
|
+
// 优先使用 require.main.filename(应用入口文件)
|
|
22
23
|
if (require.main && require.main.filename) {
|
|
23
24
|
return (0, path_1.dirname)(require.main.filename);
|
|
24
25
|
}
|
|
26
|
+
// fallback 到 process.argv[1]
|
|
25
27
|
if (process.argv[1]) {
|
|
26
28
|
return (0, path_1.dirname)(process.argv[1]);
|
|
27
29
|
}
|
|
30
|
+
// 最后 fallback 到当前工作目录
|
|
28
31
|
return process.cwd();
|
|
29
32
|
};
|
|
30
33
|
const possibleRootPaths = [getAppRootPath(), process.cwd(), __dirname];
|
|
@@ -56,6 +59,8 @@ function findValidRootPath() {
|
|
|
56
59
|
throw new Error(`No valid .env file: ${envFilePath}`);
|
|
57
60
|
}
|
|
58
61
|
const { envFilePath, rootPath, baseEnvFilePath } = findValidRootPath();
|
|
62
|
+
// 配置加载顺序: base.env < 环境.env < Vault
|
|
63
|
+
// 1. 先加载本地配置文件 (base.env 和 环境.env)
|
|
59
64
|
dotenv.config({ path: [envFilePath, baseEnvFilePath] });
|
|
60
65
|
process.env.ROOT_PATH = rootPath;
|
|
61
66
|
process.env.ENV_FILE_PATH = envFilePath;
|
|
@@ -121,34 +126,47 @@ const vault_1 = require("../vault");
|
|
|
121
126
|
const dto_1 = require("../common/dto");
|
|
122
127
|
function bootstrapSetup(AppModule, SetupSwagger) {
|
|
123
128
|
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
// 2. 加载 Vault 配置(会覆盖 .env 中的配置)
|
|
124
130
|
yield vault_1.VaultConfigLoader.loadVaultConfig();
|
|
131
|
+
// 获取应用模式
|
|
125
132
|
const shouldStartHttp = (0, mode_setup_1.shouldStartHttpServer)();
|
|
133
|
+
// 创建应用实例
|
|
126
134
|
const app = yield core_1.NestFactory.create(AppModule, {
|
|
127
135
|
bufferLogs: true,
|
|
128
136
|
autoFlushLogs: true,
|
|
129
137
|
});
|
|
138
|
+
// 设置容器 - 类似class-validator的useContainer
|
|
130
139
|
const appModuleRef = app.select(AppModule);
|
|
131
140
|
(0, class_validator_1.useContainer)(appModuleRef, { fallbackOnErrors: true });
|
|
141
|
+
// 初始化DTO容器
|
|
132
142
|
dto_1.DtoContainer.useContainer(appModuleRef);
|
|
143
|
+
// 获取核心服务
|
|
133
144
|
const configService = app.select(__1.ServiceRegistryModule).get(__1.ApiConfigService);
|
|
134
145
|
const logger = app.get(nestjs_pino_1.Logger);
|
|
135
146
|
app.useLogger(logger);
|
|
136
147
|
app.flushLogs();
|
|
148
|
+
// 记录应用模式
|
|
137
149
|
logger.log(`Application Mode: ${(0, mode_setup_1.getModeDescription)()}`);
|
|
138
150
|
logger.log(`Environment: ${process.env.NODE_ENV || 'unknown'}`);
|
|
139
151
|
app.enableShutdownHooks();
|
|
152
|
+
// 基础配置
|
|
140
153
|
app.enableVersioning();
|
|
141
154
|
app.enable('trust proxy');
|
|
142
155
|
app.set('query parser', 'extended');
|
|
156
|
+
// 中间件配置
|
|
143
157
|
app.use(bodyParse.urlencoded({
|
|
144
158
|
extended: true,
|
|
145
159
|
parameterLimit: 1000,
|
|
146
160
|
}), bodyParse.json({ limit: '50mb' }), new nestjs_cls_1.ClsMiddleware({
|
|
147
161
|
saveReq: true,
|
|
162
|
+
// 启用请求保存,解决CLS相关的上下文问题
|
|
148
163
|
}).use, (0, __1.RequestIdMiddleware)(), (0, __1.PowerByMiddleware)(), (0, __1.OmniAuthMiddleware)(), compression());
|
|
164
|
+
// 全局过滤器
|
|
149
165
|
const reflector = app.get(core_1.Reflector);
|
|
150
166
|
app.useGlobalFilters(new setup_1.SentryGlobalFilter(), new __1.HttpExceptionFilter(), new __1.QueryFailedFilter(reflector));
|
|
167
|
+
// 全局拦截器
|
|
151
168
|
app.useGlobalInterceptors(new __1.LanguageInterceptor(), new __1.TranslationInterceptor(), new nestjs_pino_1.LoggerErrorInterceptor());
|
|
169
|
+
// 全局管道
|
|
152
170
|
app.useGlobalPipes(new nestjs_i18n_1.I18nValidationPipe({
|
|
153
171
|
whitelist: true,
|
|
154
172
|
errorHttpStatusCode: common_1.HttpStatus.UNPROCESSABLE_ENTITY,
|
|
@@ -156,6 +174,7 @@ function bootstrapSetup(AppModule, SetupSwagger) {
|
|
|
156
174
|
stopAtFirstError: true,
|
|
157
175
|
validationError: { target: false, value: false },
|
|
158
176
|
}));
|
|
177
|
+
// 可选功能模块 - 仅在 HTTP 或 Hybrid 模式下启用
|
|
159
178
|
if (shouldStartHttp) {
|
|
160
179
|
if (configService.documentationEnabled && SetupSwagger) {
|
|
161
180
|
SetupSwagger(app, configService.documentationPath);
|
|
@@ -181,6 +200,7 @@ function bootstrapSetup(AppModule, SetupSwagger) {
|
|
|
181
200
|
else {
|
|
182
201
|
logger.log('Running in Worker-only mode - HTTP server not started');
|
|
183
202
|
logger.log('Application is ready to process background tasks');
|
|
203
|
+
// 在 Worker 模式下,应用会持续运行但不监听 HTTP 请求
|
|
184
204
|
yield app.init();
|
|
185
205
|
}
|
|
186
206
|
return app;
|
package/setup/mode.setup.d.ts
CHANGED
|
@@ -1,12 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Mode Detection and Management System
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for detecting and managing different application modes:
|
|
5
|
+
* - HTTP: Only HTTP server (no workers/schedulers)
|
|
6
|
+
* - WORKER: Only background workers and schedulers (no HTTP server)
|
|
7
|
+
* - HYBRID: Both HTTP server and workers (default)
|
|
8
|
+
*/
|
|
1
9
|
export declare enum ApplicationMode {
|
|
2
10
|
HTTP = "http",
|
|
3
11
|
WORKER = "worker",
|
|
4
12
|
HYBRID = "hybrid"
|
|
5
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Get the current application mode from environment variables
|
|
16
|
+
* Supports both APP_MODE and MODE environment variables
|
|
17
|
+
*
|
|
18
|
+
* @returns The current application mode
|
|
19
|
+
*/
|
|
6
20
|
export declare function getApplicationMode(): ApplicationMode;
|
|
21
|
+
/**
|
|
22
|
+
* Check if the current mode should process queues and scheduled tasks
|
|
23
|
+
*
|
|
24
|
+
* @returns True if workers should be registered
|
|
25
|
+
*/
|
|
7
26
|
export declare function shouldProcessQueues(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Check if the current mode should start HTTP server
|
|
29
|
+
*
|
|
30
|
+
* @returns True if HTTP server should be started
|
|
31
|
+
*/
|
|
8
32
|
export declare function shouldStartHttpServer(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Check if running in HTTP-only mode
|
|
35
|
+
*
|
|
36
|
+
* @returns True if running in HTTP-only mode
|
|
37
|
+
*/
|
|
9
38
|
export declare function isHttpMode(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check if running in Worker-only mode
|
|
41
|
+
*
|
|
42
|
+
* @returns True if running in Worker-only mode
|
|
43
|
+
*/
|
|
10
44
|
export declare function isWorkerMode(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Check if running in Hybrid mode
|
|
47
|
+
*
|
|
48
|
+
* @returns True if running in Hybrid mode
|
|
49
|
+
*/
|
|
11
50
|
export declare function isHybridMode(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Get a human-readable description of the current mode
|
|
53
|
+
*
|
|
54
|
+
* @returns Description of the current mode
|
|
55
|
+
*/
|
|
12
56
|
export declare function getModeDescription(): string;
|
package/setup/mode.setup.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Application Mode Detection and Management System
|
|
4
|
+
*
|
|
5
|
+
* This module provides utilities for detecting and managing different application modes:
|
|
6
|
+
* - HTTP: Only HTTP server (no workers/schedulers)
|
|
7
|
+
* - WORKER: Only background workers and schedulers (no HTTP server)
|
|
8
|
+
* - HYBRID: Both HTTP server and workers (default)
|
|
9
|
+
*/
|
|
2
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
11
|
exports.ApplicationMode = void 0;
|
|
4
12
|
exports.getApplicationMode = getApplicationMode;
|
|
@@ -14,6 +22,12 @@ var ApplicationMode;
|
|
|
14
22
|
ApplicationMode["WORKER"] = "worker";
|
|
15
23
|
ApplicationMode["HYBRID"] = "hybrid";
|
|
16
24
|
})(ApplicationMode || (exports.ApplicationMode = ApplicationMode = {}));
|
|
25
|
+
/**
|
|
26
|
+
* Get the current application mode from environment variables
|
|
27
|
+
* Supports both APP_MODE and MODE environment variables
|
|
28
|
+
*
|
|
29
|
+
* @returns The current application mode
|
|
30
|
+
*/
|
|
17
31
|
function getApplicationMode() {
|
|
18
32
|
const mode = (process.env.APP_MODE || process.env.MODE || 'hybrid')
|
|
19
33
|
.toLowerCase()
|
|
@@ -28,23 +42,53 @@ function getApplicationMode() {
|
|
|
28
42
|
return ApplicationMode.HYBRID;
|
|
29
43
|
}
|
|
30
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if the current mode should process queues and scheduled tasks
|
|
47
|
+
*
|
|
48
|
+
* @returns True if workers should be registered
|
|
49
|
+
*/
|
|
31
50
|
function shouldProcessQueues() {
|
|
32
51
|
const mode = getApplicationMode();
|
|
33
52
|
return mode === ApplicationMode.WORKER || mode === ApplicationMode.HYBRID;
|
|
34
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if the current mode should start HTTP server
|
|
56
|
+
*
|
|
57
|
+
* @returns True if HTTP server should be started
|
|
58
|
+
*/
|
|
35
59
|
function shouldStartHttpServer() {
|
|
36
60
|
const mode = getApplicationMode();
|
|
37
61
|
return mode === ApplicationMode.HTTP || mode === ApplicationMode.HYBRID;
|
|
38
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if running in HTTP-only mode
|
|
65
|
+
*
|
|
66
|
+
* @returns True if running in HTTP-only mode
|
|
67
|
+
*/
|
|
39
68
|
function isHttpMode() {
|
|
40
69
|
return getApplicationMode() === ApplicationMode.HTTP;
|
|
41
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if running in Worker-only mode
|
|
73
|
+
*
|
|
74
|
+
* @returns True if running in Worker-only mode
|
|
75
|
+
*/
|
|
42
76
|
function isWorkerMode() {
|
|
43
77
|
return getApplicationMode() === ApplicationMode.WORKER;
|
|
44
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if running in Hybrid mode
|
|
81
|
+
*
|
|
82
|
+
* @returns True if running in Hybrid mode
|
|
83
|
+
*/
|
|
45
84
|
function isHybridMode() {
|
|
46
85
|
return getApplicationMode() === ApplicationMode.HYBRID;
|
|
47
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Get a human-readable description of the current mode
|
|
89
|
+
*
|
|
90
|
+
* @returns Description of the current mode
|
|
91
|
+
*/
|
|
48
92
|
function getModeDescription() {
|
|
49
93
|
const mode = getApplicationMode();
|
|
50
94
|
switch (mode) {
|