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

[Expressions] Update expressions public API to expose partial results support #102403

Merged
merged 6 commits into from Jul 1, 2021

Conversation

dokmic
Copy link
Contributor

@dokmic dokmic commented Jun 16, 2021

Summary

Updates expressions plugin to expose partial results support.
Resolves #98280.

Checklist

For maintainers

@dokmic dokmic changed the title [Expressions] Update expressions public API to expose partial results [Expressions] Update expressions public API to expose partial results support Jun 16, 2021
@spalger
Copy link
Contributor

spalger commented Jun 16, 2021

jenkins, test this

(restarting due to jenkins upgrade)

@dokmic dokmic force-pushed the feature/98280 branch 4 times, most recently from 7e79486 to 2bc22d4 Compare June 21, 2021 07:09
@dokmic dokmic marked this pull request as ready for review June 21, 2021 09:15
@dokmic dokmic requested a review from a team June 21, 2021 09:15
@dokmic dokmic requested review from a team as code owners June 21, 2021 09:15
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-services (Team:AppServices)

@dokmic dokmic requested a review from ppisljar June 21, 2021 09:16
this.data$.subscribe((data) => {
this.render(data);
this.data$.subscribe(({ result }) => {
this.render(result);
Copy link
Member

@ppisljar ppisljar Jun 21, 2021

Choose a reason for hiding this comment

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

loader needs to receive an option if partial results should be rendered or not,

if option is false (default), we only render when partial===false

@@ -30,7 +30,11 @@ export interface ReactExpressionRendererProps extends IExpressionLoaderParams {
) => React.ReactElement | React.ReactElement[];
padding?: 'xs' | 's' | 'm' | 'l' | 'xl';
onEvent?: (event: ExpressionRendererEvent) => void;
onData$?: <TData, TInspectorAdapters>(data: TData, adapters?: TInspectorAdapters) => void;
onData$?: <TData, TInspectorAdapters>(
Copy link
Member

Choose a reason for hiding this comment

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

we need a prop to allow opting in to partial result. we should pass that to loader then, if prop is not enabled partial data should not be rendered (only final results)

Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

I might be missing something but this looks like it's not possible to disable partial rendering when using the expression renderer component? As we want to provide indication for partial results in the rendered Lens chart, we need a way to selectively disable partial results.

Edit: What Peter said (#102403 (comment))

@dokmic
Copy link
Contributor Author

dokmic commented Jun 21, 2021

@ppisljar @flash1293 I have added an option to disable partial results in the loader and the renderer. Could you please take another look?

Copy link
Contributor

@wylieconlon wylieconlon left a comment

Choose a reason for hiding this comment

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

I'm reviewing this and seeing that I have two assumptions that are not fully met here:

  1. Lens might conditionally render partial results, for example if there is a time series vs terms aggregation.

  2. Lens might implement some kind of progress indicator as a percentage, like 50% loaded.

/**
* Partial result flag.
*/
partial: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

We need more than just a flag for partial data, we need some kind of status indicator as well. Typically I'd imagine this is the shard responses: 100 total shards, 5 successful, 50 skipped, 1 failure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We cannot predict that because an expression function can emit an indefinite number of results. So the best you can do is to implement the progress indication in a function.

Copy link
Contributor

@flash1293 flash1293 Jun 22, 2021

Choose a reason for hiding this comment

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

@dokmic

So the best you can do is to implement the progress indication in a function

Can you elaborate on how this would look like? I think this is an important part of supporting partial results.
I can imagine this information being part of the datatable (what do you think @ppisljar ?) but I think we need to find some kind of solution for it.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dokmic Elasticsearch indicates the number of successful vs total shards on every partial status call, this is what I'm referring to: async search status

Copy link
Member

Choose a reason for hiding this comment

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

@flash1293 @wylieconlon this PR does not try to address progress indication apart from letting the consumer know when result is partial vs final. Progress reporting will be added at a later time, right now its not even supported on our low level search service.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ppisljar Right, I understand that it's not supported yet. What I'm asking is that we implement an API that can support a progress indicator, not just a boolean.

Copy link
Member

Choose a reason for hiding this comment

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

we didn't want to do anything more for now as we don't know yet in what form progress from es will be provided to us or how we'd want to report this on expression level. in the future we are likely to keep this partial flag and add another progress variable.


subscriber.add(
source.subscribe({
next: (result) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like sources need to provide their own partial status indicator here, not just automatically setting it to partial: true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's being overwritten later on the same frame upon completion. So for the last result that will be true. You can also see that in the unit test.

@flash1293
Copy link
Contributor

flash1293 commented Jun 22, 2021

@wylieconlon

Lens might conditionally render partial results, for example if there is a time series vs terms aggregation.

Maybe I'm missing something, but this should be possible with the changes on this PR, right?

https://github.com/elastic/kibana/pull/102403/files#diff-7baf074ce8b6f875e3a7bae021ba4cbf98ed6907c9d7819025954b037587395aR51

adds the partial flag to the loader params which can be used on the expression renderer component as well. We can put custom logic in Lens to decide whether to execute an expression with or without partial flag (seems like a relatively easy extension on our side)

@flash1293
Copy link
Contributor

@elasticmachine merge upstream

@wylieconlon
Copy link
Contributor

@flash1293 I think you're right that this PR does expose options for us. We can always set <ReactExpressionRenderer partial={shouldRenderPartial()} ...> from Lens so that partial data is rendered only when we need it to be.

@flash1293
Copy link
Contributor

flash1293 commented Jun 23, 2021

I'm not sure whether this is fully working for Lens (at least for the other bucket).

I set the partial flag here:

but the onData callback is still only called once when I'm running a configuration using the other bucket setting on a top values:

As far as I understood the other bucket should be treated as partial result, right?

@dokmic
Copy link
Contributor Author

dokmic commented Jun 29, 2021

@flash1293 That does not work because the partial prop is being discarded in the ExpressionWrapper higher-order component.

Copy link
Member

@ppisljar ppisljar left a comment

Choose a reason for hiding this comment

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

LGTM

@flash1293
Copy link
Contributor

flash1293 commented Jun 30, 2021

@dokmic The piece of code you linked is not used in the Lens editor, it's only used on dashboards.

I retried on the latest version and it doesn't work for me, I guess I'm doing something wrong. These are the steps I took:

Screenshot 2021-06-30 at 11 11 05

  • Load a chart which includes an other bucket (top values function). My understanding is that it should cause the chart to render twice - once without the other bucket row, then again with the other bucket. However it's just rendering once (with the other bucket):
    Kapture 2021-06-30 at 11 12 18

If you are seeing something else I'm happy to sync offline to clear up my confusion.

@spalger spalger added v7.15.0 and removed v7.14.0 labels Jun 30, 2021
Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

Discussed this offline and this PR won't give the ability the actually render partial results in Lens yet - further steps are necessary (esaggs has to return an observable instead of a promise).

I tested Lens, Visualize and TSVB and didn't notice anything breaking. LGTM for Kibana app side.

Copy link
Contributor

@wylieconlon wylieconlon left a comment

Choose a reason for hiding this comment

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

Okay, LGTM. I agree that we can add an additional parameter to indicate the status of the partial results.

@flash1293 Other bucket is not the only way to test the partial results, but it does seem like an easy one. The other one that I've found to work pretty well is creating a script that performs more work on older data and less work on newer data. Sharing this script in case it helps:

ZonedDateTime date = doc['@timestamp'].value;
long doctime = date.toInstant().toEpochMilli();
String datetime = '2021-07-07T22:15:30Z';
ZonedDateTime now = ZonedDateTime.parse(datetime);
long nowtime = now.toInstant().toEpochMilli();
long multiple = 20 * (nowtime - doctime) / 31536000000L;
for (int i = 0; i < multiple; i++) {
    String local = '1983-10-13T22:15:30Z';
    ZonedDateTime localz = ZonedDateTime.parse(datetime);
    long epoch = localz.toInstant().toEpochMilli();
}
emit(multiple);

The other change that needs to be made to test locally is updating batched_reduce_size: 64 -> batched_reduce_size: 2 in request_utils.ts

Copy link
Contributor

@clintandrewhall clintandrewhall left a comment

Choose a reason for hiding this comment

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

LGTM

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
expressions 1534 1535 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
canvas 1.2MB 1.2MB +222.0B
visTypeTimeseries 1007.3KB 1007.3KB +68.0B
total +290.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
expressions 210.2KB 211.3KB +1.0KB
Unknown metric groups

API count

id before after diff
expressions 1962 1966 +4

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@dokmic dokmic merged commit 975e361 into elastic:master Jul 1, 2021
@dokmic dokmic deleted the feature/98280 branch July 1, 2021 20:48
dokmic added a commit that referenced this pull request Jul 1, 2021
… support (#102403) (#104210)

* Add partial result flag to the execution result
* Update expressions plugin run method to return observable
* Update data getter in the execution contract to return observable
* Update the expression loader to take into account the partial results flag
madirey pushed a commit to madirey/kibana that referenced this pull request Jul 6, 2021
… support (elastic#102403)

* Add partial result flag to the execution result
* Update expressions plugin run method to return observable
* Update data getter in the execution contract to return observable
* Update the expression loader to take into account the partial results flag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

update all expression public API's to expose partial results
8 participants