diff --git a/workers/grouper/src/index.ts b/workers/grouper/src/index.ts index c8812392..c3a3f42b 100644 --- a/workers/grouper/src/index.ts +++ b/workers/grouper/src/index.ts @@ -6,7 +6,7 @@ import { Worker } from '../../../lib/worker'; import * as WorkerNames from '../../../lib/workerNames'; import * as pkg from '../package.json'; import type { GroupWorkerTask, RepetitionDelta } from '../types/group-worker-task'; -import type { EventAddons, EventDataAccepted, GroupedEventDBScheme } from '@hawk.so/types'; +import type { EventAddons, EventDataAccepted, GroupedEventDBScheme, BacktraceFrame, SourceCodeLine } from '@hawk.so/types'; import type { RepetitionDBScheme } from '../types/repetition'; import { DatabaseReadWriteError, DiffCalculationError, ValidationError } from '../../../lib/workerErrors'; import { decodeUnsafeFields, encodeUnsafeFields } from '../../../lib/utils/unsafeFields'; @@ -17,12 +17,18 @@ import RedisHelper from './redisHelper'; import levenshtein from 'js-levenshtein'; import { computeDelta } from './utils/repetitionDiff'; import TimeMs from '../../../lib/utils/time'; +import { rightTrim } from '../../../lib/utils/string'; /** * Error code of MongoDB key duplication error */ const DB_DUPLICATE_KEY_ERROR = '11000'; +/** + * Maximum length for backtrace code line or title + */ +const MAX_CODE_LINE_LENGTH = 140; + /** * Worker for handling Javascript events */ @@ -118,6 +124,11 @@ export default class GrouperWorker extends Worker { let incrementDailyAffectedUsers = false; + /** + * Trim source code lines to prevent memory leaks + */ + this.trimSourceCodeLines(task.event); + /** * Filter sensitive information */ @@ -223,6 +234,30 @@ export default class GrouperWorker extends Worker { } } + /** + * Trims source code lines in event's backtrace to prevent memory leaks + * + * @param event - event to process + */ + private trimSourceCodeLines(event: EventDataAccepted): void { + if (!event.backtrace) { + return; + } + + event.backtrace.forEach((frame: BacktraceFrame) => { + if (!frame.sourceCode) { + return; + } + + frame.sourceCode = frame.sourceCode.map((line: SourceCodeLine) => { + return { + line: line.line, + content: rightTrim(line.content, MAX_CODE_LINE_LENGTH), + }; + }); + }); + } + /** * Get unique hash based on event type and title * @@ -248,12 +283,18 @@ export default class GrouperWorker extends Worker { const lastUniqueEvents = await this.findLastEvents(projectId, eventsCountToCompare); + /** + * Trim titles to reduce CPU usage for Levenshtein comparison + */ + const trimmedEventTitle = rightTrim(event.title, MAX_CODE_LINE_LENGTH); + /** * First try to find by Levenshtein distance */ const similarByLevenshtein = lastUniqueEvents.filter(prevEvent => { - const distance = levenshtein(event.title, prevEvent.payload.title); - const threshold = event.title.length * diffTreshold; + const trimmedPrevTitle = rightTrim(prevEvent.payload.title, MAX_CODE_LINE_LENGTH); + const distance = levenshtein(trimmedEventTitle, trimmedPrevTitle); + const threshold = trimmedEventTitle.length * diffTreshold; return distance < threshold; }).pop(); diff --git a/workers/javascript/src/index.ts b/workers/javascript/src/index.ts index d1807d7e..92b3ee66 100644 --- a/workers/javascript/src/index.ts +++ b/workers/javascript/src/index.ts @@ -9,7 +9,6 @@ import * as pkg from '../package.json'; import { JavaScriptEventWorkerTask } from '../types/javascript-event-worker-task'; import HawkCatcher from '@hawk.so/nodejs'; import Crypto from '../../../lib/utils/crypto'; -import { rightTrim } from '../../../lib/utils/string'; import { BacktraceFrame, SourceCodeLine, SourceMapDataExtended } from '@hawk.so/types'; import { beautifyUserAgent } from './utils'; import { Collection } from 'mongodb'; @@ -228,7 +227,6 @@ export default class JavascriptEventWorker extends EventWorker { * Fixes bug: https://github.com/codex-team/hawk.workers/issues/121 */ if (originalLocation.source) { - console.log('original location source found'); /** * Get 5 lines above and 5 below */ @@ -402,7 +400,7 @@ export default class JavascriptEventWorker extends EventWorker { return focusedLines.map((line, idx) => { return { line: Math.max(original.line - margin + idx, 1), - content: rightTrim(line), + content: line, } as SourceCodeLine; }); }