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] Refactor expression functions to use observables underneath #100409

Merged
merged 2 commits into from
Jun 11, 2021

Conversation

dokmic
Copy link
Contributor

@dokmic dokmic commented May 20, 2021

Summary

Refactor expression functions to use observables underneath.
Resolves #93016.

Checklist

For maintainers

@dokmic dokmic marked this pull request as ready for review May 27, 2021 07:52
@dokmic dokmic requested review from a team as code owners May 27, 2021 07:52
@dokmic dokmic added Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) release_note:skip Skip the PR/issue when compiling release notes review Team:AppServices v7.14.0 v8.0.0 labels May 27, 2021
@elasticmachine
Copy link
Contributor

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

@dokmic dokmic requested a review from ppisljar May 27, 2021 07:54
columns: [...input.columns],
rows: [row],
}) ?? of(null)
).pipe(map((value) => ({ ...row, [id]: value })))
Copy link
Member

Choose a reason for hiding this comment

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

i think we don't need the pipe here

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 do need that because the expression returns a value that we need to put into the row. The expression is an observable, so we have to use the pipe here to process the value upon subscription.

});
return defer(() => {
const rows$ = input.rows.length
? zip(
Copy link
Member

Choose a reason for hiding this comment

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

zip will wait for all rows to emit the first value .... should we consider emitting rows as they come ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess that behavior will be backward incompatible and may not work as expected without adapting the code in other plugins.

const metaSourceFrom = columns.find(({ id }) => id === args.copyMetaFrom);
newColumn.meta = { ...newColumn.meta, ...(metaSourceFrom?.meta || {}) };
}
return rows$.pipe<Datatable>(
Copy link
Member

Choose a reason for hiding this comment

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

why do we need to pipe here?

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 here because we need to process rows altogether and put them into a datatable.

return { type: 'case', matches, result };
fn(input, { if: condition, then, when }) {
return defer(() => {
const matches = condition ?? when?.().pipe(map((value) => value === input)) ?? true;
Copy link
Member

Choose a reason for hiding this comment

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

why pipe ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

when returns an observable. That's the cleanest way to convert the value.

return args.else?.().pipe(take(1)).toPromise() ?? input;
}
fn(input, args) {
return defer(() => (args.condition ? args.then?.() : args.else?.()) ?? of(input));
Copy link
Member

Choose a reason for hiding this comment

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

condition is required

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected the argument type, but the code remains the same because then and else are optional.

byColumns = args.by.map((by) => {
const column = input.columns.find((col) => col.name === by);
const byColumns =
args.by?.map((by) => {
Copy link
Member

Choose a reason for hiding this comment

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

by will always exist (will be empty array if not set)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've checked that, and optional multi-valued arguments are actually undefined.

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.

Tested with Lens formula PR (which uses mapColumn) and everything works fine.

Copy link
Contributor

@poffdeluxe poffdeluxe left a comment

Choose a reason for hiding this comment

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

Tested this out across a few different workpads that used the functions in question. Everything seems to be working fine!

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

@dokmic dokmic force-pushed the feature/93016 branch 2 times, most recently from dc5e04c to 394fe55 Compare June 10, 2021 18:47
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

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.3MB 1.3MB +2.0B

Page load bundle

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

id before after diff
canvas 530.9KB 531.2KB +285.0B
expressions 202.5KB 202.7KB +281.0B
total +566.0B

History

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

@dokmic dokmic merged commit 9bcae4d into elastic:master Jun 11, 2021
@dokmic dokmic deleted the feature/93016 branch June 11, 2021 07:53
gmmorris added a commit to gmmorris/kibana that referenced this pull request Jun 14, 2021
* master: (68 commits)
  skip flaky suite (elastic#94043)
  skip flaky suite (elastic#102012)
  [esArchive] Persists updates for management/saved_objects/* (elastic#101992)
  skip flaky suite (elastic#101449)
  remove unnecessary hack (elastic#101909)
  [Exploratory View] Use human readable formats (elastic#101520)
  [Expressions] Refactor expression functions to use observables underneath (elastic#100409)
  [esArchives] Persist migrated Kibana archives (elastic#101950)
  [kbnArchiver] fix save to non-existent file (elastic#101974)
  [Enterprise Search] Add owner and description properties to kibana.json (elastic#101957)
  [DOCS] Fixes terminology in Stack Monitoring:Kibana alerts (elastic#101696)
  [Observability] [Cases] Cases in the observability app (elastic#101487)
  [Alerting][Docs] Combine rule creation and management pages (elastic#101498)
  temporarily disable build-buddy
  [Fleet] Fix fleet server collector in case settings are not set (elastic#101752)
  [Event Log] Populated rule.* ECS fields for alert events. (elastic#101132)
  [APM] Fleet support for merging input.config values with other nested properties in the policy input (elastic#101690)
  Add comments to some alerting plugin public API items (elastic#101551)
  [Alerting][Docs] Moving alerting setup to its own page (elastic#101323)
  remove uptime public API, it's not used. (elastic#101799)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) release_note:skip Skip the PR/issue when compiling release notes review v7.14.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rewrite functions using resolve:false to support observable arguments
6 participants