Skip to content

Conversation

mydea
Copy link
Member

@mydea mydea commented Sep 25, 2025

Extracted this out of #17782, this improved our promise buffer class a bit:

  1. Remove the code path without a limit, as we never use this (there is a default limit used). There is also really no reason to use this without a limit, the limit is the whole purpose of this class.
  2. Use a Set instead of an array for the internal buffer handling, this should slightly streamline stuff.
  3. For drain, we can simplify the implementation without a timeout drastically. We can use Promise.race() to handle this more gracefully, which should be supported everywhere.
  4. Some slight refactorings, actually improving timing semantics slightly.

@mydea mydea self-assigned this Sep 25, 2025
* @returns Removed promise.
*/
function remove(task: PromiseLike<T>): PromiseLike<T | void> {
return buffer.splice(buffer.indexOf(task), 1)[0] || Promise.resolve(undefined);
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think it is necessary to wait on anything here, we can just remove this from the buffer directly and be done with it - we already execute the function anyhow without this.

@mydea mydea force-pushed the fn/better-promise-buffer branch from bed62c2 to f1aedb6 Compare September 25, 2025 14:33
expect(buffer.add(producer1)).toEqual(task1);
void expect(buffer.add(producer2)).rejects.toThrowError();
// This is immediately executed and removed again from the buffer
expect(buffer.$.length).toEqual(0);
Copy link
Member Author

Choose a reason for hiding this comment

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

You can see the slight change of timing semantics here, in that the promise is immediately added & removed from the buffer if it is a sync promise. This makes sense IMHO and is possibly a tiny micro-optimization, I suppose.

Copy link
Contributor

github-actions bot commented Sep 25, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.23 kB -0.1% -22 B 🔽
@sentry/browser - with treeshaking flags 22.75 kB -0.13% -28 B 🔽
@sentry/browser (incl. Tracing) 40.42 kB -0.04% -16 B 🔽
@sentry/browser (incl. Tracing, Replay) 78.8 kB -0.03% -18 B 🔽
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 68.45 kB -0.05% -34 B 🔽
@sentry/browser (incl. Tracing, Replay with Canvas) 83.47 kB -0.03% -17 B 🔽
@sentry/browser (incl. Tracing, Replay, Feedback) 95.67 kB -0.02% -17 B 🔽
@sentry/browser (incl. Feedback) 40.95 kB -0.07% -26 B 🔽
@sentry/browser (incl. sendFeedback) 28.89 kB -0.1% -27 B 🔽
@sentry/browser (incl. FeedbackAsync) 33.82 kB -0.07% -23 B 🔽
@sentry/react 25.96 kB -0.08% -19 B 🔽
@sentry/react (incl. Tracing) 42.39 kB -0.05% -20 B 🔽
@sentry/vue 28.75 kB -0.13% -35 B 🔽
@sentry/vue (incl. Tracing) 42.23 kB -0.03% -11 B 🔽
@sentry/svelte 24.26 kB -0.12% -27 B 🔽
CDN Bundle 25.75 kB -0.09% -23 B 🔽
CDN Bundle (incl. Tracing) 40.31 kB -0.07% -27 B 🔽
CDN Bundle (incl. Tracing, Replay) 76.55 kB -0.03% -20 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) 82.06 kB -0.01% -6 B 🔽
CDN Bundle - uncompressed 75.3 kB -0.1% -70 B 🔽
CDN Bundle (incl. Tracing) - uncompressed 119.32 kB -0.06% -70 B 🔽
CDN Bundle (incl. Tracing, Replay) - uncompressed 234.48 kB -0.03% -70 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 247.24 kB -0.03% -70 B 🔽
@sentry/nextjs (client) 44.4 kB -0.07% -27 B 🔽
@sentry/sveltekit (client) 40.84 kB -0.05% -18 B 🔽
@sentry/node-core 50 kB -0.04% -20 B 🔽
@sentry/node 153.04 kB -0.02% -22 B 🔽
@sentry/node - without tracing 91.92 kB -0.03% -19 B 🔽
@sentry/aws-serverless 105.37 kB -0.02% -21 B 🔽

View base workflow run

Copy link
Contributor

github-actions bot commented Sep 25, 2025

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 9,216 - 9,395 -2%
GET With Sentry 1,376 15% 1,361 +1%
GET With Sentry (error only) 6,018 65% 6,068 -1%
POST Baseline 1,208 - 1,198 +1%
POST With Sentry 528 44% 520 +2%
POST With Sentry (error only) 1,057 88% 1,063 -1%
MYSQL Baseline 3,321 - 3,309 +0%
MYSQL With Sentry 476 14% 422 +13%
MYSQL With Sentry (error only) 2,705 81% 2,689 +1%

View base workflow run

@mydea mydea force-pushed the fn/better-promise-buffer branch from d737fed to d8d6dec Compare September 26, 2025 07:05
@mydea mydea marked this pull request as ready for review September 26, 2025 07:06
cursor[bot]

This comment was marked as outdated.

@mydea mydea force-pushed the fn/better-promise-buffer branch from d8d6dec to be6b08e Compare September 26, 2025 10:06
Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

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

Nice! TIL about Promise.race

Comment on lines +92 to +95
expect(buffer.add(producer)).toEqual(promise);
expect(buffer.add(producer2)).toEqual(promise);

expect(buffer.$.length).toEqual(1);
Copy link
Member

Choose a reason for hiding this comment

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

Do you think this is a case we could even run into in real life? (don't think this is wrong per sé just a bit interesting because we handle this differently e.g. in client hook subscribers)

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah not quite sure, I kept this behavior (this was already that way) the same as it was before - honestly I think it is not really "desired"/"needed" but just a way to make sure we can easily remove the promises from the buffer again 😅

@mydea mydea merged commit 0e19673 into develop Sep 26, 2025
189 checks passed
@mydea mydea deleted the fn/better-promise-buffer branch September 26, 2025 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants