@lakutata/nats 2.3.0 → 3.0.0-beta.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 +23 -0
- package/README.md +288 -25
- package/dist/cjs/codecs/JSONCodec.d.ts +32 -0
- package/dist/cjs/codecs/JSONCodec.js +44 -0
- package/dist/cjs/codecs/MessagePackCodec.d.ts +22 -0
- package/dist/cjs/codecs/MessagePackCodec.js +35 -0
- package/dist/cjs/components/NATS.d.ts +376 -0
- package/dist/cjs/components/NATS.js +772 -0
- package/dist/cjs/entrypoints/NatsServiceEntrypoint.d.ts +102 -0
- package/dist/cjs/entrypoints/NatsServiceEntrypoint.js +127 -0
- package/dist/cjs/exceptions/NatsBadRequestException.d.ts +11 -0
- package/dist/cjs/exceptions/NatsBadRequestException.js +18 -0
- package/dist/cjs/exceptions/NatsBulkException.d.ts +19 -0
- package/dist/cjs/exceptions/NatsBulkException.js +26 -0
- package/dist/cjs/exceptions/NatsForbiddenException.d.ts +11 -0
- package/dist/cjs/exceptions/NatsForbiddenException.js +18 -0
- package/dist/cjs/exceptions/NatsInternalServerException.d.ts +12 -0
- package/dist/cjs/exceptions/NatsInternalServerException.js +19 -0
- package/dist/cjs/exceptions/NatsNoRespondersAvailableException.d.ts +12 -0
- package/dist/cjs/exceptions/NatsNoRespondersAvailableException.js +19 -0
- package/dist/cjs/exceptions/NatsNotFoundException.d.ts +11 -0
- package/dist/cjs/exceptions/NatsNotFoundException.js +18 -0
- package/dist/cjs/exceptions/NatsRequestTimeoutException.d.ts +11 -0
- package/dist/cjs/exceptions/NatsRequestTimeoutException.js +18 -0
- package/dist/cjs/exports/Nats.d.ts +18 -0
- package/dist/cjs/exports/Nats.js +39 -0
- package/dist/cjs/interfaces/NatsClientOptions.d.ts +106 -0
- package/dist/{lib → cjs/lib}/ServiceEventCodec.d.ts +0 -1
- package/dist/{lib → cjs/lib}/ServiceEventCodec.js +19 -9
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/providers/ServiceProxy.d.ts +210 -0
- package/dist/cjs/providers/ServiceProxy.js +274 -0
- package/dist/cjs/types/SubscribeOptions.d.ts +33 -0
- package/dist/esm/codecs/JSONCodec.js +41 -0
- package/dist/esm/codecs/MessagePackCodec.js +32 -0
- package/dist/esm/components/NATS.js +767 -0
- package/dist/esm/entrypoints/NatsServiceEntrypoint.js +123 -0
- package/dist/esm/exceptions/NatsBadRequestException.js +14 -0
- package/dist/esm/exceptions/NatsBulkException.js +22 -0
- package/dist/esm/exceptions/NatsForbiddenException.js +14 -0
- package/dist/esm/exceptions/NatsInternalServerException.js +15 -0
- package/dist/esm/exceptions/NatsNoRespondersAvailableException.js +15 -0
- package/dist/esm/exceptions/NatsNotFoundException.js +14 -0
- package/dist/esm/exceptions/NatsRequestTimeoutException.js +14 -0
- package/dist/esm/exports/Nats.js +15 -0
- package/dist/esm/interfaces/NatsClientOptions.js +1 -0
- package/dist/esm/lib/ServiceEventCodec.js +21 -0
- package/dist/esm/providers/ServiceProxy.js +270 -0
- package/dist/esm/types/SubscribeOptions.js +1 -0
- package/dist/types/codecs/JSONCodec.d.ts +32 -0
- package/dist/types/codecs/MessagePackCodec.d.ts +22 -0
- package/dist/types/components/NATS.d.ts +376 -0
- package/dist/types/entrypoints/NatsServiceEntrypoint.d.ts +102 -0
- package/dist/types/exceptions/NatsBadRequestException.d.ts +11 -0
- package/dist/types/exceptions/NatsBulkException.d.ts +19 -0
- package/dist/types/exceptions/NatsForbiddenException.d.ts +11 -0
- package/dist/types/exceptions/NatsInternalServerException.d.ts +12 -0
- package/dist/types/exceptions/NatsNoRespondersAvailableException.d.ts +12 -0
- package/dist/types/exceptions/NatsNotFoundException.d.ts +11 -0
- package/dist/types/exceptions/NatsRequestTimeoutException.d.ts +11 -0
- package/dist/types/exports/Nats.d.ts +18 -0
- package/dist/types/interfaces/NatsClientOptions.d.ts +106 -0
- package/dist/types/lib/ServiceEventCodec.d.ts +9 -0
- package/dist/types/providers/ServiceProxy.d.ts +210 -0
- package/dist/types/types/SubscribeOptions.d.ts +33 -0
- package/package.json +42 -33
- package/CHANGELOG.md +0 -288
- package/dist/CommonExports.d.ts +0 -19
- package/dist/CommonExports.d.ts.map +0 -1
- package/dist/CommonExports.js +0 -35
- package/dist/codecs/JSONCodec.d.ts +0 -3
- package/dist/codecs/JSONCodec.d.ts.map +0 -1
- package/dist/codecs/JSONCodec.js +0 -15
- package/dist/codecs/MessagePackCodec.d.ts +0 -3
- package/dist/codecs/MessagePackCodec.d.ts.map +0 -1
- package/dist/codecs/MessagePackCodec.js +0 -16
- package/dist/components/NATS.d.ts +0 -252
- package/dist/components/NATS.d.ts.map +0 -1
- package/dist/components/NATS.js +0 -564
- package/dist/entrypoints/SetupNatsServiceEntrypoint.d.ts +0 -8
- package/dist/entrypoints/SetupNatsServiceEntrypoint.d.ts.map +0 -1
- package/dist/entrypoints/SetupNatsServiceEntrypoint.js +0 -41
- package/dist/exceptions/NatsBadRequestException.d.ts +0 -7
- package/dist/exceptions/NatsBadRequestException.d.ts.map +0 -1
- package/dist/exceptions/NatsBadRequestException.js +0 -13
- package/dist/exceptions/NatsBulkException.d.ts +0 -11
- package/dist/exceptions/NatsBulkException.d.ts.map +0 -1
- package/dist/exceptions/NatsBulkException.js +0 -17
- package/dist/exceptions/NatsForbiddenException.d.ts +0 -7
- package/dist/exceptions/NatsForbiddenException.d.ts.map +0 -1
- package/dist/exceptions/NatsForbiddenException.js +0 -13
- package/dist/exceptions/NatsInternalServerException.d.ts +0 -7
- package/dist/exceptions/NatsInternalServerException.d.ts.map +0 -1
- package/dist/exceptions/NatsInternalServerException.js +0 -13
- package/dist/exceptions/NatsNoRespondersAvailableException.d.ts +0 -7
- package/dist/exceptions/NatsNoRespondersAvailableException.d.ts.map +0 -1
- package/dist/exceptions/NatsNoRespondersAvailableException.js +0 -13
- package/dist/exceptions/NatsNotFoundException.d.ts +0 -7
- package/dist/exceptions/NatsNotFoundException.d.ts.map +0 -1
- package/dist/exceptions/NatsNotFoundException.js +0 -13
- package/dist/exceptions/NatsRequestTimeoutException.d.ts +0 -7
- package/dist/exceptions/NatsRequestTimeoutException.d.ts.map +0 -1
- package/dist/exceptions/NatsRequestTimeoutException.js +0 -13
- package/dist/exceptions/ServiceInvokeException.d.ts +0 -6
- package/dist/exceptions/ServiceInvokeException.d.ts.map +0 -1
- package/dist/exceptions/ServiceInvokeException.js +0 -11
- package/dist/interfaces/NatsClientOptions.d.ts +0 -26
- package/dist/interfaces/NatsClientOptions.d.ts.map +0 -1
- package/dist/lib/ServiceEventCodec.d.ts.map +0 -1
- package/dist/lib/ServiceResponseCodec.d.ts +0 -22
- package/dist/lib/ServiceResponseCodec.d.ts.map +0 -1
- package/dist/lib/ServiceResponseCodec.js +0 -50
- package/dist/providers/ServiceProxy.d.ts +0 -85
- package/dist/providers/ServiceProxy.d.ts.map +0 -1
- package/dist/providers/ServiceProxy.js +0 -124
- package/dist/types/SubscribeOptions.d.ts +0 -12
- package/dist/types/SubscribeOptions.d.ts.map +0 -1
- package/docs/large-payload-design.md +0 -199
- package/tsconfig.json +0 -8
- /package/dist/{interfaces → cjs/interfaces}/NatsClientOptions.js +0 -0
- /package/dist/{types → cjs/types}/SubscribeOptions.js +0 -0
package/dist/components/NATS.js
DELETED
|
@@ -1,564 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.NATS = exports.buildNatsClientOptions = void 0;
|
|
13
|
-
const lakutata_1 = require("lakutata");
|
|
14
|
-
const di_1 = require("lakutata/decorator/di");
|
|
15
|
-
const nats_1 = require("nats");
|
|
16
|
-
const NatsBadRequestException_1 = require("../exceptions/NatsBadRequestException");
|
|
17
|
-
const NatsForbiddenException_1 = require("../exceptions/NatsForbiddenException");
|
|
18
|
-
const NatsNotFoundException_1 = require("../exceptions/NatsNotFoundException");
|
|
19
|
-
const NatsRequestTimeoutException_1 = require("../exceptions/NatsRequestTimeoutException");
|
|
20
|
-
const NatsNoRespondersAvailableException_1 = require("../exceptions/NatsNoRespondersAvailableException");
|
|
21
|
-
const NatsInternalServerException_1 = require("../exceptions/NatsInternalServerException");
|
|
22
|
-
const NatsBulkException_1 = require("../exceptions/NatsBulkException");
|
|
23
|
-
const ServiceEventCodec_1 = require("../lib/ServiceEventCodec");
|
|
24
|
-
const MessagePackCodec_1 = require("../codecs/MessagePackCodec");
|
|
25
|
-
const node_crypto_1 = require("node:crypto");
|
|
26
|
-
// bulk 中转协议头(放 header,不污染 payload)
|
|
27
|
-
const HDR_BULK = 'X-Lkt-Bulk'; // 能力声明:本端支持 bulk 引用中转
|
|
28
|
-
const HDR_REF = 'X-Lkt-Ref'; // 标记:payload 是 Object Store 引用 {__ref}
|
|
29
|
-
const buildNatsClientOptions = (options) => {
|
|
30
|
-
return {
|
|
31
|
-
class: NATS,
|
|
32
|
-
servers: options.servers,
|
|
33
|
-
codec: options.codec,
|
|
34
|
-
timeout: options.timeout,
|
|
35
|
-
token: options.token,
|
|
36
|
-
user: options.user,
|
|
37
|
-
pass: options.pass,
|
|
38
|
-
debug: options.debug,
|
|
39
|
-
maxPingOut: options.maxPingOut,
|
|
40
|
-
maxReconnectAttempts: options.maxReconnectAttempts,
|
|
41
|
-
name: options.name,
|
|
42
|
-
noEcho: options.noEcho,
|
|
43
|
-
noRandomize: options.noRandomize,
|
|
44
|
-
pingInterval: options.pingInterval,
|
|
45
|
-
reconnect: options.reconnect,
|
|
46
|
-
bulk: options.bulk,
|
|
47
|
-
bulkBucket: options.bulkBucket,
|
|
48
|
-
bulkTTL: options.bulkTTL,
|
|
49
|
-
bulkReplicas: options.bulkReplicas
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
exports.buildNatsClientOptions = buildNatsClientOptions;
|
|
53
|
-
class NATS extends lakutata_1.Component {
|
|
54
|
-
constructor() {
|
|
55
|
-
super(...arguments);
|
|
56
|
-
/**
|
|
57
|
-
* Service event subscription map
|
|
58
|
-
* @protected
|
|
59
|
-
*/
|
|
60
|
-
this.serviceEventSubscriptionMap = new Map();
|
|
61
|
-
/**
|
|
62
|
-
* 缓存对端(按 subject)是否支持 bulk 中转,从对方响应/请求的能力声明 header 学到。
|
|
63
|
-
* 用于请求侧判断对端:已知支持才发引用,未知/不支持则直传(向后兼容)。
|
|
64
|
-
* @private
|
|
65
|
-
*/
|
|
66
|
-
this.#peerCapabilityCache = new Map();
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* NATS client instance
|
|
70
|
-
* @private
|
|
71
|
-
*/
|
|
72
|
-
#conn;
|
|
73
|
-
/**
|
|
74
|
-
* bulk 连接与 Object Store(仅 bulk 启用时存在)
|
|
75
|
-
* @private
|
|
76
|
-
*/
|
|
77
|
-
#bulkConn;
|
|
78
|
-
#objectStore;
|
|
79
|
-
/**
|
|
80
|
-
* 缓存对端(按 subject)是否支持 bulk 中转,从对方响应/请求的能力声明 header 学到。
|
|
81
|
-
* 用于请求侧判断对端:已知支持才发引用,未知/不支持则直传(向后兼容)。
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
#peerCapabilityCache;
|
|
85
|
-
/**
|
|
86
|
-
* Initializer
|
|
87
|
-
* @protected
|
|
88
|
-
*/
|
|
89
|
-
async init() {
|
|
90
|
-
const connectOptions = {
|
|
91
|
-
servers: this.servers,
|
|
92
|
-
user: this.user,
|
|
93
|
-
pass: this.pass,
|
|
94
|
-
timeout: this.timeout,
|
|
95
|
-
token: this.token,
|
|
96
|
-
debug: this.debug,
|
|
97
|
-
maxPingOut: this.maxPingOut,
|
|
98
|
-
maxReconnectAttempts: this.maxReconnectAttempts,
|
|
99
|
-
name: this.name,
|
|
100
|
-
noEcho: this.noEcho,
|
|
101
|
-
noRandomize: this.noRandomize,
|
|
102
|
-
pingInterval: this.pingInterval,
|
|
103
|
-
reconnect: this.reconnect
|
|
104
|
-
};
|
|
105
|
-
this.#conn = await (0, nats_1.connect)(connectOptions);
|
|
106
|
-
if (this.bulk) {
|
|
107
|
-
try {
|
|
108
|
-
// 用同一套配置再开一条【独立】连接专供大数据,避免大对象传输堵塞 core RPC 连接;
|
|
109
|
-
// 并 get-or-create 一个 Object Store bucket 做大对象中转(短 TTL 自动清理)。
|
|
110
|
-
this.#bulkConn = await (0, nats_1.connect)({
|
|
111
|
-
...connectOptions,
|
|
112
|
-
name: this.name ? `${this.name}-bulk` : undefined
|
|
113
|
-
});
|
|
114
|
-
const bucket = this.bulkBucket ?? `lkt-bulk-${this.name ?? 'default'}`;
|
|
115
|
-
// 仅在用户【显式】配置了 bulkReplicas 时才下发 replicas;默认(undefined)不发该字段,
|
|
116
|
-
// 让 server 用默认单副本。无条件发 replicas 在严格校验的 NATS server 上会被
|
|
117
|
-
// 拒绝(invalid json: unknown field "replicas"),且默认单副本显式下发本就没有收益。
|
|
118
|
-
const osOptions = {
|
|
119
|
-
storage: nats_1.StorageType.File,
|
|
120
|
-
ttl: (0, nats_1.nanos)(this.bulkTTL ?? 5 * 60 * 1000)
|
|
121
|
-
};
|
|
122
|
-
if (this.bulkReplicas !== undefined)
|
|
123
|
-
osOptions.replicas = this.bulkReplicas;
|
|
124
|
-
this.#objectStore = await this.#bulkConn.jetstream().views.os(bucket, osOptions);
|
|
125
|
-
}
|
|
126
|
-
catch (e) {
|
|
127
|
-
// 优雅降级:bulk 初始化失败(JetStream 不可用 / 创建被拒 / 超时等)绝不阻塞启动。
|
|
128
|
-
// 清理半建连接并禁用 bulk(bulkEnabled 依赖 #objectStore → 自动转 false),warn 后继续,
|
|
129
|
-
// 核心 RPC/事件照常工作,仅大数据中转不可用。
|
|
130
|
-
this.#objectStore = undefined;
|
|
131
|
-
if (this.#bulkConn) {
|
|
132
|
-
try {
|
|
133
|
-
await this.#bulkConn.close();
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
// 忽略关闭错误
|
|
137
|
-
}
|
|
138
|
-
this.#bulkConn = undefined;
|
|
139
|
-
}
|
|
140
|
-
console.warn(`[NATS] bulk 旁路初始化失败,已自动禁用 bulk(核心 RPC/事件不受影响,仅大数据中转不可用): ${e?.message ?? e}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Destroyer
|
|
146
|
-
* @protected
|
|
147
|
-
*/
|
|
148
|
-
async destroy() {
|
|
149
|
-
await this.drainConnection(this.#conn);
|
|
150
|
-
if (this.#bulkConn)
|
|
151
|
-
await this.drainConnection(this.#bulkConn);
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* 优雅停机:drain 停止接收新消息、把 in-flight 处理完、flush 出站后再关闭,
|
|
155
|
-
* 这样 K8s 滚动升级/缩容时正在处理的请求不被硬切断;drain 失败兜底强制关闭。
|
|
156
|
-
* @param conn
|
|
157
|
-
* @private
|
|
158
|
-
*/
|
|
159
|
-
async drainConnection(conn) {
|
|
160
|
-
try {
|
|
161
|
-
await conn.drain();
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
try {
|
|
165
|
-
await conn.close();
|
|
166
|
-
}
|
|
167
|
-
catch {
|
|
168
|
-
// 连接已不可用,忽略
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Publishes the specified data to the specified subject.
|
|
174
|
-
* @param subject
|
|
175
|
-
* @param payload
|
|
176
|
-
*/
|
|
177
|
-
publish(subject, payload) {
|
|
178
|
-
return this.#conn.publish(subject, this.codec.encode(payload));
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Publishes a request with specified data in the specified subject expecting a
|
|
182
|
-
* response before timeout milliseconds. The api returns a
|
|
183
|
-
* Promise that resolves when the first response to the request is received. If
|
|
184
|
-
* there are no responders (a subscription) listening on the request subject,
|
|
185
|
-
* the request will fail as soon as the server processes it
|
|
186
|
-
* @param subject
|
|
187
|
-
* @param payload
|
|
188
|
-
* @param timeout
|
|
189
|
-
*/
|
|
190
|
-
async request(subject, payload, timeout) {
|
|
191
|
-
const reqHeaders = (0, nats_1.headers)();
|
|
192
|
-
if (this.bulkEnabled)
|
|
193
|
-
reqHeaders.set(HDR_BULK, '1'); // 仅本端启用 bulk 时声明能力
|
|
194
|
-
const peerSupports = this.#peerCapabilityCache.get(subject) === true;
|
|
195
|
-
const packed = await this.packPayload(payload, peerSupports);
|
|
196
|
-
if (packed.isRef)
|
|
197
|
-
reqHeaders.set(HDR_REF, '1');
|
|
198
|
-
try {
|
|
199
|
-
const response = await this.#conn.request(subject, packed.bytes, { timeout: timeout ? timeout : 0, headers: reqHeaders });
|
|
200
|
-
// 双向协商:从响应学习对端是否支持中转
|
|
201
|
-
this.#peerCapabilityCache.set(subject, response.headers?.get(HDR_BULK) === '1');
|
|
202
|
-
// 还原响应(可能是 Object Store 引用)
|
|
203
|
-
return await this.unpackPayload(response.data, response.headers?.get(HDR_REF) === '1');
|
|
204
|
-
}
|
|
205
|
-
catch (e) {
|
|
206
|
-
if (e.code) {
|
|
207
|
-
switch (e.code.toString()) {
|
|
208
|
-
case '400':
|
|
209
|
-
throw new NatsBadRequestException_1.NatsBadRequestException();
|
|
210
|
-
case '403':
|
|
211
|
-
throw new NatsForbiddenException_1.NatsForbiddenException();
|
|
212
|
-
case '404':
|
|
213
|
-
throw new NatsNotFoundException_1.NatsNotFoundException();
|
|
214
|
-
case '408':
|
|
215
|
-
case 'TIMEOUT':
|
|
216
|
-
throw new NatsRequestTimeoutException_1.NatsRequestTimeoutException();
|
|
217
|
-
case '503':
|
|
218
|
-
throw new NatsNoRespondersAvailableException_1.NatsNoRespondersAvailableException();
|
|
219
|
-
case '500':
|
|
220
|
-
throw new NatsInternalServerException_1.NatsInternalServerException();
|
|
221
|
-
default:
|
|
222
|
-
throw e;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
throw e;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
finally {
|
|
230
|
-
// 请求引用对象:服务端已取回(响应已返回),删除;失败靠 TTL 兜底
|
|
231
|
-
if (packed.objId)
|
|
232
|
-
this.deleteBulk(packed.objId).catch(() => undefined);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Subscribe expresses interest in the specified subject. The subject may
|
|
237
|
-
* have wildcards. Messages are delivered to the callback.
|
|
238
|
-
* If the subscription receives request, the callback return's value will respond to requester
|
|
239
|
-
* @param subject
|
|
240
|
-
* @param callback receives (data, subject) — `subject` is the concrete subject the message
|
|
241
|
-
* arrived on, letting wildcard subscribers read routing tokens (e.g. an id embedded in the
|
|
242
|
-
* subject) without the publisher having to duplicate them into the payload.
|
|
243
|
-
* @param subscribeOptions
|
|
244
|
-
*/
|
|
245
|
-
subscribe(subject, callback, subscribeOptions) {
|
|
246
|
-
const subscription = this.#conn.subscribe(subject, {
|
|
247
|
-
queue: subscribeOptions?.queue,
|
|
248
|
-
max: subscribeOptions?.max
|
|
249
|
-
});
|
|
250
|
-
const handleMessage = async (msg) => {
|
|
251
|
-
try {
|
|
252
|
-
// 入站:若标记为引用,从 Object Store 取回真实 payload(对小消息/event 透明)
|
|
253
|
-
const data = await this.unpackPayload(msg.data, msg.headers?.get(HDR_REF) === '1');
|
|
254
|
-
const result = await callback(data, msg.subject);
|
|
255
|
-
// 仅当消息是请求(带 reply)时才回响应;publish/event 无 reply,跳过。
|
|
256
|
-
if (msg.reply) {
|
|
257
|
-
const respHeaders = (0, nats_1.headers)();
|
|
258
|
-
if (this.bulkEnabled)
|
|
259
|
-
respHeaders.set(HDR_BULK, '1'); // 仅本端启用 bulk 时声明能力
|
|
260
|
-
// 请求方是否支持中转 → 决定大响应能否走引用
|
|
261
|
-
const clientSupports = msg.headers?.get(HDR_BULK) === '1';
|
|
262
|
-
const packed = await this.packPayload(result, clientSupports);
|
|
263
|
-
if (packed.isRef)
|
|
264
|
-
respHeaders.set(HDR_REF, '1');
|
|
265
|
-
msg.respond(packed.bytes, { headers: respHeaders });
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
catch (e) {
|
|
269
|
-
this.emitError(e);
|
|
270
|
-
// 若是请求且上层提供了错误响应工厂,回标准失败响应(直传 + 能力声明),避免请求方挂到超时。
|
|
271
|
-
if (msg.reply && subscribeOptions?.errorResponse) {
|
|
272
|
-
try {
|
|
273
|
-
const errHeaders = (0, nats_1.headers)();
|
|
274
|
-
if (this.bulkEnabled)
|
|
275
|
-
errHeaders.set(HDR_BULK, '1');
|
|
276
|
-
const errorPayload = subscribeOptions.errorResponse(e);
|
|
277
|
-
if (errorPayload !== undefined)
|
|
278
|
-
msg.respond(this.codec.encode(errorPayload), { headers: errHeaders });
|
|
279
|
-
}
|
|
280
|
-
catch (encodeError) {
|
|
281
|
-
this.emitError(encodeError);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
if (subscribeOptions?.iterator) {
|
|
287
|
-
setImmediate(async () => {
|
|
288
|
-
for await (const msg of subscription) {
|
|
289
|
-
await handleMessage(msg);
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
subscription.callback = async (err, msg) => {
|
|
295
|
-
// nats.js 在订阅级错误时以 (err, {}) 回调,此时 msg 为空对象无法处理,上报后返回。
|
|
296
|
-
if (err) {
|
|
297
|
-
this.emitError(err);
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
await handleMessage(msg);
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
return subscription;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* 安全地发出 error 事件:仅在存在监听器时发出。
|
|
307
|
-
* Node EventEmitter 在没有 'error' 监听器时 emit('error') 会抛出,
|
|
308
|
-
* 在异步回调里那会变成 unhandled rejection,所以这里加监听器守卫。
|
|
309
|
-
* @param error
|
|
310
|
-
* @protected
|
|
311
|
-
*/
|
|
312
|
-
emitError(error) {
|
|
313
|
-
if (this.listenerCount('error') > 0)
|
|
314
|
-
this.emit('error', error);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* 是否启用了 bulk 旁路(连接 + Object Store 均就绪)
|
|
318
|
-
*/
|
|
319
|
-
get bulkEnabled() {
|
|
320
|
-
return !!this.bulk && !!this.#objectStore;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* 走 bulk 的字节阈值 = server max_payload × 0.9(从连接 info 自动读,跟随集群配置)
|
|
324
|
-
*/
|
|
325
|
-
get bulkThreshold() {
|
|
326
|
-
const maxPayload = this.#conn.info?.max_payload ?? 1024 * 1024;
|
|
327
|
-
return Math.floor(maxPayload * 0.9);
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* server 是否支持消息 header(从连接 info)
|
|
331
|
-
*/
|
|
332
|
-
get headersSupported() {
|
|
333
|
-
return this.#conn.info?.headers === true;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* 把一块字节存入 Object Store,返回 objId(供引用中转)。
|
|
337
|
-
* @param bytes
|
|
338
|
-
*/
|
|
339
|
-
async putBulk(bytes) {
|
|
340
|
-
if (!this.#objectStore)
|
|
341
|
-
throw new NatsBulkException_1.NatsBulkException('bulk channel is not enabled');
|
|
342
|
-
const objId = (0, node_crypto_1.randomUUID)();
|
|
343
|
-
try {
|
|
344
|
-
await this.#objectStore.putBlob({ name: objId }, bytes);
|
|
345
|
-
}
|
|
346
|
-
catch (e) {
|
|
347
|
-
throw new NatsBulkException_1.NatsBulkException(`bulk put failed: ${e?.message ?? e}`);
|
|
348
|
-
}
|
|
349
|
-
return objId;
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* 从 Object Store 取回一块字节。
|
|
353
|
-
* @param objId
|
|
354
|
-
*/
|
|
355
|
-
async getBulk(objId) {
|
|
356
|
-
if (!this.#objectStore)
|
|
357
|
-
throw new NatsBulkException_1.NatsBulkException('bulk channel is not enabled');
|
|
358
|
-
let data;
|
|
359
|
-
try {
|
|
360
|
-
data = await this.#objectStore.getBlob(objId);
|
|
361
|
-
}
|
|
362
|
-
catch (e) {
|
|
363
|
-
throw new NatsBulkException_1.NatsBulkException(`bulk get failed: ${e?.message ?? e}`);
|
|
364
|
-
}
|
|
365
|
-
if (data === null)
|
|
366
|
-
throw new NatsBulkException_1.NatsBulkException(`bulk object not found: ${objId}`);
|
|
367
|
-
return data;
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* 删除 Object Store 中的对象(用完即清,失败由 TTL 兜底)。
|
|
371
|
-
* @param objId
|
|
372
|
-
*/
|
|
373
|
-
async deleteBulk(objId) {
|
|
374
|
-
if (!this.#objectStore)
|
|
375
|
-
return;
|
|
376
|
-
await this.#objectStore.delete(objId);
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* 返回 bulk Object Store 的运行时状态(bucket/ttl/replicas/storage/size 等);未启用 bulk 返回 undefined。
|
|
380
|
-
*/
|
|
381
|
-
async bulkStatus() {
|
|
382
|
-
return this.#objectStore?.status();
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* 打包待发送 payload:编码后若对端支持中转且超阈值,存入 Object Store 改发小引用。
|
|
386
|
-
* @param payload
|
|
387
|
-
* @param peerSupportsBulk 对端是否支持引用中转(不支持只能直传)
|
|
388
|
-
* @private
|
|
389
|
-
*/
|
|
390
|
-
async packPayload(payload, peerSupportsBulk) {
|
|
391
|
-
const bytes = this.codec.encode(payload);
|
|
392
|
-
if (peerSupportsBulk && this.bulkEnabled && bytes.length >= this.bulkThreshold) {
|
|
393
|
-
const objId = await this.putBulk(bytes);
|
|
394
|
-
return { bytes: this.codec.encode({ __ref: objId }), isRef: true, objId };
|
|
395
|
-
}
|
|
396
|
-
return { bytes, isRef: false };
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* 解包收到的字节:若是引用,从 Object Store 取回真实字节再解码(取回后即删,失败靠 TTL 兜底)。
|
|
400
|
-
* @param bytes
|
|
401
|
-
* @param isRef
|
|
402
|
-
* @private
|
|
403
|
-
*/
|
|
404
|
-
async unpackPayload(bytes, isRef) {
|
|
405
|
-
if (isRef) {
|
|
406
|
-
const ref = this.codec.decode(bytes);
|
|
407
|
-
const realBytes = await this.getBulk(ref.__ref);
|
|
408
|
-
this.deleteBulk(ref.__ref).catch(() => undefined);
|
|
409
|
-
return this.codec.decode(realBytes);
|
|
410
|
-
}
|
|
411
|
-
return this.codec.decode(bytes);
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* Emit service event
|
|
415
|
-
* @param eventName
|
|
416
|
-
* @param args
|
|
417
|
-
*/
|
|
418
|
-
emitServiceEvent(eventName, ...args) {
|
|
419
|
-
const eventSubject = ServiceEventCodec_1.ServiceEventCodec.formatSubject(this.app.appId, eventName);
|
|
420
|
-
this.publish(eventSubject, ServiceEventCodec_1.ServiceEventCodec.encode(args));
|
|
421
|
-
return this;
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* On service event
|
|
425
|
-
* @param serviceId
|
|
426
|
-
* @param eventName
|
|
427
|
-
* @param listener
|
|
428
|
-
* @param onlySingleClientReceived
|
|
429
|
-
*/
|
|
430
|
-
onServiceEvent(serviceId, eventName, listener, onlySingleClientReceived = false) {
|
|
431
|
-
const eventSubject = ServiceEventCodec_1.ServiceEventCodec.formatSubject(serviceId, eventName);
|
|
432
|
-
if (!this.serviceEventSubscriptionMap.has(eventSubject))
|
|
433
|
-
this.serviceEventSubscriptionMap.set(eventSubject, new Map());
|
|
434
|
-
if (!this.serviceEventSubscriptionMap.get(eventSubject)?.has(listener)) {
|
|
435
|
-
const subscription = this.subscribe(eventSubject, (eventData) => {
|
|
436
|
-
listener(...ServiceEventCodec_1.ServiceEventCodec.decode(eventData));
|
|
437
|
-
}, onlySingleClientReceived ? { queue: eventSubject } : void (0));
|
|
438
|
-
this.serviceEventSubscriptionMap.get(eventSubject)?.set(listener, subscription);
|
|
439
|
-
}
|
|
440
|
-
return this;
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Once service event
|
|
444
|
-
* @param serviceId
|
|
445
|
-
* @param eventName
|
|
446
|
-
* @param listener
|
|
447
|
-
*/
|
|
448
|
-
onceServiceEvent(serviceId, eventName, listener) {
|
|
449
|
-
const eventSubject = ServiceEventCodec_1.ServiceEventCodec.formatSubject(serviceId, eventName);
|
|
450
|
-
if (!this.serviceEventSubscriptionMap.has(eventSubject))
|
|
451
|
-
this.serviceEventSubscriptionMap.set(eventSubject, new Map());
|
|
452
|
-
if (!this.serviceEventSubscriptionMap.get(eventSubject)?.has(listener)) {
|
|
453
|
-
const subscription = this.subscribe(eventSubject, (eventData) => {
|
|
454
|
-
this.serviceEventSubscriptionMap.get(eventSubject)?.delete(listener);
|
|
455
|
-
listener(...ServiceEventCodec_1.ServiceEventCodec.decode(eventData));
|
|
456
|
-
}, { max: 1 });
|
|
457
|
-
this.serviceEventSubscriptionMap.get(eventSubject)?.set(listener, subscription);
|
|
458
|
-
}
|
|
459
|
-
return this;
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* Off server events
|
|
463
|
-
* @param serviceId
|
|
464
|
-
* @param eventName
|
|
465
|
-
* @param listener
|
|
466
|
-
*/
|
|
467
|
-
offServiceEvent(serviceId, eventName, listener) {
|
|
468
|
-
const eventSubject = ServiceEventCodec_1.ServiceEventCodec.formatSubject(serviceId, eventName);
|
|
469
|
-
if (listener) {
|
|
470
|
-
this.serviceEventSubscriptionMap.get(eventSubject)?.get(listener)?.unsubscribe();
|
|
471
|
-
this.serviceEventSubscriptionMap.get(eventSubject)?.delete(listener);
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
this.serviceEventSubscriptionMap.get(eventSubject)?.forEach((subscription) => subscription.unsubscribe());
|
|
475
|
-
this.serviceEventSubscriptionMap.delete(eventSubject);
|
|
476
|
-
}
|
|
477
|
-
return this;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
exports.NATS = NATS;
|
|
481
|
-
__decorate([
|
|
482
|
-
(0, di_1.Inject)(lakutata_1.Application),
|
|
483
|
-
__metadata("design:type", lakutata_1.Application
|
|
484
|
-
/**
|
|
485
|
-
* NATS servers
|
|
486
|
-
* @protected
|
|
487
|
-
*/
|
|
488
|
-
)
|
|
489
|
-
], NATS.prototype, "app", void 0);
|
|
490
|
-
__decorate([
|
|
491
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Alternatives(lakutata_1.DTO.String(), lakutata_1.DTO.Array(lakutata_1.DTO.String())).required()),
|
|
492
|
-
__metadata("design:type", Object)
|
|
493
|
-
], NATS.prototype, "servers", void 0);
|
|
494
|
-
__decorate([
|
|
495
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Object({
|
|
496
|
-
encode: lakutata_1.DTO.Function().arity(1).required(),
|
|
497
|
-
decode: lakutata_1.DTO.Function().arity(1).required()
|
|
498
|
-
}).optional().default((0, MessagePackCodec_1.MessagePackCodec)())),
|
|
499
|
-
__metadata("design:type", Object)
|
|
500
|
-
], NATS.prototype, "codec", void 0);
|
|
501
|
-
__decorate([
|
|
502
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Number().integer().optional()),
|
|
503
|
-
__metadata("design:type", Number)
|
|
504
|
-
], NATS.prototype, "timeout", void 0);
|
|
505
|
-
__decorate([
|
|
506
|
-
(0, di_1.Configurable)(lakutata_1.DTO.String().optional()),
|
|
507
|
-
__metadata("design:type", String)
|
|
508
|
-
], NATS.prototype, "token", void 0);
|
|
509
|
-
__decorate([
|
|
510
|
-
(0, di_1.Configurable)(lakutata_1.DTO.String().optional()),
|
|
511
|
-
__metadata("design:type", String)
|
|
512
|
-
], NATS.prototype, "user", void 0);
|
|
513
|
-
__decorate([
|
|
514
|
-
(0, di_1.Configurable)(lakutata_1.DTO.String().optional()),
|
|
515
|
-
__metadata("design:type", String)
|
|
516
|
-
], NATS.prototype, "pass", void 0);
|
|
517
|
-
__decorate([
|
|
518
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Boolean().optional()),
|
|
519
|
-
__metadata("design:type", Boolean)
|
|
520
|
-
], NATS.prototype, "debug", void 0);
|
|
521
|
-
__decorate([
|
|
522
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Number().optional()),
|
|
523
|
-
__metadata("design:type", Number)
|
|
524
|
-
], NATS.prototype, "maxPingOut", void 0);
|
|
525
|
-
__decorate([
|
|
526
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Number().optional().default(10)),
|
|
527
|
-
__metadata("design:type", Number)
|
|
528
|
-
], NATS.prototype, "maxReconnectAttempts", void 0);
|
|
529
|
-
__decorate([
|
|
530
|
-
(0, di_1.Configurable)(lakutata_1.DTO.String().optional()),
|
|
531
|
-
__metadata("design:type", String)
|
|
532
|
-
], NATS.prototype, "name", void 0);
|
|
533
|
-
__decorate([
|
|
534
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Boolean().optional()),
|
|
535
|
-
__metadata("design:type", Boolean)
|
|
536
|
-
], NATS.prototype, "noEcho", void 0);
|
|
537
|
-
__decorate([
|
|
538
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Boolean().optional()),
|
|
539
|
-
__metadata("design:type", Boolean)
|
|
540
|
-
], NATS.prototype, "noRandomize", void 0);
|
|
541
|
-
__decorate([
|
|
542
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Number().optional().default(1000 * 60 * 2)),
|
|
543
|
-
__metadata("design:type", Number)
|
|
544
|
-
], NATS.prototype, "pingInterval", void 0);
|
|
545
|
-
__decorate([
|
|
546
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Boolean().optional().default(true)),
|
|
547
|
-
__metadata("design:type", Boolean)
|
|
548
|
-
], NATS.prototype, "reconnect", void 0);
|
|
549
|
-
__decorate([
|
|
550
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Boolean().optional().default(true)),
|
|
551
|
-
__metadata("design:type", Boolean)
|
|
552
|
-
], NATS.prototype, "bulk", void 0);
|
|
553
|
-
__decorate([
|
|
554
|
-
(0, di_1.Configurable)(lakutata_1.DTO.String().optional()),
|
|
555
|
-
__metadata("design:type", String)
|
|
556
|
-
], NATS.prototype, "bulkBucket", void 0);
|
|
557
|
-
__decorate([
|
|
558
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Number().integer().optional().default(5 * 60 * 1000)),
|
|
559
|
-
__metadata("design:type", Number)
|
|
560
|
-
], NATS.prototype, "bulkTTL", void 0);
|
|
561
|
-
__decorate([
|
|
562
|
-
(0, di_1.Configurable)(lakutata_1.DTO.Number().integer().optional()),
|
|
563
|
-
__metadata("design:type", Number)
|
|
564
|
-
], NATS.prototype, "bulkReplicas", void 0);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { ServiceEntrypoint } from 'lakutata/com/entrypoint';
|
|
2
|
-
/**
|
|
3
|
-
* Setup service based on NATS
|
|
4
|
-
* @param natsComponentName
|
|
5
|
-
* @constructor
|
|
6
|
-
*/
|
|
7
|
-
export declare function SetupNatsServiceEntrypoint(natsComponentName: string): ServiceEntrypoint;
|
|
8
|
-
//# sourceMappingURL=SetupNatsServiceEntrypoint.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SetupNatsServiceEntrypoint.d.ts","sourceRoot":"","sources":["../../src/entrypoints/SetupNatsServiceEntrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,iBAAiB,EAEpB,MAAM,yBAAyB,CAAA;AAehC;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,iBAAiB,EAAE,MAAM,GAAG,iBAAiB,CAmBvF"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SetupNatsServiceEntrypoint = void 0;
|
|
4
|
-
const entrypoint_1 = require("lakutata/com/entrypoint");
|
|
5
|
-
const ServiceResponseCodec_1 = require("../lib/ServiceResponseCodec");
|
|
6
|
-
/**
|
|
7
|
-
* 把异常拷成可序列化的普通对象(保留 message/errno/statusCode 等自有属性)。
|
|
8
|
-
* @param error
|
|
9
|
-
*/
|
|
10
|
-
function toErrorObject(error) {
|
|
11
|
-
const errorObject = {};
|
|
12
|
-
Object.getOwnPropertyNames(error).forEach((prop) => errorObject[prop] = error[prop]);
|
|
13
|
-
return errorObject;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Setup service based on NATS
|
|
17
|
-
* @param natsComponentName
|
|
18
|
-
* @constructor
|
|
19
|
-
*/
|
|
20
|
-
function SetupNatsServiceEntrypoint(natsComponentName) {
|
|
21
|
-
return (0, entrypoint_1.BuildServiceEntrypoint)(async (module, handler) => {
|
|
22
|
-
const nats = await module.getObject(natsComponentName);
|
|
23
|
-
const appId = module.appId;
|
|
24
|
-
nats.subscribe(appId, async (incomeRequestPayload) => {
|
|
25
|
-
try {
|
|
26
|
-
return ServiceResponseCodec_1.ServiceResponseCodec.encode(await handler(new entrypoint_1.ServiceContext({
|
|
27
|
-
data: incomeRequestPayload
|
|
28
|
-
})), false);
|
|
29
|
-
}
|
|
30
|
-
catch (e) {
|
|
31
|
-
return ServiceResponseCodec_1.ServiceResponseCodec.encode(toErrorObject(e), true);
|
|
32
|
-
}
|
|
33
|
-
}, {
|
|
34
|
-
queue: `${appId}.serviceQueue`,
|
|
35
|
-
// 入站 decode 失败 / 出站 encode 失败等发生在 handler 之外(subscribe 层)的错误,
|
|
36
|
-
// 由此工厂统一回成标准失败响应,避免请求方挂到超时。
|
|
37
|
-
errorResponse: (e) => ServiceResponseCodec_1.ServiceResponseCodec.encode(toErrorObject(e), true)
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
exports.SetupNatsServiceEntrypoint = SetupNatsServiceEntrypoint;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NatsBadRequestException.d.ts","sourceRoot":"","sources":["../../src/exceptions/NatsBadRequestException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAA;AAElC,qBAAa,uBAAwB,SAAQ,SAAS;IAC3C,KAAK,EAAE,MAAM,GAAG,MAAM,CAAuB;IAC7C,OAAO,EAAE,MAAM,CAAgB;IAC/B,UAAU,EAAE,MAAM,CAAM;CAClC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NatsBadRequestException = void 0;
|
|
4
|
-
const lakutata_1 = require("lakutata");
|
|
5
|
-
class NatsBadRequestException extends lakutata_1.Exception {
|
|
6
|
-
constructor() {
|
|
7
|
-
super(...arguments);
|
|
8
|
-
this.errno = 'E_NATS_BAD_REQUEST';
|
|
9
|
-
this.message = 'Bad Request';
|
|
10
|
-
this.statusCode = 400;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
exports.NatsBadRequestException = NatsBadRequestException;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Exception } from 'lakutata';
|
|
2
|
-
/**
|
|
3
|
-
* bulk 中转层故障(Object Store put/get 失败、引用过期取不到、bulk 未启用等)。
|
|
4
|
-
* 表示"大数据通道出问题",区别于业务错误;不应自动重试(响应取不到时对侧可能已处理)。
|
|
5
|
-
* message 由抛出处给出具体原因(不设默认值,以保留原因)。
|
|
6
|
-
*/
|
|
7
|
-
export declare class NatsBulkException extends Exception {
|
|
8
|
-
errno: string | number;
|
|
9
|
-
statusCode: number;
|
|
10
|
-
}
|
|
11
|
-
//# sourceMappingURL=NatsBulkException.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NatsBulkException.d.ts","sourceRoot":"","sources":["../../src/exceptions/NatsBulkException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAA;AAElC;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IACrC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAgB;IACtC,UAAU,EAAE,MAAM,CAAM;CAClC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NatsBulkException = void 0;
|
|
4
|
-
const lakutata_1 = require("lakutata");
|
|
5
|
-
/**
|
|
6
|
-
* bulk 中转层故障(Object Store put/get 失败、引用过期取不到、bulk 未启用等)。
|
|
7
|
-
* 表示"大数据通道出问题",区别于业务错误;不应自动重试(响应取不到时对侧可能已处理)。
|
|
8
|
-
* message 由抛出处给出具体原因(不设默认值,以保留原因)。
|
|
9
|
-
*/
|
|
10
|
-
class NatsBulkException extends lakutata_1.Exception {
|
|
11
|
-
constructor() {
|
|
12
|
-
super(...arguments);
|
|
13
|
-
this.errno = 'E_NATS_BULK';
|
|
14
|
-
this.statusCode = 502;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
exports.NatsBulkException = NatsBulkException;
|