@palmetto/pubsub 2.1.3 → 2.2.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 +13 -0
- package/dist/bullmq/publisher.d.ts +1 -1
- package/dist/bullmq/publisher.js +12 -10
- package/dist/bullmq/pubsub.d.ts +1 -1
- package/dist/bullmq/pubsub.js +2 -2
- package/dist/dd-trace.wrapper.d.ts +61 -0
- package/dist/dd-trace.wrapper.js +36 -0
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +4 -0
- package/dist/interfaces.d.ts +1 -1
- package/dist/main.d.ts +1 -0
- package/dist/main.js +1 -0
- package/dist/publisher.d.ts +1 -1
- package/dist/publisher.js +66 -35
- package/dist/rabbitmq/publisher.d.ts +2 -1
- package/dist/rabbitmq/publisher.js +20 -17
- package/dist/rabbitmq/pubsub.d.ts +1 -1
- package/dist/rabbitmq/pubsub.js +2 -2
- package/dist/subscriber.js +16 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,6 +61,10 @@ yarn add @palmetto/pubsub zod
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
await publisher.publish(schemaConfig, message);
|
|
64
|
+
|
|
65
|
+
// publish a batch of messages quicker than sending the one at a time:
|
|
66
|
+
const messages: Model[] = [...];
|
|
67
|
+
await publisher.publish(schemaConfig, messages);
|
|
64
68
|
```
|
|
65
69
|
|
|
66
70
|
1. Create subscriber and subscriber to a message
|
|
@@ -108,6 +112,15 @@ yarn add @palmetto/pubsub zod
|
|
|
108
112
|
await subscriber.startSubscribe(schemaConfig, onMessage);
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
1. Register with dd-trace for improved trace logs
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import tracer from "dd-trace";
|
|
119
|
+
import { registerDdTrace } from "@palmetto/pubsub";
|
|
120
|
+
|
|
121
|
+
registerDdTrace(tracer);
|
|
122
|
+
```
|
|
123
|
+
|
|
111
124
|
### Message logging
|
|
112
125
|
|
|
113
126
|
For each message you can indicate how to log messages when they are published or handled by a subscriber. Use the `messageLogLevel` property of the queue configuration object.
|
|
@@ -8,7 +8,7 @@ export declare class BullMqPublisher implements PublisherProvider {
|
|
|
8
8
|
constructor(connection: bullmq.ConnectionOptions, logger: Logger);
|
|
9
9
|
readonly transport: string;
|
|
10
10
|
private getQueue;
|
|
11
|
-
publish(config: BullMqQueueConfiguration,
|
|
11
|
+
publish(config: BullMqQueueConfiguration, messages: string[]): Promise<void>;
|
|
12
12
|
init(config: BullMqQueueConfiguration): Promise<void>;
|
|
13
13
|
close(): Promise<void>;
|
|
14
14
|
enrichPublishedMesssageLog(config: BullMqQueueConfiguration): Record<string, unknown>;
|
package/dist/bullmq/publisher.js
CHANGED
|
@@ -36,18 +36,20 @@ class BullMqPublisher {
|
|
|
36
36
|
return queue;
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
publish(config,
|
|
39
|
+
publish(config, messages) {
|
|
40
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
-
var _a, _b;
|
|
42
41
|
const queue = yield this.getQueue(config);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
yield Promise.all(messages.map((message) => __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
(_b = (_a = this.logger).debug) === null || _b === void 0 ? void 0 : _b.call(_a, `Publishing message to ${queue.name} - ${message}`);
|
|
45
|
+
yield queue.add(config.job || connection_js_1.BULLMQ_DEFAULTJOB, message, {
|
|
46
|
+
attempts: config.retries,
|
|
47
|
+
backoff: {
|
|
48
|
+
type: "fixed",
|
|
49
|
+
delay: config.retryDelay || 30000,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
})));
|
|
51
53
|
});
|
|
52
54
|
}
|
|
53
55
|
init(config) {
|
package/dist/bullmq/pubsub.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare class BullMqPubSubProvider implements PubSubProvider {
|
|
|
6
6
|
private readonly subscriber;
|
|
7
7
|
constructor(connection: ConnectionOptions, logger: Logger);
|
|
8
8
|
readonly transport: string;
|
|
9
|
-
publish(config: BullMqQueueConfiguration,
|
|
9
|
+
publish(config: BullMqQueueConfiguration, messages: string[]): Promise<void>;
|
|
10
10
|
startSubscribe(config: BullMqQueueConfiguration, onMessage: (s: string, context: MessageContext) => Promise<MessageResult> | MessageResult): Promise<StopSubscribe>;
|
|
11
11
|
close(): Promise<void>;
|
|
12
12
|
init(config: BullMqQueueConfiguration): Promise<void>;
|
package/dist/bullmq/pubsub.js
CHANGED
|
@@ -19,8 +19,8 @@ class BullMqPubSubProvider {
|
|
|
19
19
|
this.publisher = new publisher_js_1.BullMqPublisher(connection, logger);
|
|
20
20
|
this.subscriber = new subscriber_js_1.BullMqSubscriber(connection, logger);
|
|
21
21
|
}
|
|
22
|
-
publish(config,
|
|
23
|
-
return this.publisher.publish(config,
|
|
22
|
+
publish(config, messages) {
|
|
23
|
+
return this.publisher.publish(config, messages);
|
|
24
24
|
}
|
|
25
25
|
startSubscribe(config, onMessage) {
|
|
26
26
|
return this.subscriber.startSubscribe(config, onMessage);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
interface Span {
|
|
2
|
+
/**
|
|
3
|
+
* Sets the end timestamp and finalizes Span state.
|
|
4
|
+
*
|
|
5
|
+
* With the exception of calls to Span.context() (which are always allowed),
|
|
6
|
+
* finish() must be the last call made to any span instance, and to do
|
|
7
|
+
* otherwise leads to undefined behavior.
|
|
8
|
+
*/
|
|
9
|
+
finish(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Adds a single tag to the span. See `addTags()` for details.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} key
|
|
14
|
+
* @param {any} value
|
|
15
|
+
*/
|
|
16
|
+
setTag(key: string, value: unknown): this;
|
|
17
|
+
}
|
|
18
|
+
interface SpanOptions {
|
|
19
|
+
/**
|
|
20
|
+
* a parent SpanContext (or Span, for convenience) that the newly-started
|
|
21
|
+
* span will be the child of (per REFERENCE_CHILD_OF). If specified,
|
|
22
|
+
* `references` must be unspecified.
|
|
23
|
+
*/
|
|
24
|
+
childOf: Span | null;
|
|
25
|
+
/**
|
|
26
|
+
* set of key-value pairs which will be set as tags on the newly created
|
|
27
|
+
* Span. Ownership of the object is passed to the created span for
|
|
28
|
+
* efficiency reasons (the caller should not modify this object after
|
|
29
|
+
* calling startSpan).
|
|
30
|
+
*/
|
|
31
|
+
tags: {
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The Datadog Scope Manager. This is used for context propagation.
|
|
37
|
+
*/
|
|
38
|
+
interface Scope {
|
|
39
|
+
/**
|
|
40
|
+
* Get the current active span or null if there is none.
|
|
41
|
+
*
|
|
42
|
+
* @returns {Span} The active span.
|
|
43
|
+
*/
|
|
44
|
+
active(): Span | null;
|
|
45
|
+
}
|
|
46
|
+
interface Tracer {
|
|
47
|
+
/**
|
|
48
|
+
* Starts and returns a new Span representing a logical unit of work.
|
|
49
|
+
* @param {string} name The name of the operation.
|
|
50
|
+
* @param {SpanOptions} [options] Options for the newly created span.
|
|
51
|
+
* @returns {Span} A new Span object.
|
|
52
|
+
*/
|
|
53
|
+
startSpan(name: string, options: SpanOptions): Span;
|
|
54
|
+
/**
|
|
55
|
+
* Returns a reference to the current scope.
|
|
56
|
+
*/
|
|
57
|
+
scope(): Scope;
|
|
58
|
+
}
|
|
59
|
+
export declare function getTracer(): Tracer;
|
|
60
|
+
export declare function registerDdTrace(tracer: Tracer): void;
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTracer = getTracer;
|
|
4
|
+
exports.registerDdTrace = registerDdTrace;
|
|
5
|
+
class NoOpSpan {
|
|
6
|
+
finish() {
|
|
7
|
+
// no-op
|
|
8
|
+
}
|
|
9
|
+
setTag(_key, _value) {
|
|
10
|
+
return this;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
class NoOpScope {
|
|
14
|
+
active() {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
class NoOpTracer {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.noOpSpan = new NoOpSpan();
|
|
21
|
+
this.noOpScope = new NoOpScope();
|
|
22
|
+
}
|
|
23
|
+
startSpan(_name, _options) {
|
|
24
|
+
return this.noOpSpan;
|
|
25
|
+
}
|
|
26
|
+
scope() {
|
|
27
|
+
return this.noOpScope;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let tracerInstance = new NoOpTracer();
|
|
31
|
+
function getTracer() {
|
|
32
|
+
return tracerInstance;
|
|
33
|
+
}
|
|
34
|
+
function registerDdTrace(tracer) {
|
|
35
|
+
tracerInstance = tracer;
|
|
36
|
+
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare class MissingPubSubProviderError extends Error {
|
|
|
10
10
|
static isMissingPubSubProviderError(err: unknown): err is MissingPubSubProviderError;
|
|
11
11
|
}
|
|
12
12
|
export declare class PublishError extends Error {
|
|
13
|
+
readonly failedMessages: string[];
|
|
14
|
+
constructor(message: string, failedMessages: string[]);
|
|
13
15
|
static isPublishError(err: unknown): err is PublishError;
|
|
14
16
|
}
|
|
15
17
|
export declare class SchemaValidationError extends Error {
|
package/dist/errors.js
CHANGED
|
@@ -24,6 +24,10 @@ class MissingPubSubProviderError extends Error {
|
|
|
24
24
|
}
|
|
25
25
|
exports.MissingPubSubProviderError = MissingPubSubProviderError;
|
|
26
26
|
class PublishError extends Error {
|
|
27
|
+
constructor(message, failedMessages) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.failedMessages = failedMessages;
|
|
30
|
+
}
|
|
27
31
|
static isPublishError(err) {
|
|
28
32
|
return err instanceof PublishError;
|
|
29
33
|
}
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export type BaseMessage = z.infer<typeof IdMetaSchema>;
|
|
|
23
23
|
export interface PublisherProvider {
|
|
24
24
|
transport: string;
|
|
25
25
|
init(config: PubSubConfiguration): Promise<void> | void;
|
|
26
|
-
publish(config: PubSubConfiguration,
|
|
26
|
+
publish(config: PubSubConfiguration, messages: string[]): Promise<void> | void;
|
|
27
27
|
close(): Promise<void> | void;
|
|
28
28
|
enrichPublishedMesssageLog(config: PubSubConfiguration): Record<string, unknown>;
|
|
29
29
|
}
|
package/dist/main.d.ts
CHANGED
package/dist/main.js
CHANGED
|
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./dd-trace.wrapper.js"), exports);
|
|
17
18
|
__exportStar(require("./errors.js"), exports);
|
|
18
19
|
__exportStar(require("./interfaces.js"), exports);
|
|
19
20
|
__exportStar(require("./publisher.js"), exports);
|
package/dist/publisher.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare class Publisher {
|
|
|
7
7
|
addProvider(provider: PublisherProvider): void;
|
|
8
8
|
removeProvider(providerOrTransport: PublisherProvider | string): boolean;
|
|
9
9
|
init(config: PubSubConfiguration): Promise<void>;
|
|
10
|
-
publish(config: PubSubConfiguration, message: BaseMessage): Promise<void>;
|
|
10
|
+
publish(config: PubSubConfiguration, message: BaseMessage | BaseMessage[]): Promise<void>;
|
|
11
11
|
close(): Promise<void>;
|
|
12
12
|
private getProvider;
|
|
13
13
|
private assertSchema;
|
package/dist/publisher.js
CHANGED
|
@@ -15,6 +15,7 @@ const uuid_1 = require("uuid");
|
|
|
15
15
|
const crypto_1 = require("crypto");
|
|
16
16
|
const errors_js_1 = require("./errors.js");
|
|
17
17
|
const message_logger_js_1 = require("./message-logger.js");
|
|
18
|
+
const dd_trace_wrapper_js_1 = require("./dd-trace.wrapper.js");
|
|
18
19
|
class Publisher {
|
|
19
20
|
constructor(logger, providers) {
|
|
20
21
|
var _a, _b;
|
|
@@ -53,43 +54,71 @@ class Publisher {
|
|
|
53
54
|
}
|
|
54
55
|
publish(config, message) {
|
|
55
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const tracer = (0, dd_trace_wrapper_js_1.getTracer)();
|
|
58
|
+
const span = tracer.startSpan("pubsub.publish", {
|
|
59
|
+
childOf: tracer.scope().active(),
|
|
60
|
+
tags: {
|
|
61
|
+
"pubsub.transport": config.transport,
|
|
62
|
+
"pubsub.name": config.name,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
try {
|
|
66
|
+
const provider = this.getProvider(config);
|
|
67
|
+
const { schema, schemaId } = this.assertSchema(config);
|
|
68
|
+
if (!Array.isArray(message)) {
|
|
69
|
+
message = [message];
|
|
70
|
+
}
|
|
71
|
+
const jsons = message.map((msg) => {
|
|
72
|
+
if (!msg.id) {
|
|
73
|
+
msg.id = (0, uuid_1.v4)();
|
|
74
|
+
}
|
|
75
|
+
if (!msg.meta) {
|
|
76
|
+
msg.meta = {
|
|
77
|
+
createdAt: new Date().toISOString(),
|
|
78
|
+
publishedBy: "",
|
|
79
|
+
schemaId: schemaId,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
msg.meta.schemaId = schemaId;
|
|
84
|
+
}
|
|
85
|
+
const check = schema.safeEncode(msg);
|
|
86
|
+
if (!check.success) {
|
|
87
|
+
(0, message_logger_js_1.logMessage)({
|
|
88
|
+
note: "Publish message failed schema validation",
|
|
89
|
+
message: message,
|
|
90
|
+
level: "error",
|
|
91
|
+
logger: this.logger,
|
|
92
|
+
extra: Object.assign({ transport: provider.transport, name: config.name }, provider.enrichPublishedMesssageLog(config)),
|
|
93
|
+
});
|
|
94
|
+
throw new errors_js_1.SchemaValidationError(`Schema did not accept the published message: ${check.error.message}`);
|
|
95
|
+
}
|
|
96
|
+
const json = JSON.stringify(check.data);
|
|
97
|
+
return { json, data: check.data };
|
|
98
|
+
});
|
|
99
|
+
const start = (0, message_logger_js_1.startTiming)();
|
|
100
|
+
yield provider.publish(config, jsons.map((j) => j.json));
|
|
101
|
+
const duration = (0, message_logger_js_1.getDuration)(start);
|
|
102
|
+
jsons.forEach((msg) => {
|
|
103
|
+
(0, message_logger_js_1.logMessage)({
|
|
104
|
+
note: "Published message",
|
|
105
|
+
message: msg.data,
|
|
106
|
+
level: config.messageLogLevel,
|
|
107
|
+
logger: this.logger,
|
|
108
|
+
extra: Object.assign({ transport: provider.transport, name: config.name, durationMs: duration }, provider.enrichPublishedMesssageLog(config)),
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
span.setTag("pubsub.duration_ms", duration);
|
|
112
|
+
span.setTag("pubsub.message_count", message.length);
|
|
113
|
+
span.setTag("pubsub.success", true);
|
|
59
114
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
createdAt: new Date().toISOString(),
|
|
64
|
-
publishedBy: "",
|
|
65
|
-
schemaId: schemaId,
|
|
66
|
-
};
|
|
115
|
+
catch (err) {
|
|
116
|
+
span.setTag("pubsub.success", false);
|
|
117
|
+
throw err;
|
|
67
118
|
}
|
|
68
|
-
|
|
69
|
-
|
|
119
|
+
finally {
|
|
120
|
+
span.finish();
|
|
70
121
|
}
|
|
71
|
-
const check = schema.safeEncode(message);
|
|
72
|
-
if (!check.success) {
|
|
73
|
-
(0, message_logger_js_1.logMessage)({
|
|
74
|
-
note: "Publish message failed schema validation",
|
|
75
|
-
message: message,
|
|
76
|
-
level: "error",
|
|
77
|
-
logger: this.logger,
|
|
78
|
-
extra: Object.assign({ transport: provider.transport, name: config.name }, provider.enrichPublishedMesssageLog(config)),
|
|
79
|
-
});
|
|
80
|
-
throw new errors_js_1.SchemaValidationError(`Schema did not accept the published message: ${check.error.message}`);
|
|
81
|
-
}
|
|
82
|
-
const json = JSON.stringify(check.data);
|
|
83
|
-
const start = (0, message_logger_js_1.startTiming)();
|
|
84
|
-
yield provider.publish(config, json);
|
|
85
|
-
const duration = (0, message_logger_js_1.getDuration)(start);
|
|
86
|
-
(0, message_logger_js_1.logMessage)({
|
|
87
|
-
note: "Published message",
|
|
88
|
-
message: check.data,
|
|
89
|
-
level: config.messageLogLevel,
|
|
90
|
-
logger: this.logger,
|
|
91
|
-
extra: Object.assign({ transport: provider.transport, name: config.name, durationMs: duration }, provider.enrichPublishedMesssageLog(config)),
|
|
92
|
-
});
|
|
93
122
|
});
|
|
94
123
|
}
|
|
95
124
|
close() {
|
|
@@ -108,10 +137,12 @@ class Publisher {
|
|
|
108
137
|
return provider;
|
|
109
138
|
}
|
|
110
139
|
assertSchema(config) {
|
|
140
|
+
var _a, _b;
|
|
111
141
|
const { schema } = config;
|
|
112
142
|
let hash = this.hashes.get(schema);
|
|
113
143
|
if (!hash) {
|
|
114
|
-
|
|
144
|
+
(_b = (_a = this.logger).debug) === null || _b === void 0 ? void 0 : _b.call(_a, `Calculating schema id for ${config.name}`);
|
|
145
|
+
const jsonSchema = JSON.stringify(zod_1.z.toJSONSchema(schema, { io: "input" }), null, 2);
|
|
115
146
|
hash = (0, crypto_1.createHash)("sha256").update(jsonSchema).digest("hex");
|
|
116
147
|
this.hashes.set(schema, hash);
|
|
117
148
|
}
|
|
@@ -24,9 +24,10 @@ export declare class RabbitMqPublisher implements PublisherProvider {
|
|
|
24
24
|
* @param message The JSON message to send
|
|
25
25
|
* @returns A promise that is completed when the message is published
|
|
26
26
|
*/
|
|
27
|
-
publish(config: RabbitQueueExchangeConfiguration,
|
|
27
|
+
publish(config: RabbitQueueExchangeConfiguration, messages: string[]): Promise<void>;
|
|
28
28
|
enrichPublishedMesssageLog(config: RabbitQueueExchangeConfiguration): Record<string, unknown>;
|
|
29
29
|
private publishToExchange;
|
|
30
30
|
private publishToQueue;
|
|
31
|
+
private sendMessages;
|
|
31
32
|
close(): Promise<void> | undefined;
|
|
32
33
|
}
|
|
@@ -78,14 +78,14 @@ class RabbitMqPublisher {
|
|
|
78
78
|
* @param message The JSON message to send
|
|
79
79
|
* @returns A promise that is completed when the message is published
|
|
80
80
|
*/
|
|
81
|
-
publish(config,
|
|
81
|
+
publish(config, messages) {
|
|
82
82
|
return __awaiter(this, void 0, void 0, function* () {
|
|
83
83
|
const channel = yield this.getChannel(config);
|
|
84
84
|
if (config.publishToSpecificQueue) {
|
|
85
|
-
yield this.publishToQueue(channel, config.publishToSpecificQueue,
|
|
85
|
+
yield this.publishToQueue(channel, config.publishToSpecificQueue, messages);
|
|
86
86
|
}
|
|
87
87
|
else {
|
|
88
|
-
yield this.publishToExchange(channel, config,
|
|
88
|
+
yield this.publishToExchange(channel, config, messages);
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
}
|
|
@@ -100,28 +100,31 @@ class RabbitMqPublisher {
|
|
|
100
100
|
routingKey: (0, config_js_1.getRoutingKey)(config),
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
publishToExchange(channel, config,
|
|
103
|
+
publishToExchange(channel, config, messages) {
|
|
104
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
105
|
const exchangeName = (0, config_js_1.getExchangeName)(config);
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
timestamp: new Date().valueOf(),
|
|
109
|
-
persistent: true,
|
|
110
|
-
});
|
|
111
|
-
if (!ok) {
|
|
112
|
-
throw new errors_js_1.PublishError(`RabbitMq publish to ${exchangeName} failed`);
|
|
113
|
-
}
|
|
106
|
+
const routingKey = (0, config_js_1.getRoutingKey)(config);
|
|
107
|
+
return this.sendMessages(messages, (buf, options) => channel.publish(exchangeName, routingKey, buf, options), "publish to exchange", exchangeName);
|
|
114
108
|
});
|
|
115
109
|
}
|
|
116
|
-
publishToQueue(channel, queue,
|
|
110
|
+
publishToQueue(channel, queue, messages) {
|
|
111
|
+
return this.sendMessages(messages, (buf, options) => channel.sendToQueue(queue, buf, options), "send to queue", queue);
|
|
112
|
+
}
|
|
113
|
+
sendMessages(messages, sender, action, name) {
|
|
117
114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
const
|
|
115
|
+
const options = {
|
|
119
116
|
contentType: "application/json",
|
|
120
117
|
timestamp: new Date().valueOf(),
|
|
121
118
|
persistent: true,
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
};
|
|
120
|
+
const oks = yield Promise.all(messages.map((message) => sender(Buffer.from(message, "utf8"), options)));
|
|
121
|
+
const failedMessages = oks
|
|
122
|
+
.map((ok, index) => ({ ok, index }))
|
|
123
|
+
.filter(({ ok }) => !ok)
|
|
124
|
+
.map(({ index }) => messages[index]);
|
|
125
|
+
if (failedMessages.length > 0) {
|
|
126
|
+
const allOrSome = failedMessages.length === messages.length ? "all" : "some";
|
|
127
|
+
throw new errors_js_1.PublishError(`RabbitMq ${action} ${name} failed for ${allOrSome} messages`, failedMessages);
|
|
125
128
|
}
|
|
126
129
|
});
|
|
127
130
|
}
|
|
@@ -9,7 +9,7 @@ export declare class RabbitMqPubSubProvider implements PubSubProvider {
|
|
|
9
9
|
private readonly subscriber;
|
|
10
10
|
constructor(connection: RabbitMqConnection, logger: Logger);
|
|
11
11
|
readonly transport: string;
|
|
12
|
-
publish(config: RabbitQueueExchangeConfiguration,
|
|
12
|
+
publish(config: RabbitQueueExchangeConfiguration, messages: string[]): Promise<void>;
|
|
13
13
|
startSubscribe(config: RabbitQueueExchangeConfiguration, onMessage: (s: string, context: MessageContext) => Promise<MessageResult> | MessageResult): StopSubscribe;
|
|
14
14
|
close(): Promise<void>;
|
|
15
15
|
init(config: RabbitQueueExchangeConfiguration): Promise<void>;
|
package/dist/rabbitmq/pubsub.js
CHANGED
|
@@ -22,8 +22,8 @@ class RabbitMqPubSubProvider {
|
|
|
22
22
|
this.publisher = new publisher_js_1.RabbitMqPublisher(connection, logger);
|
|
23
23
|
this.subscriber = new subscriber_js_1.RabbitMqSubscriber(connection, logger);
|
|
24
24
|
}
|
|
25
|
-
publish(config,
|
|
26
|
-
return this.publisher.publish(config,
|
|
25
|
+
publish(config, messages) {
|
|
26
|
+
return this.publisher.publish(config, messages);
|
|
27
27
|
}
|
|
28
28
|
startSubscribe(config, onMessage) {
|
|
29
29
|
return this.subscriber.startSubscribe(config, onMessage);
|
package/dist/subscriber.js
CHANGED
|
@@ -15,6 +15,7 @@ const errors_js_1 = require("./errors.js");
|
|
|
15
15
|
const events_1 = require("events");
|
|
16
16
|
const message_logger_js_1 = require("./message-logger.js");
|
|
17
17
|
const create_log_error_payload_js_1 = require("./create-log-error-payload.js");
|
|
18
|
+
const dd_trace_wrapper_js_1 = require("./dd-trace.wrapper.js");
|
|
18
19
|
class SubscribedMessage {
|
|
19
20
|
constructor(stop) {
|
|
20
21
|
this.stop = stop;
|
|
@@ -56,6 +57,14 @@ class Subscriber {
|
|
|
56
57
|
throw new errors_js_1.MissingPubSubProviderError(`No provider configured for ${config.transport}`);
|
|
57
58
|
}
|
|
58
59
|
const transform = (jsonStr, context) => __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const tracer = (0, dd_trace_wrapper_js_1.getTracer)();
|
|
61
|
+
const span = tracer.startSpan("pubsub.handleMessage", {
|
|
62
|
+
childOf: tracer.scope().active(),
|
|
63
|
+
tags: {
|
|
64
|
+
"pubsub.transport": config.transport,
|
|
65
|
+
"pubsub.name": config.name,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
59
68
|
const start = (0, message_logger_js_1.startTiming)();
|
|
60
69
|
const jsonObject = JSON.parse(jsonStr);
|
|
61
70
|
const r = schema.safeDecode(jsonObject);
|
|
@@ -77,6 +86,8 @@ class Subscriber {
|
|
|
77
86
|
};
|
|
78
87
|
this.events.emit("schemaError", handledEventContext);
|
|
79
88
|
this.events.emit("messageHandled", handledEventContext);
|
|
89
|
+
span.setTag("pubsub.success", false);
|
|
90
|
+
span.finish();
|
|
80
91
|
return interfaces_js_1.MessageResult.Fail;
|
|
81
92
|
}
|
|
82
93
|
try {
|
|
@@ -98,6 +109,9 @@ class Subscriber {
|
|
|
98
109
|
result }, provider.enrichHandledMesssageLog(config)),
|
|
99
110
|
});
|
|
100
111
|
this.events.emit("messageHandled", eventContext);
|
|
112
|
+
span.setTag("pubsub.duration_ms", durationMs);
|
|
113
|
+
span.setTag("pubsub.success", true);
|
|
114
|
+
span.finish();
|
|
101
115
|
return result;
|
|
102
116
|
}
|
|
103
117
|
catch (err) {
|
|
@@ -117,6 +131,8 @@ class Subscriber {
|
|
|
117
131
|
err,
|
|
118
132
|
};
|
|
119
133
|
this.events.emit("messageHandled", eventContext);
|
|
134
|
+
span.setTag("pubsub.success", false);
|
|
135
|
+
span.finish();
|
|
120
136
|
throw err;
|
|
121
137
|
}
|
|
122
138
|
});
|