@vtex/api 6.45.22 → 6.45.24

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/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [6.45.24] - 2023-10-05
11
+ ### Added
12
+
13
+ - Allow disabling memoization for all requests of a client
14
+ ## [6.45.23] - 2023-10-04
15
+
16
+ ### Fixed
17
+ - Fix metrics being restricted by tracing restrictions
18
+
10
19
  ## [6.45.22] - 2023-09-20
11
20
 
12
21
  ### Removed
@@ -8,6 +8,7 @@ export declare class HttpClient {
8
8
  name: string;
9
9
  private logger;
10
10
  private cacheableType;
11
+ private memoizable;
11
12
  private runMiddlewares;
12
13
  constructor(opts: ClientOptions);
13
14
  get: <T = any>(url: string, config?: RequestConfig) => Promise<T>;
@@ -97,14 +97,15 @@ class HttpClient {
97
97
  };
98
98
  this.getConfig = (url, config = {}) => ({
99
99
  cacheable: this.cacheableType,
100
- memoizable: true,
100
+ memoizable: this.memoizable,
101
101
  ...config,
102
102
  url,
103
103
  });
104
- const { baseURL, authToken, authType, memoryCache, diskCache, locale, name, metrics, product, serverTiming, recorder, userAgent, timeout = DEFAULT_TIMEOUT_MS, segmentToken, sessionToken, retries, concurrency, headers: defaultHeaders, host, params, operationId, tenant, binding, verbose, cancellation, exponentialTimeoutCoefficient, initialBackoffDelay, exponentialBackoffCoefficient, httpsAgent, tracer, logger, cacheableType = cache_1.CacheType.Memory, } = opts;
104
+ const { baseURL, authToken, authType, memoryCache, diskCache, memoizable = true, locale, name, metrics, product, serverTiming, recorder, userAgent, timeout = DEFAULT_TIMEOUT_MS, segmentToken, sessionToken, retries, concurrency, headers: defaultHeaders, host, params, operationId, tenant, binding, verbose, cancellation, exponentialTimeoutCoefficient, initialBackoffDelay, exponentialBackoffCoefficient, httpsAgent, tracer, logger, cacheableType = cache_1.CacheType.Memory, } = opts;
105
105
  this.name = name || baseURL || 'unknown';
106
106
  this.logger = logger;
107
107
  this.cacheableType = cacheableType;
108
+ this.memoizable = memoizable;
108
109
  const limit = concurrency && concurrency > 0 && p_limit_1.default(concurrency) || undefined;
109
110
  const headers = {
110
111
  ...defaultHeaders,
@@ -74,6 +74,16 @@ export interface InstanceOptions {
74
74
  timeout?: number;
75
75
  memoryCache?: CacheLayer<string, Cached>;
76
76
  diskCache?: CacheLayer<string, Cached>;
77
+ /**
78
+ * Enables memoization, ephemeral within each request, for all requests of this client.
79
+ * Useful for services that makes recursive requests, like graphql resolvers, which
80
+ * might fetch the same endpoint more than once.
81
+ * If that's not the case for your service, disabling it might improve the CPU and
82
+ * memory usage.
83
+ *
84
+ * Default value: true
85
+ */
86
+ memoizable?: boolean;
77
87
  baseURL?: string;
78
88
  retries?: number;
79
89
  exponentialTimeoutCoefficient?: number;
@@ -0,0 +1,2 @@
1
+ import { ServiceContext } from '../worker/runtime/typings';
2
+ export declare const addRequestMetricsMiddleware: () => (ctx: ServiceContext<import("../..").IOClients, import("../worker/runtime/typings").RecorderState, import("../worker/runtime/typings").ParamsContext>, next: () => Promise<void>) => Promise<void>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const stream_1 = require("stream");
4
+ const utils_1 = require("../../utils");
5
+ const instruments_1 = require("../tracing/metrics/instruments");
6
+ exports.addRequestMetricsMiddleware = () => {
7
+ const concurrentRequests = instruments_1.createConcurrentRequestsInstrument();
8
+ const requestTimings = instruments_1.createRequestsTimingsInstrument();
9
+ const totalRequests = instruments_1.createTotalRequestsInstrument();
10
+ const responseSizes = instruments_1.createRequestsResponseSizesInstrument();
11
+ const abortedRequests = instruments_1.createTotalAbortedRequestsInstrument();
12
+ return async function addRequestMetrics(ctx, next) {
13
+ const start = process.hrtime();
14
+ concurrentRequests.inc(1);
15
+ ctx.req.once('aborted', () => abortedRequests.inc({ ["handler" /* REQUEST_HANDLER */]: ctx.requestHandlerName }, 1));
16
+ let responseClosed = false;
17
+ ctx.res.once('close', () => (responseClosed = true));
18
+ try {
19
+ await next();
20
+ }
21
+ finally {
22
+ const responseLength = ctx.response.length;
23
+ if (responseLength) {
24
+ responseSizes.observe({ ["handler" /* REQUEST_HANDLER */]: ctx.requestHandlerName }, responseLength);
25
+ }
26
+ totalRequests.inc({
27
+ ["handler" /* REQUEST_HANDLER */]: ctx.requestHandlerName,
28
+ ["status_code" /* STATUS_CODE */]: ctx.response.status,
29
+ }, 1);
30
+ const onResFinished = () => {
31
+ requestTimings.observe({
32
+ ["handler" /* REQUEST_HANDLER */]: ctx.requestHandlerName,
33
+ }, utils_1.hrToMillisFloat(process.hrtime(start)));
34
+ concurrentRequests.dec(1);
35
+ };
36
+ if (responseClosed) {
37
+ onResFinished();
38
+ }
39
+ else {
40
+ stream_1.finished(ctx.res, onResFinished);
41
+ }
42
+ }
43
+ };
44
+ };
@@ -7,23 +7,14 @@ const tracing_1 = require("../../tracing");
7
7
  const Tags_1 = require("../../tracing/Tags");
8
8
  const utils_1 = require("../../tracing/utils");
9
9
  const utils_2 = require("../../utils");
10
- const instruments_1 = require("./metrics/instruments");
11
10
  const PATHS_BLACKLISTED_FOR_TRACING = ['/_status', '/healthcheck'];
12
11
  exports.addTracingMiddleware = (tracer) => {
13
- const concurrentRequests = instruments_1.createConcurrentRequestsInstrument();
14
- const requestTimings = instruments_1.createRequestsTimingsInstrument();
15
- const totalRequests = instruments_1.createTotalRequestsInstrument();
16
- const responseSizes = instruments_1.createRequestsResponseSizesInstrument();
17
- const abortedRequests = instruments_1.createTotalAbortedRequestsInstrument();
18
12
  return async function addTracing(ctx, next) {
19
13
  var _a;
20
- const start = process.hrtime();
21
- concurrentRequests.inc(1);
22
14
  const rootSpan = tracer.extract(opentracing_1.FORMAT_HTTP_HEADERS, ctx.request.headers);
23
15
  ctx.tracing = { tracer, currentSpan: undefined };
24
16
  if (!shouldTrace(ctx, rootSpan)) {
25
17
  await next();
26
- concurrentRequests.dec(1);
27
18
  return;
28
19
  }
29
20
  const currentSpan = tracer.startSpan('unknown-operation', {
@@ -32,7 +23,6 @@ exports.addTracingMiddleware = (tracer) => {
32
23
  });
33
24
  const initialSamplingDecision = tracing_1.getTraceInfo(currentSpan).isSampled;
34
25
  ctx.tracing = { currentSpan, tracer };
35
- ctx.req.once('aborted', () => abortedRequests.inc({ ["handler" /* REQUEST_HANDLER */]: currentSpan.operationName }, 1));
36
26
  let responseClosed = false;
37
27
  ctx.res.once('close', () => (responseClosed = true));
38
28
  try {
@@ -43,14 +33,6 @@ exports.addTracingMiddleware = (tracer) => {
43
33
  throw err;
44
34
  }
45
35
  finally {
46
- const responseLength = ctx.response.length;
47
- if (responseLength) {
48
- responseSizes.observe({ ["handler" /* REQUEST_HANDLER */]: currentSpan.operationName }, responseLength);
49
- }
50
- totalRequests.inc({
51
- ["handler" /* REQUEST_HANDLER */]: currentSpan.operationName,
52
- ["status_code" /* STATUS_CODE */]: ctx.response.status,
53
- }, 1);
54
36
  const traceInfo = tracing_1.getTraceInfo(currentSpan);
55
37
  if (traceInfo === null || traceInfo === void 0 ? void 0 : traceInfo.isSampled) {
56
38
  if (!initialSamplingDecision) {
@@ -70,10 +52,6 @@ exports.addTracingMiddleware = (tracer) => {
70
52
  ctx.set(constants_1.TRACE_ID_HEADER, traceInfo.traceId);
71
53
  }
72
54
  const onResFinished = () => {
73
- requestTimings.observe({
74
- ["handler" /* REQUEST_HANDLER */]: currentSpan.operationName,
75
- }, utils_2.hrToMillisFloat(process.hrtime(start)));
76
- concurrentRequests.dec(1);
77
55
  currentSpan === null || currentSpan === void 0 ? void 0 : currentSpan.finish();
78
56
  };
79
57
  if (responseClosed) {
@@ -88,7 +66,8 @@ exports.addTracingMiddleware = (tracer) => {
88
66
  exports.nameSpanOperationMiddleware = (operationType, operationName) => {
89
67
  return function nameSpanOperation(ctx, next) {
90
68
  var _a, _b;
91
- (_b = (_a = ctx.tracing) === null || _a === void 0 ? void 0 : _a.currentSpan) === null || _b === void 0 ? void 0 : _b.setOperationName(`${operationType}:${operationName}`);
69
+ ctx.requestHandlerName = `${operationType}:${operationName}`;
70
+ (_b = (_a = ctx.tracing) === null || _a === void 0 ? void 0 : _a.currentSpan) === null || _b === void 0 ? void 0 : _b.setOperationName(ctx.requestHandlerName);
92
71
  return next();
93
72
  };
94
73
  };
@@ -13,6 +13,7 @@ const MetricsAccumulator_1 = require("../../metrics/MetricsAccumulator");
13
13
  const loaders_1 = require("../loaders");
14
14
  const console_1 = require("../logger/console");
15
15
  const logger_1 = require("../logger/logger");
16
+ const requestMetricsMiddleware_1 = require("../metrics/requestMetricsMiddleware");
16
17
  const TracerSingleton_1 = require("../tracing/TracerSingleton");
17
18
  const tracingMiddlewares_1 = require("../tracing/tracingMiddlewares");
18
19
  const listeners_1 = require("./listeners");
@@ -157,6 +158,7 @@ exports.startWorker = (serviceJSON) => {
157
158
  .use(error_1.error)
158
159
  .use(middlewares_1.prometheusLoggerMiddleware())
159
160
  .use(tracingMiddlewares_1.addTracingMiddleware(tracer))
161
+ .use(requestMetricsMiddleware_1.addRequestMetricsMiddleware())
160
162
  .use(middlewares_1.addMetricsLoggerMiddleware())
161
163
  .use(rateLimit_1.concurrentRateLimiter((_a = serviceJSON === null || serviceJSON === void 0 ? void 0 : serviceJSON.rateLimitPerReplica) === null || _a === void 0 ? void 0 : _a.concurrent))
162
164
  .use(koa_compress_1.default())
@@ -29,6 +29,7 @@ export interface Context<T extends IOClients> {
29
29
  timings: Record<string, [number, number]>;
30
30
  metrics: Record<string, [number, number]>;
31
31
  previousTimerStart: [number, number];
32
+ requestHandlerName?: string;
32
33
  serverTiming?: ServerTiming;
33
34
  tracing?: TracingContext;
34
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/api",
3
- "version": "6.45.22",
3
+ "version": "6.45.24",
4
4
  "description": "VTEX I/O API client",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",