Skip to content

Commit e00a469

Browse files
fix: Harvest generic events when max size is reached (#1250)
1 parent b1e4113 commit e00a469

File tree

4 files changed

+28
-40
lines changed

4 files changed

+28
-40
lines changed

.github/actions/build-ab/templates/released.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ window.NREUM={
2525
enabled: true
2626
},
2727
performance: {
28-
capture_marks: true,
28+
capture_marks: false,
2929
capture_measures: true
3030
},
3131
proxy: {}

src/features/generic_events/aggregate/index.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { now } from '../../../common/timing/now'
1313
import { registerHandler } from '../../../common/event-emitter/register-handler'
1414
import { SUPPORTABILITY_METRIC_CHANNEL } from '../../metrics/constants'
1515
import { applyFnToProps } from '../../../common/util/traverse'
16-
import { IDEAL_PAYLOAD_SIZE } from '../../../common/constants/agent-constants'
1716
import { FEATURE_TO_ENDPOINT } from '../../../loaders/features/features'
1817
import { UserActionsAggregator } from './user-actions/user-actions-aggregator'
1918
import { isIFrameWindow } from '../../../common/dom/iframe'
@@ -177,9 +176,16 @@ export class Aggregate extends AggregateBase {
177176
...obj
178177
}
179178

180-
this.events.add(eventAttributes)
181-
182-
this.checkEventLimits()
179+
const addedEvent = this.events.add(eventAttributes)
180+
if (!addedEvent && !this.events.isEmpty()) {
181+
/** could not add the event because it pushed the buffer over the limit
182+
* so we harvest early, and try to add it again now that the buffer is cleared
183+
* if it fails again, we do nothing
184+
*/
185+
this.ee.emit(SUPPORTABILITY_METRIC_CHANNEL, ['GenericEvents/Harvest/Max/Seen'])
186+
this.harvestScheduler.runHarvest()
187+
this.events.add(eventAttributes)
188+
}
183189
}
184190

185191
serializer (eventBuffer) {
@@ -189,12 +195,4 @@ export class Aggregate extends AggregateBase {
189195
queryStringsBuilder () {
190196
return { ua: this.agentRef.info.userAttributes, at: this.agentRef.info.atts }
191197
}
192-
193-
checkEventLimits () {
194-
// check if we've reached any harvest limits...
195-
if (this.events.byteSize() > IDEAL_PAYLOAD_SIZE) {
196-
this.ee.emit(SUPPORTABILITY_METRIC_CHANNEL, ['GenericEvents/Harvest/Max/Seen'])
197-
this.harvestScheduler.runHarvest()
198-
}
199-
}
200198
}

tests/components/generic_events/aggregate/index.test.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,30 @@ test('should warn if invalid event is provide', async () => {
6161
expect(console.debug).toHaveBeenCalledWith('New Relic Warning: https://github.com/newrelic/newrelic-browser-agent/blob/main/docs/warning-codes.md#44', undefined)
6262
})
6363

64-
test('should only buffer 64kb of events at a time', async () => {
64+
test('should harvest early if will exceed 1mb', async () => {
6565
genericEventsAggregate.ee.emit('rumresp', [{ ins: 1 }])
6666

6767
await new Promise(process.nextTick)
6868

6969
genericEventsAggregate.harvestScheduler.runHarvest = jest.fn()
70-
genericEventsAggregate.addEvent({ name: 'test', eventType: 'x'.repeat(63000) })
70+
genericEventsAggregate.addEvent({ name: 'test', eventType: 'x'.repeat(900000) })
7171

7272
expect(genericEventsAggregate.harvestScheduler.runHarvest).not.toHaveBeenCalled()
73-
genericEventsAggregate.addEvent({ name: 1000, eventType: 'x'.repeat(1000) })
73+
genericEventsAggregate.addEvent({ name: 1000, eventType: 'x'.repeat(100000) })
7474
expect(genericEventsAggregate.harvestScheduler.runHarvest).toHaveBeenCalled()
7575
})
7676

77+
test('should not harvest if single event will exceed 1mb', async () => {
78+
genericEventsAggregate.ee.emit('rumresp', [{ ins: 1 }])
79+
80+
await new Promise(process.nextTick)
81+
82+
genericEventsAggregate.harvestScheduler.runHarvest = jest.fn()
83+
genericEventsAggregate.addEvent({ name: 'test', eventType: 'x'.repeat(1000000) })
84+
85+
expect(genericEventsAggregate.harvestScheduler.runHarvest).not.toHaveBeenCalled()
86+
})
87+
7788
describe('sub-features', () => {
7889
beforeEach(async () => {
7990
genericEventsAggregate.ee.emit('rumresp', [{ ins: 1 }])

tests/specs/ins/harvesting.e2e.js

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('ins harvesting', () => {
8181
pageUrl: expect.any(String),
8282
timestamp: expect.any(Number)
8383
})
84-
expect(clickUAs[1].actionDuration).toBeGreaterThan(0)
84+
expect(clickUAs[1].actionDuration).toBeGreaterThanOrEqual(0)
8585
expect(clickUAs[1].actionMs).toEqual(expect.stringMatching(/^\[\d+(,\d+){4}\]$/))
8686
})
8787

@@ -167,35 +167,14 @@ describe('ins harvesting', () => {
167167
insightsCapture.waitForResult({ timeout: 10000 }),
168168
browser.execute(function () {
169169
let i = 0
170-
while (i++ < 1010) {
170+
while (i++ < 10000) {
171171
newrelic.addPageAction('foobar')
172172
}
173173
})
174174
])
175175
expect(insightsResult.length).toBeTruthy()
176176
})
177177

178-
it('should harvest early when buffer gets too large (one big event)', async () => {
179-
const testUrl = await browser.testHandle.assetURL('instrumented.html', { init: { generic_events: { harvestTimeSeconds: 30 } } })
180-
await browser.url(testUrl)
181-
.then(() => browser.waitForAgentLoad())
182-
183-
const [insightsResult] = await Promise.all([
184-
insightsCapture.waitForResult({ timeout: 10000 }),
185-
browser.execute(function () {
186-
newrelic.addPageAction('foobar', createLargeObject())
187-
function createLargeObject () {
188-
let i = 0; let obj = {}
189-
while (i++ < 64000) {
190-
obj[i] = 'x'
191-
}
192-
return obj
193-
}
194-
})
195-
])
196-
expect(insightsResult.length).toBeTruthy()
197-
})
198-
199178
it('should not harvest if too large', async () => {
200179
const testUrl = await browser.testHandle.assetURL('instrumented.html')
201180
await browser.url(testUrl)
@@ -207,7 +186,7 @@ describe('ins harvesting', () => {
207186
newrelic.addPageAction('foobar', createLargeObject())
208187
function createLargeObject () {
209188
let i = 0; let obj = {}
210-
while (i++ < 100000) {
189+
while (i++ < 1000000) {
211190
obj[i] = Math.random()
212191
}
213192
return obj

0 commit comments

Comments
 (0)