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

[esaggs][inspector]: Refactor to prep for esaggs move to server. #83199

Merged
merged 7 commits into from
Nov 18, 2020

Conversation

lukeelmers
Copy link
Member

@lukeelmers lukeelmers commented Nov 11, 2020

Part of #65067

Summary

This PR restructures the esaggs expression function in preparation for moving it to the server. It also improves some of the Adapters typings in the inspector plugin so that they provide added type safety in the esaggs request handler.

Following this PR, we'll be able to make some of the needed changes to improve the semantics of esaggs args, and ultimately move the function to common so it can be registered on both client & server.

Changes

Inspector:

  • Adds typings for TabularData which has been a longstanding TODO item
  • Adds typings for data and requests adapters to the Adapters interface
    • There is no perfect way to do this, as anybody can add Adapters at any point, and the current typings for Adapters are basically [key: string]: any.
    • Since data and requests are both baked into the inspector plugin, it felt like we should at least provide type safety for these. It also prevents any potential naming collisions if someone else wants to add an adapter with the same names.
  • Updates downstream plugins which rely on Adapters to handle the new typings.

Esaggs:

  • Splits courierRequestHandler out of esaggs and renames requestHandler
  • Relocates buildTabularInspectorData to esaggs since it's the only place it is used
  • Refactoring in esaggs, requestHandler, buildTabularInspectorData to extract dependencies on external services
    • This will make it easier to plug in each of the service dependencies on both the client & the server, without needing to change the esaggs implementation.

Reviewers

  • If you're tagged for a codeowner review, it's due to the updated inspector typings, as all other changes are internal to data
  • It is probably easiest to review this PR commit-by-commit, with "hide whitespace changes" enabled. Otherwise the git diff doesn't make it clear what changes I made to the contents of esaggs & courier request handler

Testing

This PR should introduce no functional changes as it is simply a refactor. It touches the search infrastructure used by Visualizations, including Lens. It also touches the code that logs requests/responses to the inspector in these apps.

@lukeelmers lukeelmers added Feature:Search Querying infrastructure in Kibana WIP Work in progress v8.0.0 release_note:skip Skip the PR/issue when compiling release notes v7.11.0 labels Nov 11, 2020
@lukeelmers lukeelmers self-assigned this Nov 11, 2020
@lukeelmers lukeelmers force-pushed the feat/esaggs-server-1 branch 2 times, most recently from e7121ca to 90aa172 Compare November 12, 2020 21:47
@@ -40,8 +40,10 @@ interface ValueSuggestionsGetFnArgs {
signal?: AbortSignal;
}

const getAutocompleteTimefilter = (indexPattern: IIndexPattern) => {
const { timefilter } = getQueryService().timefilter;
Copy link
Member Author

Choose a reason for hiding this comment

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

When I removed the getQueryService service getter, I realized it was still being used here. Rather than revert the change, I simply updated the autocomplete service since it was a straightforward fix.

Comment on lines +115 to +125
getStartDependencies: async () => {
const [, , self] = await core.getStartServices();
const { fieldFormats, indexPatterns, query, search } = self;
return {
addFilters: query.filterManager.addFilters.bind(query.filterManager),
aggs: search.aggs,
deserializeFieldFormat: fieldFormats.deserialize.bind(fieldFormats),
indexPatterns,
searchSource: search.searchSource,
};
},
Copy link
Member Author

Choose a reason for hiding this comment

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

All these service dependencies are now wired up in the top-level plugin.ts, which should make it easy to update when we register the function on the server.

Some of these dependencies may also be adjusted when we clean up the esaggs index patterns & aggs args in a follow up PR.

@@ -131,7 +131,7 @@ export class SearchEmbeddable
this.savedSearch = savedSearch;
this.$rootScope = $rootScope;
this.$compile = $compile;
this.inspectorAdaptors = {
this.inspectorAdapters = {
Copy link
Member Author

Choose a reason for hiding this comment

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

Changed this to fix a typo :) Adaptors -> Adapters

const title = i18n.translate('discover.embeddable.inspectorRequestDataTitle', {
defaultMessage: 'Data',
});
const description = i18n.translate('discover.embeddable.inspectorRequestDescription', {
defaultMessage: 'This request queries Elasticsearch to fetch the data for the search.',
});

const inspectorRequest = this.inspectorAdaptors.requests.start(title, {
const inspectorRequest = this.inspectorAdapters.requests!.start(title, {
Copy link
Member Author

Choose a reason for hiding this comment

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

The only reason this worked without ! or a check for inspectorAdapters.requests was because the Adapters interface was [key: string]: any

Now that requests and data are added as optional properties, TS makes you check for their presence or assert that you know they are there.

Comment on lines +27 to +28
data?: DataAdapter;
requests?: RequestAdapter;
Copy link
Member Author

Choose a reason for hiding this comment

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

Rationale for this change:

  • data and requests are the most commonly used adapters
  • they ship in the inspector plugin so it stands to reason that we would provide typings for them
  • they are optional because technically they aren't guaranteed to be there as they need to be added by apps
  • putting them here improves type safety, and also helps prevent name collisions
  • in a perfect world, we could consider a refactor to make this generic so that you can provide type params for other Adapters to it. In the meantime, downstream apps can use casting.

@@ -44,7 +44,7 @@ interface DataViewComponentState {
tabularData: TabularData | null;
tabularOptions: TabularLoaderOptions;
adapters: Adapters;
tabularPromise: TabularCallback | null;
tabularPromise: Promise<TabularHolder> | null;
Copy link
Member Author

Choose a reason for hiding this comment

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

The existing typings were actually incorrect, which was hidden by the fact that TabularData was any

@lukeelmers lukeelmers removed the WIP Work in progress label Nov 12, 2020
@lukeelmers lukeelmers marked this pull request as ready for review November 12, 2020 23:18
@lukeelmers lukeelmers requested a review from a team November 12, 2020 23:18
@lukeelmers lukeelmers requested review from a team as code owners November 12, 2020 23:18
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch (Team:AppArch)

* This function builds tabular data from the response and attaches it to the
* inspector. It will only be called when the data view in the inspector is opened.
*
Copy link
Member

@ppisljar ppisljar Nov 16, 2020

Choose a reason for hiding this comment

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

I think we can get rid of this function (maybe in a separate PR). We had this to support inspector in expressions in the early days but i think right now its no longer needed. Rather, we should:

  • log the Datatable in every chart function (as esaggs is not the right place, futrther modifications to the datatable could happen further in expression)
  • update inspector view to work with new datatable format

@botelastic botelastic bot added the Feature:Embedding Embedding content via iFrame label Nov 16, 2020
// response data incorrectly in the inspector.
let response = (searchSource as any).rawResponse;
for (const agg of aggs.aggs) {
if (typeof agg.type.postFlightRequest === 'function') {
Copy link
Member

Choose a reason for hiding this comment

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

not related to this PR, but so bad :| terms other bucket only works inside expressions, not with searchsource directly

let request;
if (inspectorAdapters.requests) {
inspectorAdapters.requests.reset();
request = inspectorAdapters.requests.start(
Copy link
Member

Choose a reason for hiding this comment

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

hmm .... feels this should rather exist on the searchsource?

Copy link
Contributor

@kindsun kindsun left a comment

Choose a reason for hiding this comment

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

Maps changes lgtm!

  • code review

@lukeelmers
Copy link
Member Author

Here's the plan @ppisljar and I discussed offline. First, we wrap up this PR and merge it as-is so we can move toward getting esaggs on the server (which is the most time-sensitive priority).

Then we take some follow-up steps:

  1. Generalize buildTabularInspectorData to work with the new Datatable format and export it from the data runtime contract so that other apps can use it. We will be able to extract the filter data from the table itself rather than needing the FilterManager.
  2. Have updates to inspector & the postFlightRequest for aggs "other" bucket happen in SearchSource. It doesn't make sense that you'd get this functionality when using esaggs but not when using SearchSource.
  3. In the end, esaggs should simply be a small function that calls SearchSource with the provided aggs, and runs the result through tabify

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
data 597 599 +2
inspector 60 61 +1
total +3

Async chunks

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

id before after diff
data 245.4KB 245.5KB +2.0B
inspector 39.3KB 39.5KB +242.0B
maps 2.8MB 2.8MB +138.0B
total +382.0B

Page load bundle

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

id before after diff
data 965.9KB 968.9KB +3.0KB
inspector 49.9KB 52.1KB +2.2KB
total +5.2KB

History

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

Copy link
Member

@kertal kertal left a comment

Choose a reason for hiding this comment

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

KibanaApp owned code LGTM 👍 , didn't test, just a typo & TypeScript fix, thx for you explanations!

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.

code LGTM

@lukeelmers lukeelmers merged commit 62e06ae into elastic:master Nov 18, 2020
@lukeelmers lukeelmers deleted the feat/esaggs-server-1 branch November 18, 2020 16:11
phillipb added a commit to phillipb/kibana that referenced this pull request Nov 18, 2020
…o-node-details

* 'master' of github.com:elastic/kibana:
  Derive the port from the protocol in cases where it's not explicitly stated (elastic#83583)
  [CI] Build docker image during packer_cache (elastic#82145)
  [esaggs][inspector]: Refactor to prep for esaggs move to server. (elastic#83199)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Embedding Embedding content via iFrame Feature:Search Querying infrastructure in Kibana release_note:skip Skip the PR/issue when compiling release notes v7.11.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants