@clonegod/ttd-sui-common 1.0.33 → 1.0.34

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.
@@ -0,0 +1 @@
1
+ export * from "./redis_client";
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./redis_client"), exports);
@@ -0,0 +1,21 @@
1
+ import { RedisClientType } from "redis";
2
+ export declare class SimpleRedisClient {
3
+ private lock_prefix;
4
+ private redisClient;
5
+ private lockMaxRetries;
6
+ private lockRetryDelayMs;
7
+ private lockExpireSeconds;
8
+ constructor(lock_prefix: string);
9
+ getRedisClient(): Promise<RedisClientType>;
10
+ private getLockKey;
11
+ private acquireLock;
12
+ private releaseLock;
13
+ withLock<T>(lock_identifier: string, callback: () => Promise<T>, release_lock_delay_ms?: number): Promise<T>;
14
+ getValue(key: string): Promise<string>;
15
+ setValue(key: string, value: string, expireSeconds: number): Promise<any>;
16
+ hsetValue(key: string, field: string, value: string, expireSeconds: number): Promise<any>;
17
+ hgetvalue(key: string, field: string): Promise<any>;
18
+ hkeys(key: string): Promise<any>;
19
+ hgetall(key: string): Promise<any>;
20
+ del(key: string, field?: string): Promise<any>;
21
+ }
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SimpleRedisClient = void 0;
13
+ const dist_1 = require("@clonegod/ttd-core/dist");
14
+ class SimpleRedisClient {
15
+ constructor(lock_prefix) {
16
+ this.lock_prefix = lock_prefix;
17
+ this.redisClient = null;
18
+ this.lockMaxRetries = 10;
19
+ this.lockRetryDelayMs = 300;
20
+ this.lockExpireSeconds = 3;
21
+ }
22
+ getRedisClient() {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ if (!this.redisClient) {
25
+ this.redisClient = yield (0, dist_1.getRedisCache)();
26
+ }
27
+ return this.redisClient;
28
+ });
29
+ }
30
+ getLockKey(lock_identifier) {
31
+ return `${this.lock_prefix}:lock:${lock_identifier}`;
32
+ }
33
+ acquireLock(lock_key_1, lock_value_1) {
34
+ return __awaiter(this, arguments, void 0, function* (lock_key, lock_value, expireSeconds = this.lockExpireSeconds) {
35
+ const redisClient = yield this.getRedisClient();
36
+ const result = yield redisClient.set(lock_key, lock_value, {
37
+ NX: true,
38
+ EX: expireSeconds
39
+ });
40
+ (0, dist_1.log_info)(`try acquireLock: lock_key=${lock_key}, lock_value=${lock_value}, expireSeconds=${expireSeconds}, result=${result}`);
41
+ const success = result === 'OK';
42
+ if (success) {
43
+ (0, dist_1.log_info)(`acquire lock success: lock_key=${lock_key}, lock_value=${lock_value}`);
44
+ }
45
+ return success;
46
+ });
47
+ }
48
+ releaseLock(lock_key, lock_value) {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ const redisClient = yield this.getRedisClient();
51
+ const script = `
52
+ if redis.call('get', KEYS[1]) == ARGV[1] then
53
+ return redis.call('del', KEYS[1])
54
+ else
55
+ return 0
56
+ end
57
+ `;
58
+ const result = yield redisClient.eval(script, {
59
+ keys: [lock_key],
60
+ arguments: [lock_value]
61
+ });
62
+ const success = Number(result) === 1;
63
+ if (success) {
64
+ (0, dist_1.log_info)(`release lock success: lock_key=${lock_key}, lock_value=${lock_value}`);
65
+ }
66
+ else {
67
+ (0, dist_1.log_info)(`release lock failed: lock_key=${lock_key}, lock_value=${lock_value}, maybe expired or locked by other process`);
68
+ }
69
+ return success;
70
+ });
71
+ }
72
+ withLock(lock_identifier_1, callback_1) {
73
+ return __awaiter(this, arguments, void 0, function* (lock_identifier, callback, release_lock_delay_ms = 2000) {
74
+ const lock_key = this.getLockKey(lock_identifier);
75
+ const lock_value = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
76
+ let retries = 0;
77
+ let acquired = false;
78
+ let first_try_time = Date.now();
79
+ let get_lock_time = 0;
80
+ try {
81
+ while (retries < this.lockMaxRetries) {
82
+ acquired = yield this.acquireLock(lock_key, lock_value);
83
+ if (acquired)
84
+ break;
85
+ yield new Promise(resolve => setTimeout(resolve, this.lockRetryDelayMs));
86
+ retries++;
87
+ }
88
+ if (acquired) {
89
+ get_lock_time = Date.now();
90
+ return yield callback();
91
+ }
92
+ }
93
+ finally {
94
+ if (acquired) {
95
+ const release_delay = parseInt(process.env.NONCE_LOCK_RELEASE_DELAY_MS || String(release_lock_delay_ms));
96
+ yield (0, dist_1.sleep)(release_delay);
97
+ yield this.releaseLock(lock_key, lock_value);
98
+ (0, dist_1.log_info)(`withLock success: lock_key=${lock_key}, lock_value=${lock_value}, retry times=${retries}, get lock take ${get_lock_time - first_try_time}ms, release_delay=${release_delay}ms, hold lock ${Date.now() - get_lock_time}ms`);
99
+ }
100
+ else {
101
+ (0, dist_1.log_warn)(`withLock failed: lock_key=${lock_key}, lock_value=${lock_value}, retry times=${retries}, took ${Date.now() - first_try_time}ms`);
102
+ }
103
+ }
104
+ });
105
+ }
106
+ getValue(key) {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ const redisClient = yield this.getRedisClient();
109
+ return yield redisClient.get(key);
110
+ });
111
+ }
112
+ setValue(key, value, expireSeconds) {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ const redisClient = yield this.getRedisClient();
115
+ return yield redisClient.set(key, value, {
116
+ EX: expireSeconds
117
+ });
118
+ });
119
+ }
120
+ hsetValue(key, field, value, expireSeconds) {
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ const redisClient = yield this.getRedisClient();
123
+ yield redisClient.hSet(key, field, value);
124
+ yield redisClient.hExpire(key, field, expireSeconds);
125
+ });
126
+ }
127
+ hgetvalue(key, field) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ const redisClient = yield this.getRedisClient();
130
+ return yield redisClient.hGet(key, field);
131
+ });
132
+ }
133
+ hkeys(key) {
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ const redisClient = yield this.getRedisClient();
136
+ return yield redisClient.hKeys(key);
137
+ });
138
+ }
139
+ hgetall(key) {
140
+ return __awaiter(this, void 0, void 0, function* () {
141
+ const redisClient = yield this.getRedisClient();
142
+ return yield redisClient.hGetAll(key);
143
+ });
144
+ }
145
+ del(key_1) {
146
+ return __awaiter(this, arguments, void 0, function* (key, field = '') {
147
+ const redisClient = yield this.getRedisClient();
148
+ if (field) {
149
+ return yield redisClient.hDel(key, field);
150
+ }
151
+ return yield redisClient.del(key);
152
+ });
153
+ }
154
+ }
155
+ exports.SimpleRedisClient = SimpleRedisClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clonegod/ttd-sui-common",
3
- "version": "1.0.33",
3
+ "version": "1.0.34",
4
4
  "description": "Sui common library",
5
5
  "license": "UNLICENSED",
6
6
  "main": "dist/index.js",