Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow configuring request queue interval #1708

Merged
merged 1 commit into from
Jan 31, 2025

Conversation

pauldambra
Copy link
Member

the request queue has a fixed interval where it sends events, this allows us to batch events to reduce load on ingestion and reduce network calls on client devices

but for customers where they may have short page visits or automated page redirects this means relying on the unload mechanism which browsers don't guarantee

let's allow configuring that interval between 250 and 5000ms

Copy link

vercel bot commented Jan 31, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
posthog-js ✅ Ready (Inspect) Visit Preview Jan 31, 2025 10:35am

@pauldambra pauldambra requested a review from a team January 31, 2025 10:33
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

This PR adds configurable request queue intervals to the PostHog JS library, allowing more frequent event batching for scenarios with short page visits or automated redirects.

  • Added request_queue_config.flush_interval_ms in /src/types.ts to configure batch intervals between 250-5000ms (default 3000ms)
  • Implemented interval clamping with validation in /src/request-queue.ts using clampToRange utility
  • Renamed request types for clarity (e.g. RequestOptions to RequestWithOptions) across multiple files for consistency
  • Added comprehensive test coverage in /src/__tests__/request-queue.test.ts for interval bounds and configuration integration
  • Maintained backward compatibility while adding new configuration options for request batching

7 file(s) reviewed, 2 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines +53 to 105
it('handles poll after enqueueing requests', () => {
queue.enqueue({
data: { event: 'foo', timestamp: EPOCH - 3000 },
transport: 'XHR',
url: '/e',
})
queue.enqueue({
data: { event: '$identify', timestamp: EPOCH - 2000 },
url: '/identify',
})
queue.enqueue({
data: { event: 'bar', timestamp: EPOCH - 1000 },
url: '/e',
})
queue.enqueue({
data: { event: 'zeta', timestamp: EPOCH },
url: '/e',
batchKey: 'sessionRecording',
})

queue.unload()
queue.enable()

expect(sendRequest).toHaveBeenCalledTimes(3)
expect(sendRequest).toHaveBeenCalledTimes(0)

expect(sendRequest).toHaveBeenNthCalledWith(1, {
data: [
{ event: 'foo', timestamp: 1610000000 },
{ event: 'bar', timestamp: 1630000000 },
],
transport: 'sendBeacon',
url: '/e',
jest.runOnlyPendingTimers()

expect(sendRequest).toHaveBeenCalledTimes(3)
expect(jest.mocked(sendRequest).mock.calls).toEqual([
[
{
url: '/e',
data: [
{ event: 'foo', offset: 3000 },
{ event: 'bar', offset: 1000 },
],
transport: 'XHR',
},
],
[
{
url: '/identify',
data: [{ event: '$identify', offset: 2000 }],
},
],
[
{
url: '/e',
data: [{ event: 'zeta', offset: 0 }],
batchKey: 'sessionRecording',
},
],
])
})
Copy link
Contributor

Choose a reason for hiding this comment

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

style: This test now lives under 'with default config' but actually tests core queue functionality. Consider moving to a separate describe block for clarity.

Comment on lines +152 to +153
{ event: 'foo', timestamp: 1610000000 },
{ event: 'bar', timestamp: 1630000000 },
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Inconsistent timestamp formatting - some use underscores (1_610_000_000) while these don't. Should standardize for readability.

Copy link

Size Change: +1.53 kB (+0.05%)

Total Size: 3.3 MB

Filename Size Change
dist/array.full.es5.js 268 kB +150 B (+0.06%)
dist/array.full.js 370 kB +154 B (+0.04%)
dist/array.full.no-external.js 369 kB +154 B (+0.04%)
dist/array.js 183 kB +153 B (+0.08%)
dist/array.no-external.js 181 kB +154 B (+0.08%)
dist/main.js 184 kB +153 B (+0.08%)
dist/module.full.js 371 kB +154 B (+0.04%)
dist/module.full.no-external.js 369 kB +154 B (+0.04%)
dist/module.js 183 kB +153 B (+0.08%)
dist/module.no-external.js 181 kB +154 B (+0.08%)
ℹ️ View Unchanged
Filename Size
dist/all-external-dependencies.js 215 kB
dist/customizations.full.js 13.8 kB
dist/dead-clicks-autocapture.js 14.5 kB
dist/exception-autocapture.js 9.48 kB
dist/external-scripts-loader.js 2.64 kB
dist/recorder-v2.js 115 kB
dist/recorder.js 115 kB
dist/surveys-preview.js 69.4 kB
dist/surveys.js 72.4 kB
dist/tracing-headers.js 1.76 kB
dist/web-vitals.js 10.4 kB

compressed-size-action

Copy link
Collaborator

@benjackwhite benjackwhite left a comment

Choose a reason for hiding this comment

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

No problem with the implementation, just a comment about the source problem

import { each } from './utils'

import { isArray, isUndefined } from './utils/type-utils'
import { clampToRange } from './utils/number-utils'

export const DEFAULT_FLUSH_INTERVAL_MS = 3000
Copy link
Collaborator

Choose a reason for hiding this comment

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

Feels like a solution that doesn't actually relate to the problem...

The problem sounds more to me like customers want a way to flush data and wait for the response before unloading?

Copy link
Member Author

Choose a reason for hiding this comment

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

In the specific case they have an auto-refresh after 2 seconds, so they wouldn't want to delay too long

it's also a much bigger change to wait on refreshes...

what I'd love to do instead is have this queue store to local storage as well as memory, and then this all becomes much safer

(so, yep, this is for sure a workaround I can give this customer quickly, much more than something I'd expect many people to set)

@pauldambra pauldambra added the bump minor Bump minor version when this PR gets merged label Jan 31, 2025
@pauldambra pauldambra merged commit 4dc0bc1 into main Jan 31, 2025
32 checks passed
@pauldambra pauldambra deleted the feat/allow-configuring-request-timeout branch January 31, 2025 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bump minor Bump minor version when this PR gets merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants