PostHog / posthog-js-lite

Reimplementation of posthog-js to be as light and modular as possible.
https://posthog.com/docs/libraries
MIT License
69 stars 36 forks source link

feat: Improved queue flushing #177

Closed marandaneto closed 8 months ago

marandaneto commented 9 months ago

Problem

Fixes https://github.com/PostHog/posthog-js-lite/issues/176

Changes

Release info Sub-libraries affected

Bump level

Libraries affected

Changelog notes

github-actions[bot] commented 9 months ago

Size Change: +534 B (+1%)

Total Size: 72.3 kB

Filename Size Change
posthog-node/lib/index.cjs.js 19.6 kB +120 B (+1%)
posthog-node/lib/index.esm.js 19.6 kB +122 B (+1%)
posthog-web/lib/index.cjs.js 16.6 kB +146 B (+1%)
posthog-web/lib/index.esm.js 16.5 kB +146 B (+1%)

compressed-size-action

marandaneto commented 9 months ago

What happens if you flush twice in a row? Feels like we are missing something to block multiple flushes (or at least handle them correctly).

Similarly we might want to check that the shutdown logic would still work if we block multiple flushes at once

True, I assumed the method was sync but there's a then call at the end, and that would lead to race conditions and messing up the queue, good catch. Only 1 flush per time is allowed to avoid such races using the state flag isFlushing. The shutdown logic should be fine because it awaits all pending promises anyway and call flush again. WDYT? can write tests if you think this is enough now.

marandaneto commented 9 months ago

What happens if you flush twice in a row? Feels like we are missing something to block multiple flushes (or at least handle them correctly).

Similarly we might want to check that the shutdown logic would still work if we block multiple flushes at once

The flush method only calls removeItemsFromQueue and it's a sync method and JS is single-threaded. In React Native land we could use useState to be sure and avoid race conditions, but this method isn't async so I guess this is fine?

Happy to jump in and help here as this is a bit more JS-y than mobile-y

yep, made a new comment here, but happy to hear your thoughts since this has node/web impact.

promise-hold approach would work but I wonder if it's really necessary, I'd say it's only fully necessary if we want close to real-time events, where any call to flush or flushAsync cannot be missed and cannot wait the next timer cycle. The only downside is the shutdownAsync, but as mentioned in my comment, even with the current implementation, the Queue isn't fully flushed.