@bugsnag/core-performance
Version:
Core performance client
61 lines (59 loc) • 2.07 kB
JavaScript
const msInDay = 24 * 60 * 60000;
class InMemoryQueue {
constructor(delivery, retryQueueMaxSize) {
this.delivery = delivery;
this.retryQueueMaxSize = retryQueueMaxSize;
this.requestQueue = Promise.resolve();
this.payloads = [];
}
add(payload, time) {
this.payloads.push({ payload, time });
let spanCount = this.payloads.reduce((count, { payload }) => count + countSpansInPayload(payload), 0);
while (spanCount > this.retryQueueMaxSize) {
const payload = this.payloads.shift();
if (!payload) {
break;
}
spanCount -= countSpansInPayload(payload.payload);
}
}
async flush() {
if (this.payloads.length === 0)
return;
const payloads = this.payloads;
this.payloads = [];
this.requestQueue = this.requestQueue.then(async () => {
for (const { payload, time } of payloads) {
// discard payloads at least 24 hours old
if (Date.now() >= time + msInDay)
continue;
try {
const { state } = await this.delivery.send(payload);
switch (state) {
case 'success':
case 'failure-discard':
break;
case 'failure-retryable':
this.add(payload, time);
break;
default:
state;
}
}
catch (err) { }
}
});
await this.requestQueue;
}
}
function countSpansInPayload(payload) {
let count = 0;
for (let i = 0; i < payload.body.resourceSpans.length; ++i) {
const scopeSpans = payload.body.resourceSpans[i].scopeSpans;
for (let j = 0; j < scopeSpans.length; ++j) {
count += scopeSpans[j].spans.length;
}
}
return count;
}
export { InMemoryQueue };