Skip to content

expression service#42337

Merged
ppisljar merged 6 commits intoelastic:masterfrom
ppisljar:expressionService/1
Sep 4, 2019
Merged

expression service#42337
ppisljar merged 6 commits intoelastic:masterfrom
ppisljar:expressionService/1

Conversation

@ppisljar
Copy link
Copy Markdown
Contributor

@ppisljar ppisljar commented Jul 31, 2019

Summary

Implements basic expression service

Checklist

Use strikethroughs to remove checklist items you don't feel are applicable to this PR.

For maintainers

@ppisljar ppisljar added WIP Work in progress Team:AppArch labels Jul 31, 2019
@ppisljar ppisljar requested review from flash1293 and lukeelmers July 31, 2019 11:37
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/kibana-app-arch

@elasticmachine
Copy link
Copy Markdown
Contributor

💔 Build Failed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Removing that makes it impossible to pass in things like the context over the react interface. IExpressionLoaderParams should be part of the renderer props. They are already passed correctly to the loader: https://github.com/elastic/kibana/pull/42337/files#diff-e2b0614a60b75e9f05d4bec84efb896aR50

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The only breaking change for the expression renderer react component is that it won't be possible to pass in a custom getInitialContext function anymore. Maybe I'm missing something, but is that limitation necessary?

The alternative would be adding getInitialContext to IExpressionLoaderParams instead of searchContext. Then there could also be initial contexts other than kibana_context. Not important for the usage in Lens though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

you can pass in the SearchContext (which will be returned by getInitialContext).
for now lets keep it like this, if we find a usecase for sending in something else we can extend this in the future.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The re-creates the loader every time a new expression is passed into this component, right? Shouldn't we hold the loader in a ref? Otherwise cancel isn't called correctly in this branch https://github.com/elastic/kibana/pull/42337/files#diff-1793959dde8c2d221081302bc14dd984R99 for the old loader.

Copy link
Copy Markdown
Contributor

@lizozom lizozom Aug 6, 2019

Choose a reason for hiding this comment

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

Please change the imports to the new plugin.
You will have to export DataAdapter, RequestAdapter from the top level of the inspector plugin.

I started here #42615, but closing this PR now.

@ppisljar ppisljar force-pushed the expressionService/1 branch from e5056d3 to 23af8fa Compare August 22, 2019 11:43
@ppisljar ppisljar added review and removed WIP Work in progress labels Aug 22, 2019
@ppisljar ppisljar requested a review from streamich August 22, 2019 11:43
@ppisljar ppisljar added v7.4.0 v8.0.0 release_note:skip Skip the PR/issue when compiling release notes labels Aug 22, 2019
@elasticmachine
Copy link
Copy Markdown
Contributor

💔 Build Failed

Copy link
Copy Markdown
Contributor

@streamich streamich left a comment

Choose a reason for hiding this comment

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

LGTM, subject to Joe's questions and green CI.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

FYI, I'm adding getRenderer method to Expressions service in a parallel PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure why set all these observables on this object, we can already access them through this.renderHandler.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

renderHandler is private and not accessible to the outside

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IExpressionLoader is a type, not interface, but it has I prefix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

do we have a convention for naming types ? TExpressionLoader ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Like Liza mentioned, the above two could be like this:

import { DataAdapter, RequestAdapter, Adapters } from '../../../../../../plugins/inspector/public';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Right now this is just typed as unknown in the @kbn/interpreter package. We should instead use the ExpressionAST interface from src/plugins/data/common/expressions/types

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are the anys needed here, or are these types already provided by IInterpreterRenderHandlers?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should export DataStart here too

Copy link
Copy Markdown
Contributor

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 is ultimately calling the renderer from the registry right (via the render handler?)

Are any renderers actually returning a Promise<RenderId> today? Otherwise we should perhaps be adding an ExpressionRenderer generic, similar to ExpressionFunction, so that this can actually be enforced.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hmm ... here we call the expression renderer handler, which will return a promise which will always resolve with the renderId. There internally we call renderer from the registry and pass it the handlers. Once rendering is done the done() handler should be called (and is nowadays i think for all renderers) which then resolves the promise.

@ppisljar ppisljar force-pushed the expressionService/1 branch from 23af8fa to 3f4cb0d Compare September 3, 2019 10:48
@ppisljar ppisljar added v7.5.0 and removed v7.4.0 labels Sep 3, 2019
@elasticmachine
Copy link
Copy Markdown
Contributor

💔 Build Failed

@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

}: ExpressionRendererProps) => {
const mountpoint: React.MutableRefObject<null | HTMLDivElement> = useRef(null);

const handlerRef = useRef((null as any) as ExpressionLoader);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: can be written as useRef<null | ExpressionLoader>(null); for better type safety.

*/
onRenderFailure?: (result: Result) => void;
};
onRenderFailure?: (result: IInterpreterResult) => void;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you add a className prop here that's passed to the mount div element?

handlerRef.current.data$.toPromise().catch(result => {
if (onRenderFailure) {
onRenderFailure(result);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This effect should also re-render if options.context changes

}

public start({ inspector }: ExpressionsServiceStartDependencies) {
const ExpressionRenderer = createRenderer(loader);
Copy link
Copy Markdown
Contributor

@flash1293 flash1293 Sep 4, 2019

Choose a reason for hiding this comment

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

Can we expose the renderer in the setup phase? Lens currently requires the expression renderer in the embeddable factory which should register its stuff in the setup phase.

EDIT: OK, I see why it is solved this way - the inspector is not ready in the setup phase. I guess we could work around it in Lens and pass the expression renderer to the embeddable factory instance in the start phase - slightly dirty but probably the best way. It's not super clean because it hides the fact that Lens embeddables can only be created after the start phase but it shouldn't cause problems in this particular instance and I can throw an explanatory error if it happens.

Still wondering whether there is a better way though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah, also different plugins (will) register renderers, so in your setup lifecycle there is no guarantee that the functions or renderers exist in the registry yet.

adding options to deps
Copy link
Copy Markdown
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.

Changes LGTM

@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

@ppisljar ppisljar merged commit 2f5306e into elastic:master Sep 4, 2019
> & {
expression: string | Ast;
export interface ExpressionRendererProps extends IExpressionLoaderParams {
className: 'string';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@ppisljar The only allowed className here is the literal string "string"- the quotes should be removed

ppisljar added a commit to ppisljar/kibana that referenced this pull request Sep 9, 2019
ppisljar added a commit that referenced this pull request Sep 9, 2019
@elasticmachine
Copy link
Copy Markdown
Contributor

💔 Build Failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release_note:skip Skip the PR/issue when compiling release notes review v7.5.0 v8.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants