-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Scale histogram aggregation interval to avoid crashing browser #14157
Conversation
} | ||
}, | ||
|
||
{ | ||
name: 'max', |
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.
We should probably use a less generic param name, maybe combine min
/max
to autoBounds: { min/max }
?
Interval | ||
<kbn-info | ||
placement="right" | ||
info="Interval will be automatically scaled in the event that the provided internval creates more buckets than specified by Advanced Setting's 'histogram:maxBars'"> |
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.
typo - internval
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.
This change is going to make a lot of people happy, awesome!
I have mostly minor comments to improve understanding and navigability of the new methods. The onStart-hook makes a lot of sense, but I'd tighten the method signatures a little bit more explicitly.
I would also add a selenium test for this, create a bar chart or something with a very small interval. e.g. add a test-case here: https://github.com/thomasneirynck/kibana/blob/b278ad96a9c0d4e9e0fcf91efb878884d1401fff/test/functional/apps/visualize/_vertical_bar_chart.js#L112-L112
@@ -0,0 +1,19 @@ | |||
<div class="form-group"> | |||
<label for="visEditorInterval{{agg.id}}"> | |||
Interval |
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.
I'd rename now to "Minimum Interval"
// ensure interval does not create too many buckets and crash browser | ||
if (aggConfig.autoBounds) { | ||
const range = aggConfig.autoBounds.max - aggConfig.autoBounds.min; | ||
const bars = range / interval; |
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.
I'd check if interval
is 0. Through the magic of JS bars
is either going to be NaN or Infinity depending on the nominator, so I'd just avoid this altogether.
An option too is modify the number_interval
, to disallow 0
input for the agg.params.interval
value.
* | ||
* @returns {Promise<undefined>|undefined} | ||
*/ | ||
BaseParamType.prototype.onSearchRequestStart = function () { |
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.
-
I'd have this return a dummy resolved Promise iso undefined.
-
I'd make the function signature also more explicit
BaseParamType.prototype.onSearchRequestStart = async function (aggconfig, searchSource, searchRequest) {
- Given this is a side-effect function, consider renaming as
modifyAggConfigOnSearchRequestStart
. This rename would also to distinguish it fromAggConfig#onsearchRequestStart(searchSource,SearchRequest)
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.
I updated the method name and added @param
comments about the arguments but I could not put the arguments in the method definition since BaseParamType#modifyAggConfigOnSearchRequestStart does not use the arguments and eslint is not happy about unused arguments
src/ui/public/vis/agg_config.js
Outdated
self.type && self.type.params.forEach(function (param) { | ||
if (param.onRequest) param.onRequest(self); | ||
}); | ||
AggConfig.prototype.onSearchRequestStart = function (...args) { |
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.
I wouldn't use the varargs and just call them what they are:
AggConfig.prototype.onSearchRequestStart = function (searchSource, searchRequest) { ...
}) | ||
.fetchAsRejectablePromise() | ||
.then((resp) => { | ||
aggConfig.autoBounds = { |
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.
We do this stuff quite a bit in Kibana, and side-effects when well managed are very useful, but I'd consider making this explicit with a getter/setter on AggConfig
. It will help jumping around in the code.
So I'd add something like:
AggConfig.prototype.setAutoBounds(autoBounds)
and AggConfig.prototype.getAutoBounds()
.
This would be similar to https://github.com/thomasneirynck/kibana/blob/1423d068f8d4d38e5c0f2087482e4a9155e77a28/src/ui/public/time_buckets/time_buckets.js#L44-L44, which I find a little more readable.
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.
Should the getters/setter methods really be added to AggConfig since most other configs will never need autoBounds
? Autobounds is added to AggConfig as a decoration https://github.com/nreese/kibana/blob/hist_pre_flight/src/ui/public/agg_types/buckets/histogram.js#L22.
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.
I don't think this should go on the aggConfig
at all, but should go on aggConfig.params
. That's what the params object is for, and adding a getter/setter to a general class like AggConfig
doesn't really make sense to me.
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.
Oh, I guess you could just update your decorateAggConfig
function with getAutoBounds()
and setAutoBounds()
...
@thomasneirynck The PR contains a selenium test. Is another needed? |
@nreese ok, shame on me, I completely missed https://github.com/elastic/kibana/pull/14157/files#diff-492637ba8caab7b809370b55eecad4e1. no, that's good, sorry for run around. |
@thomasneirynck Everything has been addressed and should be ready for another look |
jenkins, test this |
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.
🔥 👨🚒
great, thx!
2e56fa1
to
2d76f03
Compare
Failed test caused by #14503. Trying again Jenkins, test this |
… add functional test
…ters for autoBounds to AggConfig. Protect against divide by zero
2d76f03
to
abfb618
Compare
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.
nice! LGTM
…ic#14157) * update histogram agg to fetch min and max when search request started * scale interval when too many buckets are created * move min and max params into autoBounds param, remove typo in help text * use decorated property instead of params to avoid changing agg state, add functional test * remove sleep from functional test * make args for onSearchRequest functions specific. Add getters and setters for autoBounds to AggConfig. Protect against divide by zero * add unused arguments with eslint comment
… (#14531) * update histogram agg to fetch min and max when search request started * scale interval when too many buckets are created * move min and max params into autoBounds param, remove typo in help text * use decorated property instead of params to avoid changing agg state, add functional test * remove sleep from functional test * make args for onSearchRequest functions specific. Add getters and setters for autoBounds to AggConfig. Protect against divide by zero * add unused arguments with eslint comment
Fixes #2908
@spalger's PR added the infrastructure required for aggregations to perform pre-flight requests before getting serialized. This PR uses
onRequestStart
to fetch the min/max before serializing the histogram aggregation. That way, the interval can be scaled to ensure that a proper value is provided to avoid creating a gazillion buckets and crashing the browser.