Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nasty-sloths-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@segment/analytics-next': minor
---

Fix retry behavior
60 changes: 58 additions & 2 deletions packages/browser/src/plugins/segmentio/__tests__/retries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ describe('Segment.io retries 500s and 429', () => {
jest.restoreAllMocks()

options = { apiKey: 'foo' }
analytics = new Analytics({ writeKey: options.apiKey })
analytics = new Analytics(
{ writeKey: options.apiKey },
{ retryQueue: true }
)
segment = await segmentio(
analytics,
options,
Expand All @@ -36,7 +39,7 @@ describe('Segment.io retries 500s and 429', () => {
const ctx = await analytics.track('event')
jest.runAllTimers()

expect(ctx.attempts).toBeGreaterThanOrEqual(3) // Gets incremented after use
expect(ctx.attempts).toBeGreaterThanOrEqual(2) // Gets incremented after use
expect(fetch.mock.calls.length).toBeGreaterThanOrEqual(2)
expect(fetch.mock.lastCall[1].body).toContain('"retryCount":')
})
Expand Down Expand Up @@ -131,3 +134,56 @@ describe('Batches retry 500s and 429', () => {
expect(fetch.mock.lastCall[1].body).toContain('"retryCount":2')
})
})

describe('retryQueue', () => {
let options: SegmentioSettings
let analytics: Analytics
let segment: Plugin
beforeEach(async () => {
jest.useRealTimers()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally just just make this at afterEach -- and beforeEach can just have 'jest.useFakeTimers()`

jest.resetAllMocks()
jest.restoreAllMocks()

options = {
apiKey: 'foo',
}

fetch.mockReturnValue(createError({ status: 500 }))
})

it('Only attempts once if retryQueue is false', async () => {
jest.useFakeTimers({ advanceTimers: true })
analytics = new Analytics(
{ writeKey: options.apiKey },
{ retryQueue: false }
)
segment = await segmentio(
analytics,
options,
cdnSettingsMinimal.integrations
)
await analytics.register(segment, envEnrichment)

await analytics.track('foo')
jest.runAllTimers()
expect(fetch).toHaveBeenCalledTimes(1)
})

it('Attempts multiple times if retryQueue is true', async () => {
jest.useFakeTimers({ advanceTimers: true })
analytics = new Analytics(
{ writeKey: options.apiKey },
{ retryQueue: true }
)
segment = await segmentio(
analytics,
options,
cdnSettingsMinimal.integrations
)
await analytics.register(segment, envEnrichment)

await analytics.track('foo')
jest.runAllTimers()
expect(fetch.mock.calls.length).toBeGreaterThanOrEqual(2)
})
})
5 changes: 5 additions & 0 deletions packages/browser/src/plugins/segmentio/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ export function segmentio(
json = onAlias(analytics, json)
}

if (buffer.getAttempts(ctx) >= buffer.maxAttempts) {
inflightEvents.delete(ctx)
return ctx
}

return client
.dispatch(
`${remote}/${path}`,
Expand Down
Loading