-
Notifications
You must be signed in to change notification settings - Fork 236
fix avoids a possible 'RangeError: Maximum call stack size exceeded' in maybeTime(...) #2939
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
Conversation
…in maybeTime(...) This avoids a possible 'RangeError: Maximum call stack size exceeded' as described in #2929. The case the user hit is in `maybeTime(...)` used in Span timer handling by dropping the recursion. A `Timer` instance's `_timer` is always the same object as its parent's `_timer` if it has a parent, so there is no need to walk the chain. Refs: #2929
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving, but just to say this out loud, that approval hinges on this being true
A Timer instance's _timer is always the same object as its parent's _timer if it has a parent
I only dug into this shallowly, but looking at the place a span-or-transaction's Timer
object gets instantiated
https://github.com/elastic/apm-agent-nodejs/blob/main/lib/instrumentation/generic-span.js#L25
this._timer = new Timer(opts.timer, opts.startTime)
The timer passed to Timer
's constructor is an object that could be set by a user passing in options to startSpan
or startTransaction
, which means making assumptions about its structure is trusting that end users aren't getting too wild with what they're doing.
This isn't a documented part of the user facing API so not a blocker, but if we start getting reports of weird timings from our most power of power users we'll want to remember this change has been made.
this._parent = timer | ||
this._timer = timer ? timer._timer : microtime() | ||
this.start = maybeTime(this, startTime) // microsecond integer | ||
constructor (parentTimer, startTime) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only seeing the (more accurate) parameter name change and comment change here -- no functional changes.
@astorm Good point, thanks. What do you think about adding a warning if a user passing in
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The log makes sense 👍 approving.
#2990 added to drop the option in a future major rev. |
…in maybeTime(...) (elastic#2939) This avoids a possible 'RangeError: Maximum call stack size exceeded' as described in elastic#2929. The case the user hit is in `maybeTime(...)` used in Span timer handling by dropping the recursion. A `Timer` instance's `_timer` is always(*) the same object as its parent's `_timer` if it has a parent, so there is no need to walk the chain. (*): Assuming the internal `timer` option to Span/Transaction creation isn't manually used. This change adds a deprecation warning if that is the case. Refs: elastic#2929
This avoids a possible 'RangeError: Maximum call stack size exceeded' as
described in #2929.
The case the user hit is in
maybeTime(...)
used in Span timer handling.Fixed by dropping the recursion. A
Timer
instance's_timer
is always thesame object as its parent's
_timer
if it has a parent, so there is noneed to walk the chain.
Refs: #2929
See the discussion at #2929 for why this doesn't include tests. We don't have a perfect understanding of how this is happening so don't have a good test to add. If this passes the current breakdown metrics tests ("test/metrics/breakdown.test.js"), then I think this should be good as a workaround for the user's issue.