Skip to content

Commit

Permalink
fix: limit logged args per error
Browse files Browse the repository at this point in the history
  • Loading branch information
erights authored and michaelfig committed Apr 8, 2023
1 parent fc74466 commit 88f4662
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 11 deletions.
38 changes: 27 additions & 11 deletions packages/ses/src/error/note-log-args.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,18 @@ const spliceOut = cell => {
*
* TODO: Make parameterized `Key` and `Value` template types
*
* @param {number} budget
* @param {number} keysBudget
* @returns {WeakMap<object,any>}
*/
export const makeLRUCacheMap = budget => {
if (!isSafeInteger(budget) || budget < 0) {
throw new TypeError('budget must be a safe non-negative integer number');
export const makeLRUCacheMap = keysBudget => {
if (!isSafeInteger(keysBudget) || keysBudget < 0) {
throw new TypeError(
'keysBudget must be a safe non-negative integer number',
);
}
/** @type {Map<object, DoublyLinkedCell>} */
const map = new Map();
let size = 0; // `size` must remain <= `budget`
let size = 0; // `size` must remain <= `keysBudget`
// As a sigil, `head` uniquely is not in the `map`.
const head = makeSelfCell(undefined, undefined);

Expand Down Expand Up @@ -131,12 +133,12 @@ export const makeLRUCacheMap = budget => {
freeze(get);

const set = (key, value) => {
if (budget >= 1) {
if (keysBudget >= 1) {
let cell = touchCell(key);
if (cell !== undefined) {
cell.value = value;
} else {
if (size >= budget) {
if (size >= keysBudget) {
const condemned = head.prev;
spliceOut(condemned); // Drop least recently used
map.delete(condemned.key);
Expand Down Expand Up @@ -176,12 +178,23 @@ export const makeLRUCacheMap = budget => {
};
freeze(makeLRUCacheMap);

const defaultLogArgsBudget = 1000;
const defaultLoggedErrorsBudget = 1000;
const defaultArgsPerErrorBudget = 100;

/**
* @param {number} [budget]
* @param {number} [errorsBudget]
* @param {number} [argsPerErrorBudget]
*/
export const makeNoteLogArgsArrayKit = (budget = defaultLogArgsBudget) => {
export const makeNoteLogArgsArrayKit = (
errorsBudget = defaultLoggedErrorsBudget,
argsPerErrorBudget = defaultArgsPerErrorBudget,
) => {
if (!isSafeInteger(argsPerErrorBudget) || argsPerErrorBudget < 1) {
throw new TypeError(
'argsPerErrorBudget must be a safe positive integer number',
);
}

/**
* @type {WeakMap<Error, LogArgs[]>}
*
Expand All @@ -192,7 +205,7 @@ export const makeNoteLogArgsArrayKit = (budget = defaultLogArgsBudget) => {
* An augmented console, like the causal console of `console.js`, could
* then retrieve the graph of such annotations.
*/
const noteLogArgsArrayMap = makeLRUCacheMap(budget);
const noteLogArgsArrayMap = makeLRUCacheMap(errorsBudget);

/**
* @param {Error} error
Expand All @@ -201,6 +214,9 @@ export const makeNoteLogArgsArrayKit = (budget = defaultLogArgsBudget) => {
const addLogArgs = (error, logArgs) => {
const logArgsArray = noteLogArgsArrayMap.get(error);
if (logArgsArray !== undefined) {
if (logArgsArray.length >= argsPerErrorBudget) {
logArgsArray.shift();
}
logArgsArray.push(logArgs);
} else {
noteLogArgsArrayMap.set(error, [logArgs]);
Expand Down
22 changes: 22 additions & 0 deletions packages/ses/test/error/test-lru-cache-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import test from 'ava';

import { makeLRUCacheMap } from '../../src/error/note-log-args.js';

test('lru cache map basic', t => {
const lruMap = makeLRUCacheMap(2);
const key1 = {};
const key2 = {};
const key3 = {};
t.is(lruMap.has(key1), false);

lruMap.set(key1, 'x');
lruMap.set(key2, 'y');
t.is(lruMap.has(key2), true);
t.is(lruMap.has(key1), true);
t.is(lruMap.has(key3), false);

lruMap.set(key3, 'z');
t.is(lruMap.has(key1), true);
t.is(lruMap.has(key2), false);
t.is(lruMap.has(key3), true);
});
24 changes: 24 additions & 0 deletions packages/ses/test/error/test-note-log-args.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import test from 'ava';

import { makeNoteLogArgsArrayKit } from '../../src/error/note-log-args.js';

test('note log args array kit basic', t => {
const { addLogArgs, takeLogArgsArray } = makeNoteLogArgsArrayKit(3, 2);
const e1 = Error('e1');
const e2 = Error('e2');
const e3 = Error('e3');
const e4 = Error('e4');

addLogArgs(e1, ['a']);
addLogArgs(e3, ['b']);
addLogArgs(e2, ['c']);
addLogArgs(e4, ['d']); // drops e1
addLogArgs(e1, ['e']); // new e1 entry, drops e3
addLogArgs(e2, ['f']);
addLogArgs(e2, ['g']); // drops e2,c
addLogArgs(e2, ['h']); // drops e2,f
t.deepEqual(takeLogArgsArray(e1), [['e']]);
t.deepEqual(takeLogArgsArray(e2), [['g'], ['h']]);
t.deepEqual(takeLogArgsArray(e3), undefined);
t.deepEqual(takeLogArgsArray(e4), [['d']]);
});

0 comments on commit 88f4662

Please sign in to comment.