mlock-server 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 脉冲云
3
+ Copyright (c) 2020 Liang Xingchen https://github.com/liangxingchen
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,8 +1,218 @@
1
- # `mlock-server`
1
+ # mlock-server
2
2
 
3
- ## Usage
3
+ Multi-resource distributed lock server
4
4
 
5
+ ## 功能特性
6
+
7
+ - 原子性多资源锁支持
8
+ - TCP 协议通信
9
+ - 锁超时和续期
10
+ - 队列等待机制
11
+ - 断线重连支持
12
+ - 实时状态查询
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install mlock-server
18
+ ```
19
+
20
+ ## 快速开始
21
+
22
+ ### JavaScript
23
+
24
+ ```javascript
25
+ const Server = require('mlock-server');
26
+
27
+ const server = new Server({ port: 12340 });
28
+ await server.listen();
29
+ console.log('Server started on port 12340');
30
+ ```
31
+
32
+ ### TypeScript
33
+
34
+ ```typescript
35
+ import Server from 'mlock-server';
36
+
37
+ const server = new Server({ port: 12340, debug: true });
38
+ await server.listen();
39
+ ```
40
+
41
+ ### CLI 命令
42
+
43
+ ```bash
44
+ # 启动服务
45
+ npx mlock-server --port 12340
46
+
47
+ # 查看状态
48
+ npx mlock-status
49
+ ```
50
+
51
+ ## 配置选项
52
+
53
+ | 参数 | 类型 | 默认值 | 说明 |
54
+ |------|------|--------|------|
55
+ | port | number | 12340 | 监听端口 |
56
+ | debug | boolean | false | 是否输出调试日志 |
57
+
58
+ ## API
59
+
60
+ ### constructor(options: ServerOptions)
61
+
62
+ 创建服务端实例。
63
+
64
+ ```javascript
65
+ const server = new Server({
66
+ port: 12340,
67
+ debug: true
68
+ });
69
+ ```
70
+
71
+ ### listen(): Promise<void>
72
+
73
+ 启动服务监听。
74
+
75
+ ```javascript
76
+ await server.listen();
77
+ ```
78
+
79
+ ### close(): Promise<void>
80
+
81
+ 关闭服务,清理所有连接和锁。
82
+
83
+ ```javascript
84
+ await server.close();
85
+ ```
86
+
87
+ ## 协议说明
88
+
89
+ mlock-server 使用简单的文本协议,通过 TCP 通信。
90
+
91
+ ### 消息格式
92
+
93
+ 所有消息以空格分隔,由 `packet-wrapper` 处理数据包边界。
94
+
95
+ ### 命令列表
96
+
97
+ #### CONNECT
98
+
99
+ 客户端连接认证。
100
+
101
+ ```
102
+ connect <socketId> <apiVersion>
103
+ ```
104
+
105
+ **响应:**
106
+ ```
107
+ connected <version>
108
+ ```
109
+
110
+ #### LOCK
111
+
112
+ 请求上锁。
113
+
114
+ ```
115
+ lock <requestId> <resources> <ttl> <timeout> <tolerate>
5
116
  ```
6
- const mlockServer = require('mlock-server');
7
117
 
118
+ - `requestId`: 请求 ID,用于响应匹配
119
+ - `resources`: 资源列表,用 `|` 分隔
120
+ - `ttl`: 锁生存时间(毫秒)
121
+ - `timeout`: 上锁超时时间(毫秒),0 表示不超时
122
+ - `tolerate`: 容忍队列长度,0 表示不限制
123
+
124
+ **响应:**
125
+ ```
126
+ result <requestId> success <lockId>
127
+ result <requestId> failed <error>
128
+ ```
129
+
130
+ #### EXTEND
131
+
132
+ 续期锁。
133
+
134
+ ```
135
+ extend <requestId> <lockId> <ttl>
136
+ ```
137
+
138
+ **响应:**
139
+ ```
140
+ result <requestId> success <expiredAt>
141
+ result <requestId> failed <error>
142
+ ```
143
+
144
+ #### UNLOCK
145
+
146
+ 解锁。
147
+
148
+ ```
149
+ unlock <requestId> <lockId>
150
+ ```
151
+
152
+ **响应:**
153
+ ```
154
+ result <requestId> success done
155
+ result <requestId> failed <error>
156
+ ```
157
+
158
+ #### PING
159
+
160
+ 心跳检测。
161
+
162
+ ```
163
+ ping <requestId>
164
+ ```
165
+
166
+ **响应:**
8
167
  ```
168
+ result <requestId> success pong
169
+ ```
170
+
171
+ #### STATUS
172
+
173
+ 查询服务器状态。
174
+
175
+ ```
176
+ status <requestId>
177
+ ```
178
+
179
+ **响应:**
180
+ ```
181
+ result <requestId> success <statusJSON>
182
+ ```
183
+
184
+ ### 服务器推送消息
185
+
186
+ 服务器会主动推送以下消息:
187
+
188
+ ```
189
+ connected <version> # 连接成功
190
+ error <message> # 连接错误
191
+ locked <lockId> # 锁获取成功
192
+ timeout <lockId> # 锁超时
193
+ expired <lockId> # 锁过期
194
+ ```
195
+
196
+ ## 状态查询
197
+
198
+ 通过 Telnet 或 netcat 直接连接可获取状态:
199
+
200
+ ```bash
201
+ nc localhost 12340
202
+ status
203
+ ```
204
+
205
+ 返回文本格式的状态信息:
206
+
207
+ ```
208
+ socketCount: 1
209
+ currentLocks: 0
210
+ liveTime: 12345
211
+ lockCount: 5
212
+ lockedCount: 5
213
+ ...
214
+ ```
215
+
216
+ ## 许可证
217
+
218
+ MIT
package/index.d.ts CHANGED
@@ -1,16 +1,42 @@
1
1
  import * as net from 'net';
2
2
 
3
+ /**
4
+ * 服务端配置选项
5
+ */
3
6
  export interface ServerOptions {
7
+ /**
8
+ * 监听端口,默认 12340
9
+ */
4
10
  port?: number;
11
+ /**
12
+ * 是否开启调试模式,开启后会输出详细日志
13
+ */
5
14
  debug?: boolean;
6
15
  }
7
16
 
17
+ /**
18
+ * 分布式锁服务端
19
+ *
20
+ * 提供 TCP 协议接口,支持资源的分布式锁管理
21
+ * 支持锁的超时、续期、队列等待等功能
22
+ */
8
23
  export default class Server {
9
24
  server: net.Server;
10
25
  options: ServerOptions;
11
26
 
27
+ /**
28
+ * 创建服务端实例
29
+ * @param options 服务端配置选项
30
+ */
12
31
  constructor(options: ServerOptions);
13
32
 
33
+ /**
34
+ * 启动服务监听
35
+ */
14
36
  listen(): Promise<void>;
37
+
38
+ /**
39
+ * 关闭服务,清理所有连接和锁
40
+ */
15
41
  close(): Promise<void>;
16
42
  }
package/lib/index.js CHANGED
@@ -19,6 +19,9 @@ function objectToText(object, indent = 0) {
19
19
  }
20
20
  return text;
21
21
  }
22
+ process.on('uncaughtException', function (err) {
23
+ console.error('uncaughtException', err.stack);
24
+ });
22
25
  class Server {
23
26
  constructor(options) {
24
27
  this.check = () => {
@@ -142,6 +145,12 @@ class Server {
142
145
  this.sockets[socket.id] = null;
143
146
  console.log(`disconnected ${socket.remoteAddress}:${socket.remotePort} ${socket.id}`);
144
147
  });
148
+ socket.on('error', (error) => {
149
+ console.error(`${socket.remoteAddress}:${socket.remotePort}`, error);
150
+ if (!socket.destroyed) {
151
+ socket.destroy();
152
+ }
153
+ });
145
154
  });
146
155
  return new Promise((resolve, reject) => {
147
156
  this.server.on('error', (e) => {
@@ -196,7 +205,7 @@ class Server {
196
205
  let args = [socket].concat(list.slice(1));
197
206
  let cmd = list[0].toLowerCase();
198
207
  if (!socket.id && cmd !== 'connect')
199
- return this.sendError(socket, 'shoule connect first!');
208
+ return this.sendError(socket, 'should connect first!');
200
209
  switch (cmd) {
201
210
  case 'connect':
202
211
  this.connect(...args);
@@ -395,6 +404,8 @@ class Server {
395
404
  socket.end();
396
405
  }
397
406
  send(socket, args) {
407
+ if (socket.destroyed || socket.writableEnded)
408
+ return;
398
409
  if (this.options.debug) {
399
410
  console.log(`send: ${socket.remoteAddress}:${socket.remotePort} ${args.join(' ')}`);
400
411
  }
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "mlock-server",
3
- "version": "0.1.9",
4
- "description": "Maichong lock server",
5
- "author": "Liang <liang@maichong.it> (https://github.com/liangxingchen)",
6
- "homepage": "https://github.com/maichong/mlock/tree/master/packages/mlock-server#readme",
3
+ "version": "0.2.0",
4
+ "description": "Multi-resource distributed lock server",
5
+ "author": {
6
+ "name": "Liang",
7
+ "email": "liang@miaomo.cn",
8
+ "url": "https://github.com/liangxingchen"
9
+ },
10
+ "homepage": "https://github.com/liangxingchen/mlock/tree/master/packages/mlock-server#readme",
7
11
  "license": "MIT",
8
12
  "bin": {
9
13
  "mlock-server": "bin/mlock-server",
@@ -17,19 +21,19 @@
17
21
  ],
18
22
  "repository": {
19
23
  "type": "git",
20
- "url": "git+https://github.com/maichong/mlock.git"
24
+ "url": "git+https://github.com/liangxingchen/mlock.git"
21
25
  },
22
26
  "scripts": {
23
27
  "build": "tsc"
24
28
  },
25
29
  "bugs": {
26
- "url": "https://github.com/maichong/mlock/issues"
30
+ "url": "https://github.com/liangxingchen/mlock/issues"
27
31
  },
28
32
  "dependencies": {
29
33
  "packet-wrapper": "^0.1.0"
30
34
  },
31
35
  "devDependencies": {
32
- "typescript": "^4.1.3"
36
+ "typescript": "^5.9.3"
33
37
  },
34
- "gitHead": "2f039368e09100e126f9aed9e8234630a426307d"
38
+ "gitHead": "fc9fbe81475b3fbdc8a54aff9015f152aa6f4edb"
35
39
  }