@lad-tech/nsc-toolkit 1.28.1 → 1.28.2

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.
Files changed (48) hide show
  1. package/.vscode/launch.json +77 -0
  2. package/.vscode/tasks.json +25 -0
  3. package/package.json +1 -1
  4. package/CHANGELOG.md +0 -6
  5. package/dist/Client.js +0 -303
  6. package/dist/Container.js +0 -124
  7. package/dist/Meter.js +0 -77
  8. package/dist/Method.js +0 -7
  9. package/dist/Root.js +0 -120
  10. package/dist/Service.js +0 -677
  11. package/dist/StreamBatchMsgFetcher.js +0 -17
  12. package/dist/StreamManager.js +0 -173
  13. package/dist/StreamOptions/BufferToJsonTransform.js +0 -34
  14. package/dist/StreamOptions/JsonToBufferTransform.js +0 -11
  15. package/dist/StreamOptions/index.js +0 -19
  16. package/dist/StreamSingleMsgFetcher.js +0 -28
  17. package/dist/Union/Broker.js +0 -95
  18. package/dist/Union/ConsumerApi.js +0 -28
  19. package/dist/Union/JetStreamClient.js +0 -40
  20. package/dist/Union/JetStreamManager.js +0 -26
  21. package/dist/Union/StreamApi.js +0 -46
  22. package/dist/Union/Subscription.js +0 -47
  23. package/dist/Union/index.js +0 -18
  24. package/dist/index.js +0 -24
  25. package/dist/injector.js +0 -65
  26. package/dist/interfaces.js +0 -16
  27. package/dist/types/Client.d.ts +0 -32
  28. package/dist/types/Container.d.ts +0 -54
  29. package/dist/types/Meter.d.ts +0 -13
  30. package/dist/types/Method.d.ts +0 -6
  31. package/dist/types/Root.d.ts +0 -29
  32. package/dist/types/Service.d.ts +0 -140
  33. package/dist/types/StreamBatchMsgFetcher.d.ts +0 -13
  34. package/dist/types/StreamManager.d.ts +0 -26
  35. package/dist/types/StreamOptions/BufferToJsonTransform.d.ts +0 -14
  36. package/dist/types/StreamOptions/JsonToBufferTransform.d.ts +0 -6
  37. package/dist/types/StreamOptions/index.d.ts +0 -2
  38. package/dist/types/StreamSingleMsgFetcher.d.ts +0 -16
  39. package/dist/types/Union/Broker.d.ts +0 -32
  40. package/dist/types/Union/ConsumerApi.d.ts +0 -16
  41. package/dist/types/Union/JetStreamClient.d.ts +0 -18
  42. package/dist/types/Union/JetStreamManager.d.ts +0 -12
  43. package/dist/types/Union/StreamApi.d.ts +0 -16
  44. package/dist/types/Union/Subscription.d.ts +0 -19
  45. package/dist/types/Union/index.d.ts +0 -1
  46. package/dist/types/index.d.ts +0 -7
  47. package/dist/types/injector.d.ts +0 -14
  48. package/dist/types/interfaces.d.ts +0 -181
package/dist/Service.js DELETED
@@ -1,677 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Service = void 0;
4
- const Root_1 = require("./Root");
5
- const nats_1 = require("nats");
6
- const _1 = require(".");
7
- const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
8
- const resources_1 = require("@opentelemetry/resources");
9
- const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
10
- const api_1 = require("@opentelemetry/api");
11
- const exporter_jaeger_1 = require("@opentelemetry/exporter-jaeger");
12
- const node_stream_1 = require("node:stream");
13
- const promises_1 = require("node:stream/promises");
14
- const toolbelt_1 = require("@lad-tech/toolbelt");
15
- const http = require("node:http");
16
- const os = require("node:os");
17
- const promises_2 = require("node:timers/promises");
18
- const node_util_1 = require("node:util");
19
- const StreamManager_1 = require("./StreamManager");
20
- class Service extends Root_1.Root {
21
- constructor(options) {
22
- super(options.brokerConnection, options.loggerOutputFormatter);
23
- this.options = options;
24
- this.emitter = {};
25
- this.subscriptions = [];
26
- this.httpMethods = new Map();
27
- this.rootSpans = new Map();
28
- /**
29
- * Unique identifier NATS header for a message that will be used by the server apply
30
- * de-duplication within the configured Duplicate Window
31
- */
32
- this.UNIQ_ID_HEADER = 'Nats-Msg-Id';
33
- /**
34
- * Nats-Rollup header indicating all prior messages should be purged
35
- */
36
- this.ROLLUP_HEADER = 'Nats-Rollup';
37
- /**
38
- * Roll-up only same subject message in the stream
39
- */
40
- this.ROLLUP_STRATEGY = 'sub';
41
- this.BASE_EVENT_SUFFIX = 'base';
42
- this.serviceName = options.name;
43
- this.logger.setLocation(this.serviceName);
44
- if (options.events) {
45
- const events = Object.keys(options.events.list);
46
- this.emitter = events.reduce((result, eventName) => {
47
- result[eventName] = ((params, uniqId, rollupId, external) => {
48
- var _a, _b, _c;
49
- const subject = [options.name];
50
- const eventOptions = (_a = options.events) === null || _a === void 0 ? void 0 : _a.list[eventName];
51
- const isStream = (_b = eventOptions === null || eventOptions === void 0 ? void 0 : eventOptions.options) === null || _b === void 0 ? void 0 : _b.stream;
52
- if (isStream) {
53
- const prefix = (_c = options.events) === null || _c === void 0 ? void 0 : _c.streamOptions.prefix;
54
- if (!prefix) {
55
- throw new Error(`Stream prefix not set for event ${String(eventName)} marked as stream`);
56
- }
57
- subject.push(prefix);
58
- }
59
- subject.push(String(eventName));
60
- let settings;
61
- if (uniqId) {
62
- settings = { headers: (0, nats_1.headers)() };
63
- settings.headers.append(this.UNIQ_ID_HEADER, uniqId);
64
- }
65
- if (rollupId && isStream) {
66
- settings = settings !== null && settings !== void 0 ? settings : { headers: (0, nats_1.headers)() };
67
- settings.headers.append(this.ROLLUP_HEADER, this.ROLLUP_STRATEGY);
68
- subject.push(rollupId);
69
- }
70
- else if (rollupId && !isStream) {
71
- this.logger.warn(`${String(eventName)}. Rollup is available only for streams`);
72
- }
73
- else if (isStream) {
74
- subject.push(this.BASE_EVENT_SUFFIX);
75
- }
76
- if (external) {
77
- const baggage = this.getBaggageFromExternalHeader(external);
78
- const tracer = api_1.trace.getTracer('');
79
- const context = this.getContext(this.isBaggageContainTrace(baggage) ? baggage : undefined);
80
- const span = tracer.startSpan(String(eventName), { kind: api_1.SpanKind.PRODUCER }, context);
81
- const eventSpanContext = span.spanContext();
82
- const eventHeader = this.convertBaggaggeToExternalHeader(eventSpanContext);
83
- if (!settings) {
84
- settings = { headers: (0, nats_1.headers)() };
85
- }
86
- for (const [key, value] of Object.entries(eventHeader)) {
87
- settings.headers.append(key, `${value}`);
88
- }
89
- span.end();
90
- }
91
- this.broker.publish(subject.join('.'), this.buildMessage(params), settings);
92
- });
93
- return result;
94
- }, this.emitter);
95
- }
96
- this.createTracer();
97
- }
98
- /**
99
- * Create global Tracer
100
- */
101
- createTracer() {
102
- const provider = new sdk_trace_base_1.BasicTracerProvider({
103
- resource: new resources_1.Resource({
104
- [semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: this.options.name,
105
- }),
106
- });
107
- let host;
108
- let port;
109
- const agentUrl = this.getSettingFromEnv('OTEL_AGENT', false);
110
- if (agentUrl) {
111
- const agent = agentUrl.split(':');
112
- host = agent[0];
113
- port = parseInt(agent[1]) || undefined;
114
- }
115
- const exporter = new exporter_jaeger_1.JaegerExporter({ host, port });
116
- provider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(exporter));
117
- provider.register();
118
- }
119
- finishSpan(span, error, tag) {
120
- if (error) {
121
- span.setAttribute('error', true);
122
- span.setAttribute('error.kind', error.message);
123
- }
124
- this.applyTag(span, tag);
125
- span.end();
126
- }
127
- /**
128
- * Wrapper for async methods. Create span
129
- */
130
- perform(func, funcContext, arg, tracer, context, tag) {
131
- const span = tracer.startSpan(func.name, undefined, context);
132
- try {
133
- const result = func.apply(funcContext, arg);
134
- if (result.then) {
135
- return result.then((result) => {
136
- this.finishSpan(span, undefined, tag);
137
- return result;
138
- }, (error) => {
139
- this.finishSpan(span, error, tag);
140
- throw error;
141
- });
142
- }
143
- this.finishSpan(span, undefined, tag);
144
- return result;
145
- }
146
- catch (error) {
147
- this.finishSpan(span, error, tag);
148
- throw error;
149
- }
150
- }
151
- /**
152
- * Build trap for object with async methods
153
- */
154
- getTrap(instance, tracer, baggage, tag) {
155
- const perform = this.perform.bind(this);
156
- const context = this.getContext(baggage);
157
- return {
158
- get(target, propKey, receiver) {
159
- const method = Reflect.get(target, propKey, receiver);
160
- if (typeof method === 'function') {
161
- return function (...args) {
162
- return perform(method, instance, args, tracer, context, tag);
163
- };
164
- }
165
- else {
166
- return method;
167
- }
168
- },
169
- };
170
- }
171
- /**
172
- * Creating an object to inject into Method (business logic)
173
- */
174
- createObjectWithDependencies(method, tracer, baggage) {
175
- const services = _1.ServiceContainer.get(method.settings.action) || new Map();
176
- const instances = _1.InstanceContainer.get(method.settings.action) || new Map();
177
- const tags = new Map();
178
- const dependences = { [_1.ConstructorDependencyKey]: [] };
179
- const dependencyStorage = Reflect.getMetadata(_1.dependencyStorageMetaKey, method);
180
- if (dependencyStorage && dependencyStorage.size) {
181
- // for constructor
182
- dependencyStorage.forEach((dependencyKey, propertyName) => {
183
- var _a;
184
- if (Array.isArray(dependencyKey)) {
185
- if (propertyName === _1.ConstructorDependencyKey) {
186
- dependencyKey.forEach((item, index) => {
187
- const { dependency } = _1.container.get(item);
188
- if (dependency.type === _1.DependencyType.SERVICE) {
189
- dependences[_1.ConstructorDependencyKey][index] = new dependency.value(this.broker, baggage, this.options.cache);
190
- }
191
- if (dependency.type === _1.DependencyType.ADAPTER) {
192
- const instance = _1.container.getInstance(item);
193
- const trap = this.getTrap(instance, tracer, baggage);
194
- dependences[_1.ConstructorDependencyKey][index] = new Proxy(instance, trap);
195
- }
196
- if (dependency.type === _1.DependencyType.CONSTANT) {
197
- dependences[_1.ConstructorDependencyKey][index] = dependency.value;
198
- }
199
- });
200
- }
201
- return;
202
- }
203
- const { dependency } = _1.container.get(dependencyKey);
204
- if (dependency.type === _1.DependencyType.SERVICE) {
205
- services.set(propertyName, dependency.value);
206
- }
207
- if (dependency.type === _1.DependencyType.ADAPTER) {
208
- instances.set(propertyName, _1.container.getInstance(dependencyKey));
209
- if ((_a = dependency.options) === null || _a === void 0 ? void 0 : _a.tag) {
210
- tags.set(propertyName, dependency.options.tag);
211
- }
212
- }
213
- if (dependency.type === _1.DependencyType.CONSTANT) {
214
- dependences[propertyName] = dependency.value;
215
- }
216
- });
217
- }
218
- if (services.size) {
219
- services.forEach((Dependence, key) => {
220
- dependences[key] = new Dependence(this.broker, baggage, this.options.cache);
221
- });
222
- }
223
- if (instances.size) {
224
- instances.forEach((instance, key) => {
225
- const trap = this.getTrap(instance, tracer, baggage, tags.get(key));
226
- dependences[key] = new Proxy(instance, trap);
227
- });
228
- }
229
- return dependences;
230
- }
231
- /**
232
- * Create Method (business logic) context
233
- */
234
- createMethodContext(Method, dependencies) {
235
- const constructor = dependencies[_1.ConstructorDependencyKey] || [];
236
- const context = new Method(...constructor);
237
- for (const key in dependencies) {
238
- context[key] = dependencies[key];
239
- }
240
- return context;
241
- }
242
- /**
243
- * Create Baggage from span. Expired one-on-one business logic call
244
- */
245
- getNextBaggage(span, baggage) {
246
- const { traceId, spanId, traceFlags } = span.spanContext();
247
- return { traceId, spanId, traceFlags, expired: baggage === null || baggage === void 0 ? void 0 : baggage.expired, requestId: baggage === null || baggage === void 0 ? void 0 : baggage.requestId };
248
- }
249
- /**
250
- * Guard for determine whether baggage contains trace information
251
- */
252
- isBaggageContainTrace(params) {
253
- return !!params && !!(params.traceId && params.spanId && params.traceFlags);
254
- }
255
- /**
256
- * If there is no baggage. For example, in HTTP Gateway
257
- */
258
- getRootBaggage(subject, headers, ownTimeout) {
259
- const baggage = headers ? this.getBaggageFromExternalHeader(headers) : undefined;
260
- const tracer = api_1.trace.getTracer('');
261
- const context = this.getContext(this.isBaggageContainTrace(baggage) ? baggage : undefined);
262
- const span = tracer.startSpan(subject, undefined, context);
263
- const newBaggage = this.getNextBaggage(span, baggage);
264
- this.rootSpans.set(newBaggage.traceId, span);
265
- return {
266
- ...newBaggage,
267
- expired: this.getExpired(undefined, ownTimeout),
268
- };
269
- }
270
- /**
271
- * End root baggage
272
- */
273
- endRootSpan(traceId, error) {
274
- const span = this.rootSpans.get(traceId);
275
- if (span) {
276
- this.finishSpan(span, error);
277
- this.rootSpans.delete(traceId);
278
- }
279
- }
280
- buildService(Client, baggage) {
281
- return new Client(this.broker, baggage, this.options.cache, this.options.loggerOutputFormatter);
282
- }
283
- /**
284
- * Create service Method for send HTTP settings
285
- */
286
- async runServiceMethodForHttp() {
287
- const subject = `${this.serviceName}.${this.SERVICE_SUBJECT_FOR_GET_HTTP_SETTINGS}`;
288
- const subscription = this.broker.subscribe(subject, { queue: this.serviceName });
289
- this.subscriptions.push(subscription);
290
- for await (const message of subscription) {
291
- message.respond(this.buildMessage(this.getHttpSettings()));
292
- }
293
- }
294
- makeHttpSingleResponse(response, data) {
295
- const isError = !data.payload && data.error && data.error.message;
296
- const responseData = JSON.stringify(data);
297
- response
298
- .writeHead(isError ? 500 : 200, {
299
- 'Content-Length': Buffer.byteLength(responseData),
300
- 'Content-Type': 'application/json',
301
- })
302
- .write(responseData);
303
- response.end();
304
- }
305
- /**
306
- * Create transform stream for convert object to string in stream pipeline
307
- */
308
- getStringifyTransform() {
309
- return new node_stream_1.Transform({
310
- objectMode: true,
311
- transform(chunk, encoding, push) {
312
- try {
313
- if (chunk instanceof Buffer) {
314
- push(null, chunk);
315
- }
316
- else {
317
- const result = JSON.stringify(chunk);
318
- push(null, result);
319
- }
320
- }
321
- catch (error) {
322
- push(error);
323
- }
324
- },
325
- });
326
- }
327
- makeHttpStreamResponse(response, data) {
328
- data.payload.on('error', error => {
329
- this.logger.error(error);
330
- });
331
- response.writeHead(200, {
332
- 'Content-Type': 'application/octet-stream',
333
- });
334
- return (0, promises_1.pipeline)(data.payload, this.getStringifyTransform(), response);
335
- }
336
- /**
337
- * Up HTTP server and start listen http routes
338
- */
339
- async buildHTTPHandlers() {
340
- await this.upHTTPServer();
341
- this.runServiceMethodForHttp();
342
- this.httpServer.on('request', async (request, response) => {
343
- var _a, _b, _c, _d;
344
- try {
345
- if (request.method !== 'POST' || !request.url) {
346
- throw new Error('Wrong http request');
347
- }
348
- const parsedUrl = request.url.split('/');
349
- parsedUrl.shift();
350
- const [serviceName, action, ...other] = parsedUrl;
351
- const wrongServiceName = this.serviceName !== serviceName;
352
- const Method = this.httpMethods.get(action);
353
- if (other.length || wrongServiceName || !Method) {
354
- throw new Error('Wrong url or service name or action');
355
- }
356
- const baggage = this.getBaggageFromExternalHeader(request.headers);
357
- if ((_b = (_a = Method.settings.options) === null || _a === void 0 ? void 0 : _a.useStream) === null || _b === void 0 ? void 0 : _b.request) {
358
- const result = await this.handled(request, Method, baggage);
359
- if (Method.settings.options.useStream.response && result.payload instanceof node_stream_1.Readable) {
360
- this.makeHttpStreamResponse(response, result);
361
- return;
362
- }
363
- this.makeHttpSingleResponse(response, result);
364
- return;
365
- }
366
- const requestDataRaw = [];
367
- for await (const data of request) {
368
- requestDataRaw.push(data);
369
- }
370
- const requestData = Buffer.concat(requestDataRaw).toString();
371
- const result = await this.handled(JSON.parse(requestData), Method, baggage);
372
- if (((_d = (_c = Method.settings.options) === null || _c === void 0 ? void 0 : _c.useStream) === null || _d === void 0 ? void 0 : _d.response) && result.payload instanceof node_stream_1.Readable) {
373
- await this.makeHttpStreamResponse(response, result);
374
- return;
375
- }
376
- this.makeHttpSingleResponse(response, result);
377
- }
378
- catch (error) {
379
- this.logger.error(error);
380
- if (error instanceof Error) {
381
- this.makeHttpSingleResponse(response, this.buildErrorMessage(error));
382
- return;
383
- }
384
- this.makeHttpSingleResponse(response, this.buildErrorMessage('System unknown error'));
385
- }
386
- });
387
- }
388
- /**
389
- * Run business logic for request
390
- */
391
- async handled(payload, Method, baggage) {
392
- const subject = `${this.serviceName}.${Method.settings.action}`;
393
- const tracer = api_1.trace.getTracer('');
394
- const context = this.getContext(this.isBaggageContainTrace(baggage) ? baggage : undefined);
395
- const span = tracer.startSpan(subject, undefined, context);
396
- const logger = new toolbelt_1.Logs.Logger({
397
- location: `${this.serviceName}.${Method.settings.action}`,
398
- metadata: baggage,
399
- outputFormatter: this.options.loggerOutputFormatter,
400
- });
401
- const nextBaggage = this.getNextBaggage(span, baggage);
402
- try {
403
- const requestedDependencies = this.createObjectWithDependencies(Method, tracer, nextBaggage);
404
- const context = this.createMethodContext(Method, requestedDependencies);
405
- context['logger'] = logger;
406
- context['emitter'] = this.getWrappedEmitter(nextBaggage);
407
- const response = await context.handler.call(context, payload);
408
- const result = {
409
- payload: response,
410
- };
411
- logger.debug({ request: payload, response });
412
- this.finishSpan(span);
413
- return result;
414
- }
415
- catch (error) {
416
- logger.debug({ request: payload });
417
- logger.error(this.createErrorMessageForLogger(error));
418
- this.finishSpan(span, error);
419
- return this.buildErrorMessage(error);
420
- }
421
- }
422
- /**
423
- * Wrap emitter for luggage baggagge
424
- */
425
- getWrappedEmitter(baggage) {
426
- if (!baggage) {
427
- return this.emitter;
428
- }
429
- const externalBaggage = this.convertBaggaggeToExternalHeader(baggage);
430
- return new Proxy(this.emitter, {
431
- get(target, propKey, receiver) {
432
- const event = Reflect.get(target, propKey, receiver);
433
- if (typeof event === 'function') {
434
- return (params, uniqId, rollupId, userExternalBaggage) => {
435
- return event(params, uniqId, rollupId, userExternalBaggage !== null && userExternalBaggage !== void 0 ? userExternalBaggage : externalBaggage);
436
- };
437
- }
438
- else {
439
- return event;
440
- }
441
- },
442
- });
443
- }
444
- /**
445
- * Make error object if error instance of Error object for logger
446
- */
447
- createErrorMessageForLogger(error) {
448
- if (error instanceof Error) {
449
- return { name: error.name, message: error.message, stack: error.stack };
450
- }
451
- return { message: JSON.stringify(error) };
452
- }
453
- /**
454
- * Start service. Subscribe for subject and up http server
455
- */
456
- async start() {
457
- var _a;
458
- const { methods } = this.options;
459
- try {
460
- methods.forEach(async (Method) => {
461
- var _a;
462
- if ((_a = Method.settings.options) === null || _a === void 0 ? void 0 : _a.useStream) {
463
- this.httpMethods.set(Method.settings.action, Method);
464
- return;
465
- }
466
- const subject = `${this.serviceName}.${Method.settings.action}`;
467
- const subscription = this.broker.subscribe(subject, { queue: this.serviceName });
468
- this.subscriptions.push(subscription);
469
- for await (const message of subscription) {
470
- const { payload, baggage } = (0, nats_1.JSONCodec)().decode(message.data);
471
- this.handled(payload, Method, baggage)
472
- .then(result => {
473
- message.respond(this.buildMessage(result));
474
- })
475
- .catch(error => {
476
- message.respond(this.buildMessage({ error: error.message }));
477
- });
478
- }
479
- });
480
- if (this.httpMethods.size > 0) {
481
- await this.buildHTTPHandlers();
482
- }
483
- this.watchBrokerEvents();
484
- this.upProbeRoutes();
485
- this.registerGracefulShutdown();
486
- if ((_a = this.options.events) === null || _a === void 0 ? void 0 : _a.streamOptions) {
487
- const streamManager = new StreamManager_1.StreamManager({
488
- broker: this.broker,
489
- options: this.options.events.streamOptions,
490
- serviceName: this.serviceName,
491
- outputFormatter: this.options.loggerOutputFormatter,
492
- });
493
- await streamManager.createStreams();
494
- }
495
- this.logger.info('Service successfully started!');
496
- }
497
- catch (error) {
498
- if (error instanceof Error) {
499
- this.logger.error(error.name, error.message);
500
- }
501
- else {
502
- this.logger.error('An error occurred while starting the service', error);
503
- }
504
- process.exit(1);
505
- }
506
- }
507
- /**
508
- * Correct finish all connections
509
- */
510
- async cleanupAndExit() {
511
- var _a, _b, _c, _d;
512
- try {
513
- const timeout = ((_a = this.options.gracefulShutdown) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
514
- this.logger.info('Closing Broker connection');
515
- await Promise.race([this.broker.drain(), (0, promises_2.setTimeout)(timeout)]);
516
- if (this.httpServer) {
517
- this.logger.info('Closing HTTP server');
518
- const closeHttp = (0, node_util_1.promisify)(this.httpServer.close);
519
- await Promise.race([closeHttp, (0, promises_2.setTimeout)(timeout)]);
520
- }
521
- if ((_c = (_b = this.options.gracefulShutdown) === null || _b === void 0 ? void 0 : _b.additional) === null || _c === void 0 ? void 0 : _c.length) {
522
- this.logger.info('Closing additional services');
523
- for await (const service of (_d = this.options.gracefulShutdown) === null || _d === void 0 ? void 0 : _d.additional) {
524
- await Promise.race([service.close(), (0, promises_2.setTimeout)(timeout)]);
525
- }
526
- }
527
- if (this.httpProbServer) {
528
- this.logger.info('Closing HTTP Prob server');
529
- const closeHttp = (0, node_util_1.promisify)(this.httpProbServer.close);
530
- await Promise.race([closeHttp, (0, promises_2.setTimeout)(timeout)]);
531
- }
532
- }
533
- catch (error) {
534
- this.logger.error('Fail correct finish service', error);
535
- }
536
- process.exit(0);
537
- }
538
- async stop() {
539
- await this.cleanupAndExit();
540
- }
541
- /**
542
- * Handler for OS Signal
543
- */
544
- handleSignal(signal) {
545
- return () => {
546
- this.logger.warn(`signal ${signal} received`);
547
- this.cleanupAndExit();
548
- };
549
- }
550
- /**
551
- * Handler for Force OS Signal
552
- */
553
- handleFatalError(message) {
554
- return (err) => {
555
- this.logger.error(message, err);
556
- process.exit(1);
557
- };
558
- }
559
- /**
560
- * Register listeners for Graceful Shutdown
561
- */
562
- registerGracefulShutdown() {
563
- process.on('SIGINT', this.handleSignal('SIGINT'));
564
- process.on('SIGQUIT', this.handleSignal('SIGQUIT'));
565
- process.on('SIGTERM', this.handleSignal('SIGTERM'));
566
- process.on('uncaughtException', this.handleFatalError('Uncaught exception'));
567
- process.on('unhandledRejection', this.handleFatalError('Unhandled rejection'));
568
- }
569
- /**
570
- * Up Probe Route for container orchestration service
571
- */
572
- upProbeRoutes() {
573
- if (this.httpProbServer || process.env.ENVIRONMENT === 'local') {
574
- return;
575
- }
576
- this.httpProbServer = http.createServer();
577
- this.httpProbServer.on('request', (request, response) => {
578
- if (request.url === '/healthcheck' && request.method === 'GET') {
579
- response.writeHead(200).end();
580
- return;
581
- }
582
- response.writeHead(500).end();
583
- });
584
- this.httpProbServer.listen(8081).once('error', error => {
585
- if (!this.broker.isUnion) {
586
- throw error;
587
- }
588
- this.httpProbServer = undefined;
589
- });
590
- }
591
- /**
592
- * Type guard for NATS debug event
593
- */
594
- isNATSDebugEvent(event) {
595
- return (event === nats_1.DebugEvents.PingTimer || event === nats_1.DebugEvents.Reconnecting || event === nats_1.DebugEvents.StaleConnection);
596
- }
597
- /**
598
- * Logs events from the broker
599
- */
600
- async watchBrokerEvents() {
601
- for await (const event of this.broker.status()) {
602
- if (this.isNATSDebugEvent(event.type)) {
603
- this.logger.debug(`${event.type}: ${event.data}`);
604
- return;
605
- }
606
- this.logger.warn(`${event.type}: ${event.data}`);
607
- }
608
- }
609
- /**
610
- * Build message for broker
611
- */
612
- buildMessage(message) {
613
- return (0, nats_1.JSONCodec)().encode(message);
614
- }
615
- async upHTTPServer() {
616
- this.httpServer = http.createServer();
617
- this.ipAddress = this.getMyIpV4();
618
- this.httpPort = await new Promise((resolve, reject) => {
619
- this.httpServer = this.httpServer.listen(0, () => {
620
- const address = this.httpServer.address();
621
- if (!address) {
622
- reject(new Error('Failed to get the port number: server is not listening'));
623
- return;
624
- }
625
- if (typeof address === 'string') {
626
- reject(new Error('Listening on a unix socket is not supported'));
627
- return;
628
- }
629
- resolve(address.port);
630
- });
631
- });
632
- return this.httpServer;
633
- }
634
- getMyIpV4() {
635
- const networkInterfaces = os.networkInterfaces();
636
- const myIpV4Address = Object.keys(networkInterfaces).reduce((ip, key) => {
637
- if (ip) {
638
- return ip;
639
- }
640
- const networkInterface = networkInterfaces[key];
641
- const externalIpV4Interface = networkInterface === null || networkInterface === void 0 ? void 0 : networkInterface.find(item => !item.internal && item.family === 'IPv4');
642
- if (externalIpV4Interface) {
643
- return externalIpV4Interface.address;
644
- }
645
- return ip;
646
- }, '');
647
- if (!myIpV4Address) {
648
- throw new Error('Failed to get service ip address');
649
- }
650
- return myIpV4Address;
651
- }
652
- getHttpSettings() {
653
- return {
654
- ip: this.ipAddress,
655
- port: this.httpPort,
656
- };
657
- }
658
- getBaggageFromExternalHeader(headers) {
659
- const expired = headers['nsc-expired'] ? +headers['nsc-expired'] : undefined;
660
- const traceId = headers['nsc-trace-id'];
661
- const spanId = headers['nsc-span-id'];
662
- const traceFlags = headers['nsc-trace-flags'] ? +headers['nsc-trace-flags'] : undefined;
663
- const requestId = headers['x-request-id'] ? String(headers['x-request-id']) : undefined;
664
- if (traceId && spanId && traceFlags) {
665
- return {
666
- traceId,
667
- spanId,
668
- traceFlags,
669
- expired,
670
- requestId,
671
- };
672
- }
673
- return { expired, requestId };
674
- }
675
- }
676
- exports.Service = Service;
677
- //# sourceMappingURL=Service.js.map
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StreamBatchMsgFetcher = void 0;
4
- class StreamBatchMsgFetcher {
5
- constructor(consumer, options) {
6
- this.consumer = consumer;
7
- this.options = options;
8
- }
9
- async fetch(size, expires) {
10
- return await this.consumer.fetch({
11
- max_messages: size !== null && size !== void 0 ? size : this.options.batchSize,
12
- expires: expires !== null && expires !== void 0 ? expires : this.options.batchTimeout,
13
- });
14
- }
15
- }
16
- exports.StreamBatchMsgFetcher = StreamBatchMsgFetcher;
17
- //# sourceMappingURL=StreamBatchMsgFetcher.js.map