Skip to content

Commit 173a123

Browse files
authored
fix: fixed retrying logic for invalid sdk key (#978)
1 parent 5561d8d commit 173a123

File tree

2 files changed

+68
-9
lines changed

2 files changed

+68
-9
lines changed

sdk/nodejs/__tests__/eventQueue.test.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { DVCPopulatedUserFromDevCycleUser } from '../src/models/populatedUserHel
1313
import { publishEvents } from '../src/request'
1414

1515
import testData from '@devcycle/bucketing-test-data/json-data/testData.json'
16+
import { ResponseError } from '@devcycle/server-request'
1617
const { config } = testData
1718

1819
const publishEvents_mock = mocked(publishEvents)
@@ -231,7 +232,6 @@ describe('EventQueue Unit Tests', () => {
231232

232233
const promise1 = eventQueue.flushEvents()
233234
const promise2 = eventQueue.flushEvents()
234-
eventQueue.cleanup()
235235

236236
await Promise.all([promise1, promise2])
237237
expect(publishEvents_mock).toHaveBeenCalledTimes(1)
@@ -327,6 +327,7 @@ describe('EventQueue Unit Tests', () => {
327327
],
328328
'localhost:3000/client/1',
329329
)
330+
eventQueue.cleanup()
330331
})
331332

332333
it(
@@ -816,6 +817,31 @@ describe('EventQueue Unit Tests', () => {
816817
},
817818
)
818819

820+
it('should close the event queue if the events api response is 401', async () => {
821+
const eventQueue = initEventQueue('sdkKey', 'uuid')
822+
const error = new ResponseError('401 error')
823+
error.status = 401
824+
publishEvents_mock.mockRejectedValueOnce(error)
825+
eventQueue.queueEvent(
826+
DVCPopulatedUserFromDevCycleUser({ user_id: 'user1' }),
827+
{ type: 'test_event' },
828+
)
829+
await eventQueue.flushEvents()
830+
831+
expect(eventQueue.disabledEventFlush).toBe(true)
832+
833+
eventQueue.queueEvent(
834+
DVCPopulatedUserFromDevCycleUser({ user_id: 'user1' }),
835+
{ type: 'test_event' },
836+
)
837+
eventQueue.queueAggregateEvent(
838+
DVCPopulatedUserFromDevCycleUser({ user_id: 'user1' }),
839+
{ type: EventTypes.aggVariableEvaluated, target: 'key' },
840+
bucketedUserConfig,
841+
)
842+
await eventQueue.flushEvents()
843+
})
844+
819845
describe('Max queue size tests', () => {
820846
it(
821847
'should not queue user event if user' +

sdk/nodejs/src/eventQueue.ts

+41-8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export class EventQueue {
4949
eventFlushIntervalMS: number
5050
flushEventQueueSize: number
5151
maxEventQueueSize: number
52+
disabledEventFlush: boolean
5253
private flushInterval: NodeJS.Timer
5354
private flushInProgress = false
5455
private flushCallbacks: Array<(arg: unknown) => void> = []
@@ -63,6 +64,8 @@ export class EventQueue {
6364
this.reporter = options.reporter
6465
this.eventsAPIURI = options.eventsAPIURI
6566
this.eventFlushIntervalMS = options?.eventFlushIntervalMS || 10 * 1000
67+
this.disabledEventFlush = false
68+
6669
if (this.eventFlushIntervalMS < 500) {
6770
throw new Error(
6871
`eventFlushIntervalMS: ${this.eventFlushIntervalMS} must be larger than 500ms`,
@@ -121,6 +124,7 @@ export class EventQueue {
121124

122125
cleanup(): void {
123126
clearInterval(this.flushInterval)
127+
this.disabledEventFlush = true
124128
}
125129

126130
private async _flushEvents() {
@@ -219,12 +223,25 @@ export class EventQueue {
219223
this.logger.debug(
220224
`DevCycle Error Flushing Events response message: ${ex.message}`,
221225
)
222-
this.bucketing.onPayloadFailure(
223-
this.sdkKey,
224-
flushPayload.payloadId,
225-
true,
226-
)
227-
results.retries++
226+
if ('status' in ex && ex.status === 401) {
227+
this.logger.debug(
228+
`SDK key is invalid, closing event flushing interval`,
229+
)
230+
this.bucketing.onPayloadFailure(
231+
this.sdkKey,
232+
flushPayload.payloadId,
233+
false,
234+
)
235+
results.failures++
236+
this.cleanup()
237+
} else {
238+
this.bucketing.onPayloadFailure(
239+
this.sdkKey,
240+
flushPayload.payloadId,
241+
true,
242+
)
243+
results.retries++
244+
}
228245
}
229246
}),
230247
)
@@ -276,9 +293,19 @@ export class EventQueue {
276293
* Queue DVCAPIEvent for publishing to DevCycle Events API.
277294
*/
278295
queueEvent(user: DVCPopulatedUser, event: DevCycleEvent): void {
296+
if (this.disabledEventFlush) {
297+
this.logger.warn(
298+
`Event flushing is disabled, dropping event: ${
299+
event.type
300+
}, event queue size: ${this.bucketing.eventQueueSize(
301+
this.sdkKey,
302+
)}`,
303+
)
304+
return
305+
}
279306
if (this.checkEventQueueSize()) {
280307
this.logger.warn(
281-
`Max event queue size reached, dropping event: ${event}`,
308+
`Max event queue size reached, dropping event: ${event.type}`,
282309
)
283310
return
284311
}
@@ -299,9 +326,15 @@ export class EventQueue {
299326
event: DevCycleEvent,
300327
bucketedConfig?: BucketedUserConfig,
301328
): void {
329+
if (this.disabledEventFlush) {
330+
this.logger.warn(
331+
`Event flushing is disabled, dropping aggregate event: ${event.type}`,
332+
)
333+
return
334+
}
302335
if (this.checkEventQueueSize()) {
303336
this.logger.warn(
304-
`Max event queue size reached, dropping aggregate event: ${event}`,
337+
`Max event queue size reached, dropping aggregate event: ${event.type}`,
305338
)
306339
return
307340
}

0 commit comments

Comments
 (0)