@palmetto/pubsub 2.2.2 → 2.2.3

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.
@@ -1,12 +1,4 @@
1
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
2
  /**
11
3
  * Adds a single tag to the span. See `addTags()` for details.
12
4
  *
@@ -16,19 +8,13 @@ interface Span {
16
8
  setTag(key: string, value: unknown): this;
17
9
  }
18
10
  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
11
  /**
26
12
  * set of key-value pairs which will be set as tags on the newly created
27
13
  * Span. Ownership of the object is passed to the created span for
28
14
  * efficiency reasons (the caller should not modify this object after
29
15
  * calling startSpan).
30
16
  */
31
- tags: {
17
+ tags?: {
32
18
  [key: string]: unknown;
33
19
  };
34
20
  }
@@ -43,19 +29,47 @@ interface Scope {
43
29
  */
44
30
  active(): Span | null;
45
31
  }
32
+ interface TraceOptions {
33
+ /**
34
+ * The resource you are tracing. The resource name must not be longer than
35
+ * 5000 characters.
36
+ */
37
+ resource?: string;
38
+ /**
39
+ * The type of request.
40
+ */
41
+ type?: string;
42
+ }
46
43
  interface Tracer {
47
44
  /**
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.
45
+ * Instruments a function by automatically creating a span activated on its
46
+ * scope.
47
+ *
48
+ * The span will automatically be finished when one of these conditions is
49
+ * met:
50
+ *
51
+ * * The function returns a promise, in which case the span will finish when
52
+ * the promise is resolved or rejected.
53
+ * * The function takes a callback as its second parameter, in which case the
54
+ * span will finish when that callback is called.
55
+ * * The function doesn't accept a callback and doesn't return a promise, in
56
+ * which case the span will finish at the end of the function execution.
52
57
  */
53
- startSpan(name: string, options: SpanOptions): Span;
58
+ trace<T>(name: string, options: TraceOptions & SpanOptions, fn: (span: Span) => Promise<T>): Promise<T>;
54
59
  /**
55
60
  * Returns a reference to the current scope.
56
61
  */
57
62
  scope(): Scope;
58
63
  }
59
64
  export declare function getTracer(): Tracer;
65
+ /**
66
+ * Registers the dd-trace tracer instance to be used by the pubsub package.
67
+ *
68
+ * Usage:
69
+ * import trace from 'dd-trace';
70
+ * registerDdTrace(trace.init());
71
+ *
72
+ * @param tracer the tracer instance
73
+ */
60
74
  export declare function registerDdTrace(tracer: unknown): void;
61
75
  export {};
@@ -20,8 +20,8 @@ class NoOpTracer {
20
20
  this.noOpSpan = new NoOpSpan();
21
21
  this.noOpScope = new NoOpScope();
22
22
  }
23
- startSpan(_name, _options) {
24
- return this.noOpSpan;
23
+ trace(_name, _options, fn) {
24
+ return fn(this.noOpSpan);
25
25
  }
26
26
  scope() {
27
27
  return this.noOpScope;
@@ -31,6 +31,15 @@ let tracerInstance = new NoOpTracer();
31
31
  function getTracer() {
32
32
  return tracerInstance;
33
33
  }
34
+ /**
35
+ * Registers the dd-trace tracer instance to be used by the pubsub package.
36
+ *
37
+ * Usage:
38
+ * import trace from 'dd-trace';
39
+ * registerDdTrace(trace.init());
40
+ *
41
+ * @param tracer the tracer instance
42
+ */
34
43
  function registerDdTrace(tracer) {
35
44
  tracerInstance = tracer;
36
45
  }
package/dist/publisher.js CHANGED
@@ -54,71 +54,66 @@ class Publisher {
54
54
  }
55
55
  publish(config, message) {
56
56
  return __awaiter(this, void 0, void 0, function* () {
57
- const tracer = (0, dd_trace_wrapper_js_1.getTracer)();
58
- const span = tracer.startSpan("pubsub.publish", {
59
- childOf: tracer.scope().active(),
57
+ yield (0, dd_trace_wrapper_js_1.getTracer)().trace("pubsub.publish", {
58
+ resource: config.name,
60
59
  tags: {
61
60
  "pubsub.transport": config.transport,
62
- "pubsub.name": config.name,
63
61
  },
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;
62
+ }, (span) => __awaiter(this, void 0, void 0, function* () {
63
+ try {
64
+ const provider = this.getProvider(config);
65
+ const { schema, schemaId } = this.assertSchema(config);
66
+ if (!Array.isArray(message)) {
67
+ message = [message];
84
68
  }
85
- const check = schema.safeEncode(msg);
86
- if (!check.success) {
69
+ const jsons = message.map((msg) => {
70
+ if (!msg.id) {
71
+ msg.id = (0, uuid_1.v4)();
72
+ }
73
+ if (!msg.meta) {
74
+ msg.meta = {
75
+ createdAt: new Date().toISOString(),
76
+ publishedBy: "",
77
+ schemaId: schemaId,
78
+ };
79
+ }
80
+ else {
81
+ msg.meta.schemaId = schemaId;
82
+ }
83
+ const check = schema.safeEncode(msg);
84
+ if (!check.success) {
85
+ (0, message_logger_js_1.logMessage)({
86
+ note: "Publish message failed schema validation",
87
+ message: message,
88
+ level: "error",
89
+ logger: this.logger,
90
+ extra: Object.assign({ transport: provider.transport, name: config.name }, provider.enrichPublishedMesssageLog(config)),
91
+ });
92
+ throw new errors_js_1.SchemaValidationError(`Schema did not accept the published message: ${check.error.message}`);
93
+ }
94
+ const json = JSON.stringify(check.data);
95
+ return { json, data: check.data };
96
+ });
97
+ const start = (0, message_logger_js_1.startTiming)();
98
+ yield provider.publish(config, jsons.map((j) => j.json));
99
+ const duration = (0, message_logger_js_1.getDuration)(start);
100
+ jsons.forEach((msg) => {
87
101
  (0, message_logger_js_1.logMessage)({
88
- note: "Publish message failed schema validation",
89
- message: message,
90
- level: "error",
102
+ note: "Published message",
103
+ message: msg.data,
104
+ level: config.messageLogLevel,
91
105
  logger: this.logger,
92
- extra: Object.assign({ transport: provider.transport, name: config.name }, provider.enrichPublishedMesssageLog(config)),
106
+ extra: Object.assign({ transport: provider.transport, name: config.name, durationMs: duration }, provider.enrichPublishedMesssageLog(config)),
93
107
  });
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
108
  });
110
- });
111
- span.setTag("pubsub.duration_ms", duration);
112
- span.setTag("pubsub.message_count", message.length);
113
- span.setTag("pubsub.success", true);
114
- }
115
- catch (err) {
116
- span.setTag("pubsub.success", false);
117
- throw err;
118
- }
119
- finally {
120
- span.finish();
121
- }
109
+ span.setTag("pubsub.duration_ms", duration);
110
+ span.setTag("pubsub.message_count", message.length);
111
+ }
112
+ catch (err) {
113
+ span.setTag("error", err);
114
+ throw err;
115
+ }
116
+ }));
122
117
  });
123
118
  }
124
119
  close() {
@@ -38,7 +38,7 @@ class RabbitMqPublisher {
38
38
  var _a, _b, _c, _d;
39
39
  const delayMs = this.connection.config.startupRetryDelayMs || 500;
40
40
  const timeoutMs = this.connection.config.startupRetryTimeoutMs || 20000;
41
- const timeoutAfter = new Date(new Date().getTime() + timeoutMs);
41
+ const timeoutAfter = Date.now() + timeoutMs;
42
42
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
43
43
  while (true) {
44
44
  try {
@@ -63,7 +63,7 @@ class RabbitMqPublisher {
63
63
  return this.channel;
64
64
  }
65
65
  catch (err) {
66
- if (new Date() >= timeoutAfter) {
66
+ if (Date.now() >= timeoutAfter) {
67
67
  throw err;
68
68
  }
69
69
  yield (0, utility_js_1.delay)(delayMs);
@@ -114,7 +114,7 @@ class RabbitMqPublisher {
114
114
  return __awaiter(this, void 0, void 0, function* () {
115
115
  const options = {
116
116
  contentType: "application/json",
117
- timestamp: new Date().valueOf(),
117
+ timestamp: Date.now(),
118
118
  persistent: true,
119
119
  };
120
120
  const oks = yield Promise.all(messages.map((message) => sender(Buffer.from(message, "utf8"), options)));
@@ -57,84 +57,79 @@ class Subscriber {
57
57
  throw new errors_js_1.MissingPubSubProviderError(`No provider configured for ${config.transport}`);
58
58
  }
59
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(),
60
+ return yield (0, dd_trace_wrapper_js_1.getTracer)().trace("pubsub.handleMessage", {
61
+ resource: config.name,
63
62
  tags: {
64
63
  "pubsub.transport": config.transport,
65
- "pubsub.name": config.name,
66
64
  },
67
- });
68
- const start = (0, message_logger_js_1.startTiming)();
69
- const jsonObject = JSON.parse(jsonStr);
70
- const r = schema.safeDecode(jsonObject);
71
- if (!r.success) {
72
- const durationMs = (0, message_logger_js_1.getDuration)(start);
73
- (0, message_logger_js_1.logMessage)({
74
- note: "Subscribed message failed schema validation",
75
- message: jsonObject,
76
- level: "error",
77
- logger: this.logger,
78
- extra: Object.assign({ transport: provider.transport, name: config.name, durationMs }, provider.enrichHandledMesssageLog(config)),
79
- });
80
- const handledEventContext = {
81
- message: jsonStr,
82
- context,
83
- config,
84
- durationMs,
85
- result: interfaces_js_1.MessageResult.Fail,
86
- };
87
- this.events.emit("schemaError", handledEventContext);
88
- this.events.emit("messageHandled", handledEventContext);
89
- span.setTag("pubsub.success", false);
90
- span.finish();
91
- return interfaces_js_1.MessageResult.Fail;
92
- }
93
- try {
94
- const result = yield onMessage(r.data, context);
95
- const durationMs = (0, message_logger_js_1.getDuration)(start);
96
- const eventContext = {
97
- message: jsonStr,
98
- context,
99
- config,
100
- durationMs,
101
- result,
102
- };
103
- (0, message_logger_js_1.logMessage)({
104
- note: "Subscriber processed message",
105
- message: r.data,
106
- level: config.messageLogLevel,
107
- logger: this.logger,
108
- extra: Object.assign({ transport: provider.transport, name: config.name, durationMs,
109
- result }, provider.enrichHandledMesssageLog(config)),
110
- });
111
- this.events.emit("messageHandled", eventContext);
112
- span.setTag("pubsub.duration_ms", durationMs);
113
- span.setTag("pubsub.success", true);
114
- span.finish();
115
- return result;
116
- }
117
- catch (err) {
118
- const durationMs = (0, message_logger_js_1.getDuration)(start);
119
- (0, message_logger_js_1.logMessage)({
120
- note: "Subscriber error when processing message",
121
- message: r.data,
122
- level: "error",
123
- logger: this.logger,
124
- extra: Object.assign(Object.assign({ transport: provider.transport, name: config.name, durationMs }, provider.enrichHandledMesssageLog(config)), { error: (0, create_log_error_payload_js_1.createLogErrorPayload)(err) }),
125
- });
126
- const eventContext = {
127
- message: jsonStr,
128
- context,
129
- config,
130
- durationMs,
131
- err,
132
- };
133
- this.events.emit("messageHandled", eventContext);
134
- span.setTag("pubsub.success", false);
135
- span.finish();
136
- throw err;
137
- }
65
+ }, (span) => __awaiter(this, void 0, void 0, function* () {
66
+ const start = (0, message_logger_js_1.startTiming)();
67
+ const jsonObject = JSON.parse(jsonStr);
68
+ const r = schema.safeDecode(jsonObject);
69
+ if (!r.success) {
70
+ const durationMs = (0, message_logger_js_1.getDuration)(start);
71
+ (0, message_logger_js_1.logMessage)({
72
+ note: "Subscribed message failed schema validation",
73
+ message: jsonObject,
74
+ level: "error",
75
+ logger: this.logger,
76
+ extra: Object.assign({ transport: provider.transport, name: config.name, durationMs }, provider.enrichHandledMesssageLog(config)),
77
+ });
78
+ const handledEventContext = {
79
+ message: jsonStr,
80
+ context,
81
+ config,
82
+ durationMs,
83
+ result: interfaces_js_1.MessageResult.Fail,
84
+ };
85
+ this.events.emit("schemaError", handledEventContext);
86
+ this.events.emit("messageHandled", handledEventContext);
87
+ span.setTag("error", r.error);
88
+ return interfaces_js_1.MessageResult.Fail;
89
+ }
90
+ try {
91
+ const result = yield onMessage(r.data, context);
92
+ const durationMs = (0, message_logger_js_1.getDuration)(start);
93
+ const eventContext = {
94
+ message: jsonStr,
95
+ context,
96
+ config,
97
+ durationMs,
98
+ result,
99
+ };
100
+ (0, message_logger_js_1.logMessage)({
101
+ note: "Subscriber processed message",
102
+ message: r.data,
103
+ level: config.messageLogLevel,
104
+ logger: this.logger,
105
+ extra: Object.assign({ transport: provider.transport, name: config.name, durationMs,
106
+ result }, provider.enrichHandledMesssageLog(config)),
107
+ });
108
+ this.events.emit("messageHandled", eventContext);
109
+ span.setTag("pubsub.duration_ms", durationMs);
110
+ return result;
111
+ }
112
+ catch (err) {
113
+ const durationMs = (0, message_logger_js_1.getDuration)(start);
114
+ (0, message_logger_js_1.logMessage)({
115
+ note: "Subscriber error when processing message",
116
+ message: r.data,
117
+ level: "error",
118
+ logger: this.logger,
119
+ extra: Object.assign(Object.assign({ transport: provider.transport, name: config.name, durationMs }, provider.enrichHandledMesssageLog(config)), { error: (0, create_log_error_payload_js_1.createLogErrorPayload)(err) }),
120
+ });
121
+ const eventContext = {
122
+ message: jsonStr,
123
+ context,
124
+ config,
125
+ durationMs,
126
+ err,
127
+ };
128
+ this.events.emit("messageHandled", eventContext);
129
+ span.setTag("error", r.error);
130
+ throw err;
131
+ }
132
+ }));
138
133
  });
139
134
  this.logger.log(`Starting subscriber for ${config.transport}:${config.name}`);
140
135
  subscribedMessage = new SubscribedMessage(yield provider.startSubscribe(config, transform));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palmetto/pubsub",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "main": "./dist/main.js",
5
5
  "scripts": {
6
6
  "lint": "yarn run -T eslint --fix ./src",