@reproapp/node-sdk 0.0.22 → 0.0.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/dist/index.js +29 -7
- package/dist/ingest/client.d.ts +1 -1
- package/dist/ingest/client.js +2 -1
- package/package.json +1 -1
- package/src/index.ts +30 -8
- package/src/ingest/client.ts +3 -2
- package/test/trace-batch-size.test.js +16 -0
package/dist/index.js
CHANGED
|
@@ -1525,9 +1525,10 @@ function resolveCollectionOrWarn(source, type) {
|
|
|
1525
1525
|
function post(cfg, sessionId, body, options) {
|
|
1526
1526
|
try {
|
|
1527
1527
|
const entries = Array.isArray(body?.entries) ? body.entries : [];
|
|
1528
|
-
(0, client_1.enqueueIngestEntries)(cfg, sessionId, entries, options);
|
|
1528
|
+
return (0, client_1.enqueueIngestEntries)(cfg, sessionId, entries, options);
|
|
1529
1529
|
}
|
|
1530
1530
|
catch { /* swallow in SDK */ }
|
|
1531
|
+
return false;
|
|
1531
1532
|
}
|
|
1532
1533
|
function toIngestConfig(cfg) {
|
|
1533
1534
|
return {
|
|
@@ -1712,6 +1713,18 @@ const TRACE_BATCH_MAX_SERIALIZED_BYTES = (() => {
|
|
|
1712
1713
|
return Math.trunc(env);
|
|
1713
1714
|
return 512 * 1024;
|
|
1714
1715
|
})();
|
|
1716
|
+
const TRACE_MAX_EVENTS_PER_REQUEST = (() => {
|
|
1717
|
+
const env = Number(process.env.REPRO_TRACE_MAX_EVENTS_PER_REQUEST);
|
|
1718
|
+
if (Number.isFinite(env) && env > 0)
|
|
1719
|
+
return Math.trunc(env);
|
|
1720
|
+
return 1000;
|
|
1721
|
+
})();
|
|
1722
|
+
const TRACE_MAX_BATCHES_PER_REQUEST = (() => {
|
|
1723
|
+
const env = Number(process.env.REPRO_TRACE_MAX_BATCHES_PER_REQUEST);
|
|
1724
|
+
if (Number.isFinite(env) && env > 0)
|
|
1725
|
+
return Math.trunc(env);
|
|
1726
|
+
return 8;
|
|
1727
|
+
})();
|
|
1715
1728
|
const TRACE_FLUSH_DELAY_MS = 20;
|
|
1716
1729
|
// Choose how to order trace events in payloads.
|
|
1717
1730
|
// - "chronological" (default): preserve event arrival order (no reshuffle).
|
|
@@ -3766,22 +3779,31 @@ function estimateTraceBatchSerializedBytes(batch, requestRid, actionId, batchInd
|
|
|
3766
3779
|
function chunkTraceEventsForTransport(events, requestRid, actionId) {
|
|
3767
3780
|
if (!Array.isArray(events) || events.length === 0)
|
|
3768
3781
|
return [];
|
|
3769
|
-
const
|
|
3782
|
+
const boundedEvents = events.slice(0, TRACE_MAX_EVENTS_PER_REQUEST);
|
|
3783
|
+
const countBatches = chunkArray(boundedEvents, TRACE_BATCH_SIZE);
|
|
3770
3784
|
const sizedBatches = [];
|
|
3771
3785
|
let current = [];
|
|
3772
3786
|
for (const event of countBatches.flat()) {
|
|
3787
|
+
if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
3788
|
+
break;
|
|
3789
|
+
}
|
|
3773
3790
|
const candidate = current.concat(event);
|
|
3774
3791
|
const batchIndex = sizedBatches.length;
|
|
3775
3792
|
const estimatedBytes = estimateTraceBatchSerializedBytes(candidate, requestRid, actionId, batchIndex);
|
|
3776
3793
|
if (current.length > 0 &&
|
|
3777
3794
|
estimatedBytes > TRACE_BATCH_MAX_SERIALIZED_BYTES) {
|
|
3778
3795
|
sizedBatches.push(current);
|
|
3796
|
+
if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
3797
|
+
current = [];
|
|
3798
|
+
break;
|
|
3799
|
+
}
|
|
3779
3800
|
current = [event];
|
|
3780
3801
|
continue;
|
|
3781
3802
|
}
|
|
3782
3803
|
current = candidate;
|
|
3783
3804
|
}
|
|
3784
|
-
if (current.length > 0
|
|
3805
|
+
if (current.length > 0 &&
|
|
3806
|
+
sizedBatches.length < TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
3785
3807
|
sizedBatches.push(current);
|
|
3786
3808
|
}
|
|
3787
3809
|
return sizedBatches;
|
|
@@ -4897,9 +4919,6 @@ function emitDbQuery(cfg, sid, aid, payload) {
|
|
|
4897
4919
|
const spanContext = payload?.spanContext ?? captureSpanContextFromTracer();
|
|
4898
4920
|
if (!shouldCaptureDbSpan(spanContext))
|
|
4899
4921
|
return;
|
|
4900
|
-
if (ctx.captureScope) {
|
|
4901
|
-
ctx.captureScope.dbChangeCount += 1;
|
|
4902
|
-
}
|
|
4903
4922
|
const runCtx = {
|
|
4904
4923
|
sid: ctx.sid,
|
|
4905
4924
|
aid: ctx.aid,
|
|
@@ -5018,7 +5037,7 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
|
|
|
5018
5037
|
resultMetaMaterialization: resultMetaMaterialization.skipped,
|
|
5019
5038
|
errorMaterialization: errorMaterialization.skipped,
|
|
5020
5039
|
}, spanContext);
|
|
5021
|
-
post(cfg, sid, {
|
|
5040
|
+
const enqueued = post(cfg, sid, {
|
|
5022
5041
|
entries: [{
|
|
5023
5042
|
actionId: aid ?? null,
|
|
5024
5043
|
requestRid: ctx.rid ?? null,
|
|
@@ -5027,6 +5046,9 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
|
|
|
5027
5046
|
t: payload.t,
|
|
5028
5047
|
}]
|
|
5029
5048
|
});
|
|
5049
|
+
if (enqueued && ctx.captureScope) {
|
|
5050
|
+
ctx.captureScope.dbChangeCount += 1;
|
|
5051
|
+
}
|
|
5030
5052
|
}
|
|
5031
5053
|
function buildMinimalUpdate(before, after) {
|
|
5032
5054
|
const set = {};
|
package/dist/ingest/client.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export declare const configureIngestQueueDrain: (options: {
|
|
|
8
8
|
}) => void;
|
|
9
9
|
export declare const kickIngestQueueDrain: () => void;
|
|
10
10
|
export declare const postIngestEntries: (config: IngestClientConfig, sessionId: string, entries: LegacyEntry[]) => Promise<void>;
|
|
11
|
-
export declare const enqueueIngestEntries: (config: IngestClientConfig, sessionId: string, entries: LegacyEntry[], options?: EnqueueIngestOptions) =>
|
|
11
|
+
export declare const enqueueIngestEntries: (config: IngestClientConfig, sessionId: string, entries: LegacyEntry[], options?: EnqueueIngestOptions) => boolean;
|
|
12
12
|
export declare const flushIngestQueue: () => Promise<void>;
|
|
13
13
|
export type { IngestClientConfig, LegacyEntry } from './types';
|
package/dist/ingest/client.js
CHANGED
|
@@ -173,7 +173,7 @@ const drainIngestQueue = async () => {
|
|
|
173
173
|
};
|
|
174
174
|
const enqueueIngestEntries = (config, sessionId, entries, options = {}) => {
|
|
175
175
|
if (!sessionId || !Array.isArray(entries) || entries.length === 0) {
|
|
176
|
-
return;
|
|
176
|
+
return false;
|
|
177
177
|
}
|
|
178
178
|
const priority = options.priority === 'high' ? 'high' : 'normal';
|
|
179
179
|
const batch = {
|
|
@@ -208,6 +208,7 @@ const enqueueIngestEntries = (config, sessionId, entries, options = {}) => {
|
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
scheduleDrain(shouldDeferDrain?.() ? deferDrainMs : 0);
|
|
211
|
+
return ingestQueue.includes(batch);
|
|
211
212
|
};
|
|
212
213
|
exports.enqueueIngestEntries = enqueueIngestEntries;
|
|
213
214
|
const flushIngestQueue = async () => {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1921,11 +1921,12 @@ function post(
|
|
|
1921
1921
|
sessionId: string,
|
|
1922
1922
|
body: any,
|
|
1923
1923
|
options?: EnqueueIngestOptions,
|
|
1924
|
-
) {
|
|
1924
|
+
): boolean {
|
|
1925
1925
|
try {
|
|
1926
1926
|
const entries = Array.isArray(body?.entries) ? (body.entries as LegacyEntry[]) : [];
|
|
1927
|
-
enqueueIngestEntries(cfg, sessionId, entries, options);
|
|
1927
|
+
return enqueueIngestEntries(cfg, sessionId, entries, options);
|
|
1928
1928
|
} catch { /* swallow in SDK */ }
|
|
1929
|
+
return false;
|
|
1929
1930
|
}
|
|
1930
1931
|
|
|
1931
1932
|
function toIngestConfig(cfg: IngestClientConfig): IngestClientConfig {
|
|
@@ -2116,6 +2117,16 @@ const TRACE_BATCH_MAX_SERIALIZED_BYTES = (() => {
|
|
|
2116
2117
|
if (Number.isFinite(env) && env > 0) return Math.trunc(env);
|
|
2117
2118
|
return 512 * 1024;
|
|
2118
2119
|
})();
|
|
2120
|
+
const TRACE_MAX_EVENTS_PER_REQUEST = (() => {
|
|
2121
|
+
const env = Number(process.env.REPRO_TRACE_MAX_EVENTS_PER_REQUEST);
|
|
2122
|
+
if (Number.isFinite(env) && env > 0) return Math.trunc(env);
|
|
2123
|
+
return 1000;
|
|
2124
|
+
})();
|
|
2125
|
+
const TRACE_MAX_BATCHES_PER_REQUEST = (() => {
|
|
2126
|
+
const env = Number(process.env.REPRO_TRACE_MAX_BATCHES_PER_REQUEST);
|
|
2127
|
+
if (Number.isFinite(env) && env > 0) return Math.trunc(env);
|
|
2128
|
+
return 8;
|
|
2129
|
+
})();
|
|
2119
2130
|
const TRACE_FLUSH_DELAY_MS = 20;
|
|
2120
2131
|
// Choose how to order trace events in payloads.
|
|
2121
2132
|
// - "chronological" (default): preserve event arrival order (no reshuffle).
|
|
@@ -4499,11 +4510,15 @@ function chunkTraceEventsForTransport(
|
|
|
4499
4510
|
): TraceEventRecord[][] {
|
|
4500
4511
|
if (!Array.isArray(events) || events.length === 0) return [];
|
|
4501
4512
|
|
|
4502
|
-
const
|
|
4513
|
+
const boundedEvents = events.slice(0, TRACE_MAX_EVENTS_PER_REQUEST);
|
|
4514
|
+
const countBatches = chunkArray(boundedEvents, TRACE_BATCH_SIZE);
|
|
4503
4515
|
const sizedBatches: TraceEventRecord[][] = [];
|
|
4504
4516
|
let current: TraceEventRecord[] = [];
|
|
4505
4517
|
|
|
4506
4518
|
for (const event of countBatches.flat()) {
|
|
4519
|
+
if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
4520
|
+
break;
|
|
4521
|
+
}
|
|
4507
4522
|
const candidate = current.concat(event);
|
|
4508
4523
|
const batchIndex = sizedBatches.length;
|
|
4509
4524
|
const estimatedBytes = estimateTraceBatchSerializedBytes(
|
|
@@ -4518,6 +4533,10 @@ function chunkTraceEventsForTransport(
|
|
|
4518
4533
|
estimatedBytes > TRACE_BATCH_MAX_SERIALIZED_BYTES
|
|
4519
4534
|
) {
|
|
4520
4535
|
sizedBatches.push(current);
|
|
4536
|
+
if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
4537
|
+
current = [];
|
|
4538
|
+
break;
|
|
4539
|
+
}
|
|
4521
4540
|
current = [event];
|
|
4522
4541
|
continue;
|
|
4523
4542
|
}
|
|
@@ -4525,7 +4544,10 @@ function chunkTraceEventsForTransport(
|
|
|
4525
4544
|
current = candidate;
|
|
4526
4545
|
}
|
|
4527
4546
|
|
|
4528
|
-
if (
|
|
4547
|
+
if (
|
|
4548
|
+
current.length > 0 &&
|
|
4549
|
+
sizedBatches.length < TRACE_MAX_BATCHES_PER_REQUEST
|
|
4550
|
+
) {
|
|
4529
4551
|
sizedBatches.push(current);
|
|
4530
4552
|
}
|
|
4531
4553
|
|
|
@@ -5837,9 +5859,6 @@ function emitDbQuery(cfg: any, sid?: string, aid?: string, payload?: any) {
|
|
|
5837
5859
|
const ctx = getCtx() as Ctx;
|
|
5838
5860
|
const spanContext = payload?.spanContext ?? captureSpanContextFromTracer();
|
|
5839
5861
|
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
5840
|
-
if (ctx.captureScope) {
|
|
5841
|
-
ctx.captureScope.dbChangeCount += 1;
|
|
5842
|
-
}
|
|
5843
5862
|
const runCtx: Ctx = {
|
|
5844
5863
|
sid: ctx.sid,
|
|
5845
5864
|
aid: ctx.aid,
|
|
@@ -5957,7 +5976,7 @@ async function emitDbQueryAsync(cfg: any, sid?: string, aid?: string, payload?:
|
|
|
5957
5976
|
resultMetaMaterialization: resultMetaMaterialization.skipped,
|
|
5958
5977
|
errorMaterialization: errorMaterialization.skipped,
|
|
5959
5978
|
}, spanContext);
|
|
5960
|
-
post(cfg, sid, {
|
|
5979
|
+
const enqueued = post(cfg, sid, {
|
|
5961
5980
|
entries: [{
|
|
5962
5981
|
actionId: aid ?? null,
|
|
5963
5982
|
requestRid: ctx.rid ?? null,
|
|
@@ -5966,6 +5985,9 @@ async function emitDbQueryAsync(cfg: any, sid?: string, aid?: string, payload?:
|
|
|
5966
5985
|
t: payload.t,
|
|
5967
5986
|
}]
|
|
5968
5987
|
});
|
|
5988
|
+
if (enqueued && ctx.captureScope) {
|
|
5989
|
+
ctx.captureScope.dbChangeCount += 1;
|
|
5990
|
+
}
|
|
5969
5991
|
}
|
|
5970
5992
|
|
|
5971
5993
|
function buildMinimalUpdate(before: any, after: any) {
|
package/src/ingest/client.ts
CHANGED
|
@@ -211,9 +211,9 @@ export const enqueueIngestEntries = (
|
|
|
211
211
|
sessionId: string,
|
|
212
212
|
entries: LegacyEntry[],
|
|
213
213
|
options: EnqueueIngestOptions = {},
|
|
214
|
-
):
|
|
214
|
+
): boolean => {
|
|
215
215
|
if (!sessionId || !Array.isArray(entries) || entries.length === 0) {
|
|
216
|
-
return;
|
|
216
|
+
return false;
|
|
217
217
|
}
|
|
218
218
|
const priority = options.priority === 'high' ? 'high' : 'normal';
|
|
219
219
|
const batch: QueuedIngestBatch = {
|
|
@@ -246,6 +246,7 @@ export const enqueueIngestEntries = (
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
scheduleDrain(shouldDeferDrain?.() ? deferDrainMs : 0);
|
|
249
|
+
return ingestQueue.includes(batch);
|
|
249
250
|
};
|
|
250
251
|
|
|
251
252
|
export const flushIngestQueue = async (): Promise<void> => {
|
|
@@ -37,6 +37,10 @@ function main() {
|
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
assert(batches.length > 1, `expected more than one batch, got ${batches.length}`);
|
|
40
|
+
assert(
|
|
41
|
+
batches.length <= 8,
|
|
42
|
+
`expected trace transport to cap batches per request, got ${batches.length}`,
|
|
43
|
+
);
|
|
40
44
|
|
|
41
45
|
batches.forEach((batch, index) => {
|
|
42
46
|
const size = __reproTestHooks.estimateTraceBatchSerializedBytesForTest(
|
|
@@ -51,6 +55,18 @@ function main() {
|
|
|
51
55
|
);
|
|
52
56
|
});
|
|
53
57
|
|
|
58
|
+
const manyEvents = Array.from({ length: 1500 }, (_, index) => makeEvent(index, 'tiny'));
|
|
59
|
+
const cappedBatches = __reproTestHooks.chunkTraceEventsForTransportForTest(
|
|
60
|
+
manyEvents,
|
|
61
|
+
'RID_test_trace_event_cap',
|
|
62
|
+
'A_test_trace_event_cap',
|
|
63
|
+
);
|
|
64
|
+
const cappedEventCount = cappedBatches.reduce((sum, batch) => sum + batch.length, 0);
|
|
65
|
+
assert(
|
|
66
|
+
cappedEventCount <= 1000,
|
|
67
|
+
`expected trace transport to cap events per request, got ${cappedEventCount}`,
|
|
68
|
+
);
|
|
69
|
+
|
|
54
70
|
// eslint-disable-next-line no-console
|
|
55
71
|
console.log('trace batch size chunking OK');
|
|
56
72
|
}
|