@hile/micro 2.0.4 → 2.0.5

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.
@@ -85,11 +85,11 @@ export class Application extends Server {
85
85
  // 这里不清理 topics 由业务方自己清理
86
86
  // 这里也不清理 declare 和 undeclare 由业务方自己清理
87
87
  return async () => {
88
+ this.stopped = true;
88
89
  for (const fallback of this.fallbacks) {
89
90
  fallback();
90
91
  }
91
92
  this.fallbacks.clear();
92
- this.stopped = true;
93
93
  if (this.reconnectTimeout) {
94
94
  clearTimeout(this.reconnectTimeout);
95
95
  this.reconnectTimeout = undefined;
@@ -106,6 +106,7 @@ export class Application extends Server {
106
106
  clearTimeout(this.reconnectTimeout);
107
107
  this.reconnectTimeout = setTimeout(() => {
108
108
  this.reconnectTimeout = undefined;
109
+ this.logger.debug('[reconnecting] %s:%d', this._registry_address.host, this._registry_address.port);
109
110
  void this.reconnectToRegistry().catch(() => {
110
111
  if (this.stopped)
111
112
  return;
@@ -141,6 +142,7 @@ export class Application extends Server {
141
142
  for (const [topic, callback] of this.topics) {
142
143
  await this.subscribe(topic, callback, true);
143
144
  }
145
+ this.logger.debug('[reconnected] %s:%d', this._registry_address.host, this._registry_address.port);
144
146
  })().finally(() => {
145
147
  this.registryReconnectPromise = undefined;
146
148
  });
package/dist/registry.js CHANGED
@@ -3,6 +3,7 @@ import { homedir } from 'node:os';
3
3
  import { resolve, join } from 'node:path';
4
4
  import { existsSync, mkdirSync, readdirSync, readFileSync, watch } from 'node:fs';
5
5
  import YAML from 'yaml';
6
+ import { createLogger } from '@hile/logger';
6
7
  /** 将 `host:port` 或 `[ipv6]:port` 形式的 key 解析为地址(端口取最后一个 `:` 之后) */
7
8
  export function parseAddressKey(key) {
8
9
  const i = key.lastIndexOf(':');
@@ -51,7 +52,12 @@ export class Registry extends Server {
51
52
  if (!existsSync(workspace)) {
52
53
  mkdirSync(workspace, { recursive: true });
53
54
  }
54
- super('registry', props);
55
+ super('registry', {
56
+ logger: props.logger ?? createLogger({
57
+ level: 'debug',
58
+ pretty: process.env.NODE_ENV !== 'production',
59
+ }), ...props
60
+ });
55
61
  this.workspace = workspace;
56
62
  this.events.on('connect', (client, extras) => {
57
63
  const key = client.host + ':' + client.port;
@@ -60,15 +66,20 @@ export class Registry extends Server {
60
66
  this.namespaces.set(namespace, new Set());
61
67
  }
62
68
  this.namespaces.get(namespace).add(key);
69
+ this.logger.debug('[connect] %s/%s', key, namespace);
63
70
  });
64
71
  this.events.on('disconnect', (client, extras) => {
65
72
  const key = client.host + ':' + client.port;
66
73
  // 清理 topic 中的关联(不删除 topic,保留 data 供后续 subscriber 使用)
67
74
  for (const [, { publishers, subscribers }] of this.topics) {
68
- if (publishers.has(key))
75
+ if (publishers.has(key)) {
69
76
  publishers.delete(key);
70
- if (subscribers.has(key))
77
+ this.logger.debug('[delete publisher] %s', key);
78
+ }
79
+ if (subscribers.has(key)) {
71
80
  subscribers.delete(key);
81
+ this.logger.debug('[delete subscriber] %s', key);
82
+ }
72
83
  }
73
84
  // 清理 namespace 中的关联
74
85
  const namespace = extras.join('/');
@@ -76,8 +87,10 @@ export class Registry extends Server {
76
87
  const keys = this.namespaces.get(namespace);
77
88
  if (keys.has(key)) {
78
89
  keys.delete(key);
90
+ this.logger.debug('[disconnect] %s/%s', key, namespace);
79
91
  if (keys.size === 0) {
80
92
  this.namespaces.delete(namespace);
93
+ this.logger.debug('[delete namespace] %s', namespace);
81
94
  }
82
95
  }
83
96
  }
@@ -183,6 +196,7 @@ export class Registry extends Server {
183
196
  entry.data = data.payload;
184
197
  publishers.add(key);
185
198
  this.publish(data.topic, data.payload);
199
+ this.logger.debug('[declare] %s/%s', key, data.topic);
186
200
  return Date.now();
187
201
  }));
188
202
  }
@@ -197,8 +211,10 @@ export class Registry extends Server {
197
211
  const i = publishers.size;
198
212
  if (publishers.has(key)) {
199
213
  publishers.delete(key);
214
+ this.logger.debug('[undeclare] %s/%s', key, data.topic);
200
215
  if (publishers.size === 0 && subscribers.size === 0) {
201
216
  this.topics.delete(data.topic);
217
+ this.logger.debug('[delete topic] %s', data.topic);
202
218
  }
203
219
  }
204
220
  return i - publishers.size;
@@ -213,6 +229,7 @@ export class Registry extends Server {
213
229
  const entry = this.topics.get(data.topic);
214
230
  const subscribers = entry.subscribers;
215
231
  subscribers.add(key);
232
+ this.logger.debug('[subscribe] %s/%s', key, data.topic);
216
233
  return entry.data;
217
234
  }));
218
235
  }
@@ -223,14 +240,11 @@ export class Registry extends Server {
223
240
  return 0;
224
241
  const entry = this.topics.get(data.topic);
225
242
  const subscribers = entry.subscribers;
226
- const publishers = entry.publishers;
227
243
  const i = subscribers.size;
228
244
  if (subscribers.has(key)) {
229
245
  subscribers.delete(key);
230
- if (subscribers.size === 0 && publishers.size === 0) {
231
- this.topics.delete(data.topic);
232
- }
233
246
  }
247
+ this.logger.debug('[unsubscribe] %s/%s', key, data.topic);
234
248
  return i - subscribers.size;
235
249
  }));
236
250
  }
package/dist/server.d.ts CHANGED
@@ -3,6 +3,7 @@ import { Client } from './client.js';
3
3
  import { IncomingMessage } from 'http';
4
4
  import { EventEmitter } from 'node:events';
5
5
  import type { Duplex } from "node:stream";
6
+ import type { Logger } from '@hile/logger';
6
7
  /** {@link MessageLoaderProps} 加上出站 WebSocket 宣告地址 */
7
8
  export type MicroServerProps = MessageLoaderProps & {
8
9
  /**
@@ -10,11 +11,16 @@ export type MicroServerProps = MessageLoaderProps & {
10
11
  * 缺省使用 `getLocalIPv4()`;若仍为 `undefined`(无可用 IPv4)则构造 {@link Server} 时抛错。
11
12
  */
12
13
  advertiseHost?: string;
14
+ /**
15
+ * 日志记录器
16
+ */
17
+ logger?: Logger;
13
18
  };
14
19
  export declare class Server extends MessageLoader {
15
20
  readonly namespace: string;
16
21
  private wss?;
17
22
  port?: number;
23
+ readonly logger: Logger | Console;
18
24
  readonly clients: Map<string, Client>;
19
25
  private readonly announceHost;
20
26
  readonly events: EventEmitter<any>;
package/dist/server.js CHANGED
@@ -9,6 +9,7 @@ export class Server extends MessageLoader {
9
9
  namespace;
10
10
  wss;
11
11
  port;
12
+ logger;
12
13
  clients = new Map();
13
14
  announceHost;
14
15
  events = new EventEmitter();
@@ -16,7 +17,7 @@ export class Server extends MessageLoader {
16
17
  return this.announceHost;
17
18
  }
18
19
  constructor(namespace, props = {}) {
19
- const { advertiseHost, ...loaderProps } = props;
20
+ const { advertiseHost, logger, ...loaderProps } = props;
20
21
  super(loaderProps);
21
22
  this.namespace = namespace;
22
23
  const resolved = advertiseHost?.trim() || getLocalIPv4();
@@ -24,6 +25,7 @@ export class Server extends MessageLoader {
24
25
  throw new Error('Unable to resolve advertise host for @hile/micro Server: pass `advertiseHost` (e.g. "127.0.0.1") in constructor options, or ensure getLocalIPv4() returns an address.');
25
26
  }
26
27
  this.announceHost = resolved;
28
+ this.logger = logger ?? console;
27
29
  this.events.on('connect', (client, extras) => {
28
30
  client.events.emit('connect', extras);
29
31
  });
@@ -133,12 +135,12 @@ export class Server extends MessageLoader {
133
135
  this.wss = new WebSocketServer({ noServer: true });
134
136
  }
135
137
  return async () => {
136
- const toDispose = [...this.clients.values()];
137
- for (const client of toDispose) {
138
- client.dispose();
139
- }
140
- this.clients.clear();
141
138
  if (this.wss) {
139
+ // terminate 立即销毁 socket,不等待对端 close frame
140
+ // 避免 graceful close 时对端无响应导致 HTTP server 无法关闭
141
+ for (const ws of [...this.wss.clients]) {
142
+ ws.terminate();
143
+ }
142
144
  await new Promise((resolve, reject) => {
143
145
  this.wss.close((err) => {
144
146
  if (err)
@@ -147,6 +149,11 @@ export class Server extends MessageLoader {
147
149
  });
148
150
  });
149
151
  }
152
+ const toDispose = [...this.clients.values()];
153
+ for (const client of toDispose) {
154
+ client.dispose();
155
+ }
156
+ this.clients.clear();
150
157
  this.wss = undefined;
151
158
  this.port = undefined;
152
159
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hile/micro",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -23,11 +23,12 @@
23
23
  "vitest": "^4.0.18"
24
24
  },
25
25
  "dependencies": {
26
+ "@hile/logger": "^2.0.1",
26
27
  "@hile/message-loader": "^2.0.1",
27
28
  "@hile/message-ws": "^2.0.3",
28
29
  "internal-ip": "^9.0.0",
29
30
  "ws": "^8.21.0",
30
31
  "yaml": "^2.9.0"
31
32
  },
32
- "gitHead": "adb7e7814470cef03cb577682f76b530b8af761e"
33
+ "gitHead": "aaa46af05d9fe0d658b4f7a8d54ad8da088a10f6"
33
34
  }