mm_redis 1.9.9 → 2.0.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 +16 -65
- package/index.js +58 -109
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ mm_redis是一个高效的Redis客户端封装库,提供了全面的Redis功
|
|
|
7
7
|
|
|
8
8
|
## 版本信息
|
|
9
9
|
|
|
10
|
-
- **当前版本**:
|
|
11
|
-
- **更新日期**:
|
|
10
|
+
- **当前版本**: 2.0.1
|
|
11
|
+
- **更新日期**: 2025-10-14
|
|
12
12
|
- **作者**: 邱文武
|
|
13
13
|
- **NPM**: [https://www.npmjs.com/package/mm_redis](https://www.npmjs.com/package/mm_redis)
|
|
14
14
|
- **GitHub**: [https://gitee.com/qiuwenwu91/mm_redis](https://gitee.com/qiuwenwu91/mm_redis)
|
|
@@ -79,6 +79,11 @@ redis.setConfig('./config.json');
|
|
|
79
79
|
```
|
|
80
80
|
## 变更日志
|
|
81
81
|
|
|
82
|
+
### v2.0.0 (2025-10-14)
|
|
83
|
+
- 移除list_push方法,统一使用addForList方法进行列表添加操作
|
|
84
|
+
- 更新文档,将所有list_push引用替换为addForList
|
|
85
|
+
- 更新文档中的API列表和使用示例
|
|
86
|
+
|
|
82
87
|
### v1.9.8 (2024-12-22)
|
|
83
88
|
- 更新文档,完善npm发布所需内容
|
|
84
89
|
- 添加GitHub仓库链接到文档
|
|
@@ -136,7 +141,7 @@ await redis.close();
|
|
|
136
141
|
await redis.setForList('users', ['user1', 'user2', 'user3']);
|
|
137
142
|
|
|
138
143
|
// 添加元素到列表
|
|
139
|
-
await redis.
|
|
144
|
+
await redis.addForList('users', 'user4');
|
|
140
145
|
|
|
141
146
|
// 获取列表
|
|
142
147
|
const users = await redis.getForList('users');
|
|
@@ -291,7 +296,7 @@ redis.on('set_error', (data) => {
|
|
|
291
296
|
| setrange | setrange_before | setrange_after | setrange_error |
|
|
292
297
|
| clear | clear_before | clear_after | clear_error |
|
|
293
298
|
| setForList | setForList_before | setForList_after | setForList_error |
|
|
294
|
-
|
|
|
299
|
+
| addForList | addForList_before | addForList_after | addForList_error |
|
|
295
300
|
| clearForList | clearForList_before | clearForList_after | clearForList_error |
|
|
296
301
|
| mset | mset_before | mset_after | mset_error |
|
|
297
302
|
| mget | mget_before | mget_after | mget_error |
|
|
@@ -335,7 +340,7 @@ redis.on('set_error', (data) => {
|
|
|
335
340
|
### 列表操作
|
|
336
341
|
|
|
337
342
|
- `setForList(key, value, seconds)`: 设置列表
|
|
338
|
-
- `
|
|
343
|
+
- `addForList(key, value)`: 添加元素到列表
|
|
339
344
|
- `getForList(key, start, end)`: 获取列表
|
|
340
345
|
- `hasForList(key, value)`: 判断列表中是否存在元素
|
|
341
346
|
- `clearForList(key, value)`: 清空列表或重置列表
|
|
@@ -423,66 +428,12 @@ redis.on('set_error', (data) => {
|
|
|
423
428
|
|
|
424
429
|
## 版本更新
|
|
425
430
|
|
|
426
|
-
###
|
|
427
|
-
-
|
|
428
|
-
-
|
|
429
|
-
-
|
|
430
|
-
-
|
|
431
|
-
-
|
|
432
|
-
- 修复原生Redis API调用中的错误,提升代码稳定性
|
|
433
|
-
- 优化连接池管理,修复潜在的内存泄漏问题
|
|
434
|
-
|
|
435
|
-
### 1.9.4 (2024-12-20)
|
|
436
|
-
- 优化了配置引入方式,支持对象配置和文件路径配置两种方式
|
|
437
|
-
- 改进了setConfig方法的实现,使用Object.assign替代原来的合并方式
|
|
438
|
-
- 修复了连接池相关的警告信息
|
|
439
|
-
- 增强了错误处理机制
|
|
440
|
-
|
|
441
|
-
### 1.9.0 (2024-11-20)
|
|
442
|
-
- 适配Redis v4 API,确保与最新版Redis客户端兼容
|
|
443
|
-
- 重写pipeline方法,使用Redis v4推荐的实现方式
|
|
444
|
-
- 优化mget方法,直接使用Redis v4的mGet API
|
|
445
|
-
- 修复集合操作(srem)和有序集合操作(zadd/zrange/zscore/zrank)的兼容性问题
|
|
446
|
-
- 完善测试用例,确保所有功能正常工作
|
|
447
|
-
- 更新依赖版本,优化连接管理
|
|
448
|
-
- 完善事件系统,为incr、decr、incrby、decrby方法添加前置事件(_before)支持
|
|
449
|
-
- 确保所有非查询方法都有完整的_before、_after、_error事件触发机制
|
|
450
|
-
- 更新文档,添加新支持的事件到事件列表中
|
|
451
|
-
- 版本号更新和发布日期更新
|
|
452
|
-
|
|
453
|
-
### 1.8.1 (2024-10-09)
|
|
454
|
-
- 修复mget方法返回格式问题,确保与原生Redis保持一致
|
|
455
|
-
- 修复mset方法参数验证逻辑,优化批量设置功能
|
|
456
|
-
- 优化Pipeline实现,确保命令正确执行
|
|
457
|
-
- 修复连接池初始化和管理逻辑
|
|
458
|
-
- 修复存储机制,确保数据正确持久化
|
|
459
|
-
- 准备npm发布,优化文档格式和结构
|
|
460
|
-
- 添加npm徽章和下载统计
|
|
461
|
-
|
|
462
|
-
### 1.8.0 (2024-10-08)
|
|
463
|
-
- 新增集合(Set)操作支持:sadd、srem、sismember、smembers、scard、sinter、sunion、sdiff
|
|
464
|
-
- 新增有序集合(Sorted Set)操作支持:zadd、zrem、zscore、zrank、zrange、zcard、zincrby
|
|
465
|
-
- 新增数值操作支持:incr、decr、incrby、decrby、expire
|
|
466
|
-
- 更新文档,添加新功能的API说明
|
|
467
|
-
- 更新版本号和发布日期
|
|
468
|
-
|
|
469
|
-
### 1.7.0 (2024-10-07)
|
|
470
|
-
- 统一事件系统的属性命名规范
|
|
471
|
-
- 更新所有方法的事件emit属性,使用统一的key、value、ttl、result等命名
|
|
472
|
-
- 增加事件系统的详细文档
|
|
473
|
-
- 修复部分方法中的拼写错误
|
|
474
|
-
|
|
475
|
-
### 1.6.0 (2024-01-10)
|
|
476
|
-
- 添加完整的连接池管理功能
|
|
477
|
-
- 新增Pipeline批量操作优化
|
|
478
|
-
- 增加Hash数据类型支持
|
|
479
|
-
- 增强错误处理和日志记录
|
|
480
|
-
- 优化重连机制,实现指数退避策略
|
|
481
|
-
|
|
482
|
-
### 1.5.0
|
|
483
|
-
- 优化连接管理
|
|
484
|
-
- 完善错误处理
|
|
485
|
-
- 提升代码稳定性
|
|
431
|
+
### 2.0.0 (2025-10-14)
|
|
432
|
+
- 移除list_push方法,统一使用addForList方法进行列表添加操作
|
|
433
|
+
- 更新文档,将所有list_push引用替换为addForList
|
|
434
|
+
- 更新文档中的API列表和使用示例
|
|
435
|
+
- 优化连接池配置管理,统一配置到this.config.pool中
|
|
436
|
+
- 新增连接池配置参数:min_idle、max_idle、idle_timeout
|
|
486
437
|
|
|
487
438
|
## 贡献指南
|
|
488
439
|
|
package/index.js
CHANGED
|
@@ -39,17 +39,18 @@ class Redis extends BaseService {
|
|
|
39
39
|
// 重试次数
|
|
40
40
|
"retry_count": 3,
|
|
41
41
|
// 重试间隔(ms)
|
|
42
|
-
"retry_delay": 1000
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
config: {
|
|
50
|
-
max_clients: 10 // 最大连接数
|
|
42
|
+
"retry_delay": 1000,
|
|
43
|
+
// 连接池配置
|
|
44
|
+
"pool": {
|
|
45
|
+
"max_clients": 100, // 最大连接数
|
|
46
|
+
"min_idle": 5, // 最小空闲连接数
|
|
47
|
+
"max_idle": 20, // 最大空闲连接数
|
|
48
|
+
"idle_timeout": 30000 // 空闲超时时间(ms)
|
|
51
49
|
}
|
|
52
50
|
};
|
|
51
|
+
this.setConfig(config);
|
|
52
|
+
// 初始化连接池
|
|
53
|
+
this._initPool();
|
|
53
54
|
// 唯一标识符
|
|
54
55
|
this.identifier = this.config.host + "/" + this.config.database;
|
|
55
56
|
// 数据库连接器
|
|
@@ -167,28 +168,53 @@ Redis.prototype.message = function(channel, message) {
|
|
|
167
168
|
* @description 设置配置
|
|
168
169
|
* @param {Object} config 配置对象或配置路径
|
|
169
170
|
*/
|
|
170
|
-
// 修复setConfig方法,移除其中的_initPool定义
|
|
171
171
|
Redis.prototype.setConfig = function(config) {
|
|
172
172
|
let obj = {};
|
|
173
173
|
if (typeof config === 'string') {
|
|
174
174
|
obj = config.loadJson(__dirname);
|
|
175
175
|
} else if (config) {
|
|
176
176
|
// 合并配置参数
|
|
177
|
-
|
|
177
|
+
if (config.pool) {
|
|
178
|
+
// 确保连接池配置的合并不会覆盖所有默认值
|
|
179
|
+
if (!this.config.pool) {
|
|
180
|
+
this.config.pool = {};
|
|
181
|
+
}
|
|
182
|
+
Object.assign(this.config.pool, config.pool);
|
|
183
|
+
// 删除config中的pool属性,避免后续Object.assign重复处理
|
|
184
|
+
const configCopy = { ...config };
|
|
185
|
+
delete configCopy.pool;
|
|
186
|
+
Object.assign(this.config, configCopy);
|
|
187
|
+
} else {
|
|
188
|
+
Object.assign(this.config, config);
|
|
189
|
+
}
|
|
178
190
|
} else {
|
|
179
191
|
return;
|
|
180
192
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// 检查是否存在连接池配置,如果没有则使用默认配置
|
|
193
|
+
|
|
194
|
+
// 确保连接池配置存在且包含所有必要字段
|
|
184
195
|
if (!this.config.pool) {
|
|
185
|
-
this.config.pool = {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
196
|
+
this.config.pool = {};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// 设置默认连接池配置,只覆盖未定义的字段
|
|
200
|
+
const defaultPoolConfig = {
|
|
201
|
+
max_clients: 100,
|
|
202
|
+
min_idle: 5,
|
|
203
|
+
max_idle: 20,
|
|
204
|
+
idle_timeout: 30000
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
for (const key in defaultPoolConfig) {
|
|
208
|
+
if (this.config.pool[key] === undefined) {
|
|
209
|
+
this.config.pool[key] = defaultPoolConfig[key];
|
|
210
|
+
}
|
|
191
211
|
}
|
|
212
|
+
|
|
213
|
+
// 如果连接池已经初始化,更新其配置
|
|
214
|
+
if (this.connection_pool) {
|
|
215
|
+
this.connection_pool.config = this.config.pool;
|
|
216
|
+
}
|
|
217
|
+
|
|
192
218
|
// 初始化连接池
|
|
193
219
|
this._initPool();
|
|
194
220
|
$.log.debug('[Redis] 配置已更新');
|
|
@@ -198,20 +224,25 @@ Redis.prototype.setConfig = function(config) {
|
|
|
198
224
|
|
|
199
225
|
// 添加连接池初始化方法
|
|
200
226
|
Redis.prototype._initPool = function() {
|
|
227
|
+
// 确保连接池配置存在
|
|
228
|
+
if (!this.config.pool) {
|
|
229
|
+
this.config.pool = {
|
|
230
|
+
max_clients: 100,
|
|
231
|
+
min_idle: 5,
|
|
232
|
+
max_idle: 20,
|
|
233
|
+
idle_timeout: 30000
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
201
237
|
// 初始化连接池相关属性
|
|
202
238
|
this.connection_pool = {
|
|
203
239
|
available: [],
|
|
204
240
|
in_use: new Set(),
|
|
205
|
-
config: this.config.pool
|
|
206
|
-
max_clients: 10,
|
|
207
|
-
min_idle: 2,
|
|
208
|
-
max_idle: 5,
|
|
209
|
-
idle_timeout: 30000
|
|
210
|
-
}
|
|
241
|
+
config: this.config.pool // 直接引用配置对象,确保同步更新
|
|
211
242
|
};
|
|
212
243
|
|
|
213
244
|
// 记录连接池初始化
|
|
214
|
-
$.log.debug('[Redis]
|
|
245
|
+
$.log.debug('[Redis] 连接池已初始化,配置:', this.config.pool);
|
|
215
246
|
};
|
|
216
247
|
|
|
217
248
|
/**
|
|
@@ -1774,87 +1805,6 @@ Redis.prototype.setForList = async function(key, value, seconds) {
|
|
|
1774
1805
|
}
|
|
1775
1806
|
};
|
|
1776
1807
|
|
|
1777
|
-
/**
|
|
1778
|
-
* @description 数组缓存追加对象
|
|
1779
|
-
* @param {String} key 键
|
|
1780
|
-
* @param {Object|Array} value 值
|
|
1781
|
-
* @return {Promise<Number>} 追加后的数组长度
|
|
1782
|
-
*/
|
|
1783
|
-
Redis.prototype.list_push = async function(key, value) {
|
|
1784
|
-
try {
|
|
1785
|
-
// 触发前置事件,允许修改或阻止操作
|
|
1786
|
-
const beforeEventData = {
|
|
1787
|
-
key,
|
|
1788
|
-
value,
|
|
1789
|
-
cancel: false
|
|
1790
|
-
};
|
|
1791
|
-
this.emit('list_push_before', beforeEventData);
|
|
1792
|
-
|
|
1793
|
-
// 如果事件处理器标记为取消,则返回0
|
|
1794
|
-
if (beforeEventData.cancel) {
|
|
1795
|
-
$.log.debug(`[Redis] list_push操作被事件处理器取消 [${key}]`);
|
|
1796
|
-
return 0;
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
// 使用可能被修改的值
|
|
1800
|
-
let {
|
|
1801
|
-
key: finalKey,
|
|
1802
|
-
value: finalValue
|
|
1803
|
-
} = beforeEventData;
|
|
1804
|
-
let len = 0;
|
|
1805
|
-
let success = true;
|
|
1806
|
-
|
|
1807
|
-
const connection = await this._getConnection();
|
|
1808
|
-
try {
|
|
1809
|
-
finalKey = this.applyPrefix(finalKey);
|
|
1810
|
-
|
|
1811
|
-
if (Array.isArray(finalValue)) {
|
|
1812
|
-
// 添加数组元素
|
|
1813
|
-
if (typeof connection.rPush === 'function') {
|
|
1814
|
-
len = await connection.rPush(finalKey, finalValue);
|
|
1815
|
-
} else if (typeof connection.execute === 'function') {
|
|
1816
|
-
len = await connection.execute('RPUSH', [finalKey, ...finalValue]);
|
|
1817
|
-
} else {
|
|
1818
|
-
$.log.error('[Redis] 连接对象不支持rPush操作');
|
|
1819
|
-
success = false;
|
|
1820
|
-
len = 0;
|
|
1821
|
-
}
|
|
1822
|
-
} else {
|
|
1823
|
-
// 添加单个元素
|
|
1824
|
-
if (typeof connection.rPush === 'function') {
|
|
1825
|
-
len = await connection.rPush(finalKey, finalValue);
|
|
1826
|
-
} else if (typeof connection.execute === 'function') {
|
|
1827
|
-
len = await connection.execute('RPUSH', [finalKey, finalValue]);
|
|
1828
|
-
} else {
|
|
1829
|
-
$.log.error('[Redis] 连接对象不支持rPush操作');
|
|
1830
|
-
success = false;
|
|
1831
|
-
len = 0;
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1835
|
-
// 触发后置事件
|
|
1836
|
-
this.emit('list_push_after', {
|
|
1837
|
-
key: finalKey,
|
|
1838
|
-
value: finalValue,
|
|
1839
|
-
result: len,
|
|
1840
|
-
success
|
|
1841
|
-
});
|
|
1842
|
-
return len;
|
|
1843
|
-
} finally {
|
|
1844
|
-
this._recycleConnection(connection);
|
|
1845
|
-
}
|
|
1846
|
-
} catch (err) {
|
|
1847
|
-
// 触发错误事件
|
|
1848
|
-
this.emit('list_push_error', {
|
|
1849
|
-
key,
|
|
1850
|
-
value,
|
|
1851
|
-
error: err
|
|
1852
|
-
});
|
|
1853
|
-
$.log.error(`[Redis] 向列表追加元素失败 [${key}]:`, err);
|
|
1854
|
-
return 0;
|
|
1855
|
-
}
|
|
1856
|
-
};
|
|
1857
|
-
|
|
1858
1808
|
/**
|
|
1859
1809
|
* @description 数组缓存追加对象
|
|
1860
1810
|
* @param {String} key 键
|
|
@@ -2620,7 +2570,6 @@ Redis.prototype._releaseConnection = function(connection) {
|
|
|
2620
2570
|
// 检查是否超过最大空闲连接数
|
|
2621
2571
|
if (this.connection_pool.available.length < this.connection_pool.config.max_idle) {
|
|
2622
2572
|
this.connection_pool.available.push(connection);
|
|
2623
|
-
$.log.debug('[Redis] 连接已释放回池中:', connection.id);
|
|
2624
2573
|
} else {
|
|
2625
2574
|
// 否则关闭多余的连接
|
|
2626
2575
|
try {
|