Skip to content

Commit 37df4c9

Browse files
Check attempts before dispatching to segment (#1276)
1 parent aa86141 commit 37df4c9

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed

.changeset/nasty-sloths-rhyme.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@segment/analytics-next': minor
3+
---
4+
5+
Fix retry behavior

packages/browser/src/plugins/segmentio/__tests__/retries.test.ts

+59-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ describe('Segment.io retries 500s and 429', () => {
2121
jest.restoreAllMocks()
2222

2323
options = { apiKey: 'foo' }
24-
analytics = new Analytics({ writeKey: options.apiKey })
24+
analytics = new Analytics(
25+
{ writeKey: options.apiKey },
26+
{ retryQueue: true }
27+
)
2528
segment = await segmentio(
2629
analytics,
2730
options,
@@ -36,7 +39,7 @@ describe('Segment.io retries 500s and 429', () => {
3639
const ctx = await analytics.track('event')
3740
jest.runAllTimers()
3841

39-
expect(ctx.attempts).toBeGreaterThanOrEqual(3) // Gets incremented after use
42+
expect(ctx.attempts).toBeGreaterThanOrEqual(2) // Gets incremented after use
4043
expect(fetch.mock.calls.length).toBeGreaterThanOrEqual(2)
4144
expect(fetch.mock.lastCall[1].body).toContain('"retryCount":')
4245
})
@@ -131,3 +134,57 @@ describe('Batches retry 500s and 429', () => {
131134
expect(fetch.mock.lastCall[1].body).toContain('"retryCount":2')
132135
})
133136
})
137+
138+
describe('retryQueue', () => {
139+
let options: SegmentioSettings
140+
let analytics: Analytics
141+
let segment: Plugin
142+
beforeEach(async () => {
143+
jest.useFakeTimers({ advanceTimers: true })
144+
jest.resetAllMocks()
145+
jest.restoreAllMocks()
146+
147+
options = {
148+
apiKey: 'foo',
149+
}
150+
151+
fetch.mockReturnValue(createError({ status: 500 }))
152+
})
153+
afterEach(() => {
154+
jest.useRealTimers()
155+
})
156+
157+
it('Only attempts once if retryQueue is false', async () => {
158+
analytics = new Analytics(
159+
{ writeKey: options.apiKey },
160+
{ retryQueue: false }
161+
)
162+
segment = await segmentio(
163+
analytics,
164+
options,
165+
cdnSettingsMinimal.integrations
166+
)
167+
await analytics.register(segment, envEnrichment)
168+
169+
await analytics.track('foo')
170+
jest.runAllTimers()
171+
expect(fetch).toHaveBeenCalledTimes(1)
172+
})
173+
174+
it('Attempts multiple times if retryQueue is true', async () => {
175+
analytics = new Analytics(
176+
{ writeKey: options.apiKey },
177+
{ retryQueue: true }
178+
)
179+
segment = await segmentio(
180+
analytics,
181+
options,
182+
cdnSettingsMinimal.integrations
183+
)
184+
await analytics.register(segment, envEnrichment)
185+
186+
await analytics.track('foo')
187+
jest.runAllTimers()
188+
expect(fetch.mock.calls.length).toBeGreaterThanOrEqual(2)
189+
})
190+
})

packages/browser/src/plugins/segmentio/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ export function segmentio(
112112
json = onAlias(analytics, json)
113113
}
114114

115+
if (buffer.getAttempts(ctx) >= buffer.maxAttempts) {
116+
inflightEvents.delete(ctx)
117+
return ctx
118+
}
119+
115120
return client
116121
.dispatch(
117122
`${remote}/${path}`,

0 commit comments

Comments
 (0)