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

[Search] Search batching using bfetch #83418

Merged
merged 36 commits into from
Nov 22, 2020

Conversation

lizozom
Copy link
Contributor

@lizozom lizozom commented Nov 16, 2020

Summary

This PR was reverted and replaced with #84043

This PR introduces search request batching using bfetch.
It is especially beneficial to applications that send multiple requests in a session, like dashboard.
It should address customer complaints on loading taking long and using a lot of network due to making multiple connections.

Without bfetch

image

With bfetch, the dashboard is re-loaded using a single request.

image

Edge cases and things to pay attention to

Requests can be sent in more than one batch. Batches are limited by size and by time. In some cases, multiple batches might be sent

Query cancellation

Query cancellation still works!

In OSS we rely on a hangup like before. Since bfetch was adjusted not to wait for aborted requests, it will close the connection as all other requests in the batch are completed.

In xpack, the same logic applies, but we also send the cancellation request

Errors

Regular errors are returned as part of the response stream and are passed back to the issuing request.
If a bfetch stream is hung up for some reason, all requests are rejected properly.

Release Notes

This PR introduces search request batching using bfetch.
It should address performance issues due to opening multiple connections for search, especially in applications like dashboard.

Users who wish to opt-out and fallback to legacy behavior for any reason, can toggle the Use legacy search option in Advanced Settings.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@lizozom lizozom marked this pull request as ready for review November 17, 2020 17:16
@lizozom lizozom requested a review from a team as a code owner November 17, 2020 17:16
@elasticmachine
Copy link
Contributor

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

@botelastic botelastic bot added Feature:Embedding Embedding content via iFrame Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) labels Nov 17, 2020
Copy link
Member

@lukasolson lukasolson left a comment

Choose a reason for hiding this comment

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

I would much prefer that we stick to the AbortSignal usage rather than introduce this getBatchDone$ which creates an observable that serves the same purpose.

@lizozom
Copy link
Contributor Author

lizozom commented Nov 19, 2020

@lukasolson in your patch, the batch signal fires if all requests that had an abort signal were aborted.
However, if there were any requests that were not aborted or didn't have a signal - you would kill the batch and prevent them from completing.

Also, using reference counting to track success, is not a good idea, as the same request might get resolved, then get aborted. (See the comment I gave to @streamich )

I really thing we need a single mechanism to track all requests, and I think mine is simple enough and having utility functions contributes to the testability of this code.

Copy link
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.

bfetch changes LGTM. Added few suggestions below.

Comment on lines 116 to 117
// abort when all items were either resolved, rejected or aborted
Promise.all(promises).then(() => abortController.abort());
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a small problem, which practically might not be an issue. The abortController.abort() is called whenever all items in the batch have somehow completed—either resolved or rejected, or aborted; in any combination.

But my understanding is that we don't need to call abortController.abort() when, for example, all items successfully resolved. We need to call abortController.abort() only when all items have completed and at least one of them completed due to an abort signal.

Do you think we should be that specific? Or aborting the request every time, even when it already finished successfully is a noop?

src/plugins/bfetch/public/streaming/from_streaming_xhr.ts Outdated Show resolved Hide resolved
@lizozom
Copy link
Contributor Author

lizozom commented Nov 21, 2020

@elasticmachine merge upstream

@lizozom lizozom merged commit 5708c5d into elastic:master Nov 22, 2020
lizozom added a commit to lizozom/kibana that referenced this pull request Nov 22, 2020
* Use bfetch for search (no abort behavior)

* fix merge

* Handle request abortion + unit tests

* fix jest

* shim totals in oss

* proper formatting for errors

* jest, types and docs

* Fix doc

* Remove old search code and rename UI Setting

* jest mocks

* jest

* Solve unhanled error

* Use AbortSignal

* ts

* code review - use abort controller instead of observable

* Revert "Remove old search code and rename UI Setting"

This reverts commit 17de9fa.

* Remove old search code and rename UI Setting

* revert search route

* fix event unsubscribe

* code review 2

* revert filter

* simplify batch done logic

* code review

* filter items in the beginning

* jest

Co-authored-by: Kibana Machine <[email protected]>
lizozom added a commit that referenced this pull request Nov 22, 2020
* Use bfetch for search (no abort behavior)

* fix merge

* Handle request abortion + unit tests

* fix jest

* shim totals in oss

* proper formatting for errors

* jest, types and docs

* Fix doc

* Remove old search code and rename UI Setting

* jest mocks

* jest

* Solve unhanled error

* Use AbortSignal

* ts

* code review - use abort controller instead of observable

* Revert "Remove old search code and rename UI Setting"

This reverts commit 17de9fa.

* Remove old search code and rename UI Setting

* revert search route

* fix event unsubscribe

* code review 2

* revert filter

* simplify batch done logic

* code review

* filter items in the beginning

* jest

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Kibana Machine <[email protected]>
mistic added a commit to mistic/kibana that referenced this pull request Nov 22, 2020
mistic added a commit that referenced this pull request Nov 23, 2020
mistic added a commit to mistic/kibana that referenced this pull request Nov 23, 2020
mistic added a commit that referenced this pull request Nov 23, 2020
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
bfetch 20 21 +1

Page load bundle

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

id before after diff
bfetch 18.6KB 19.9KB +1.2KB
data 974.0KB 973.6KB -417.0B
dataEnhanced 36.3KB 36.3KB +28.0B
total +862.0B

History

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

gmmorris added a commit to rudolf/kibana that referenced this pull request Nov 23, 2020
* master: (67 commits)
  [Observability] Load hasData call asynchronously (elastic#80644)
  Implement AnonymousAuthenticationProvider. (elastic#79985)
  Deprecate `visualization:colorMapping` advanced setting (elastic#83372)
  [TSVB] [Rollup] Table tab not working with rollup indexes (elastic#83635)
  Revert "[Search] Search batching using bfetch (elastic#83418)" (elastic#84037)
  skip flaky suite (elastic#83772)
  skip flaky suite (elastic#69849)
  create kbn-legacy-logging package (elastic#77678)
  [Search] Search batching using bfetch (elastic#83418)
  [Security Solution] Refactor Timeline flyout to take a full page (elastic#82033)
  Drop use of console-stamp (elastic#83922)
  skip flaky suite (elastic#84011 , elastic#84012)
  Fixed usage of `isReady` for usage collection of alerts and actions (elastic#83760)
  [maps] support URL drilldowns (elastic#83732)
  Revert "Added default dedupKey value as an {{alertInstanceId}} to provide grouping functionality for PagerDuty incidents. (elastic#83226)"
  [code coverage] Update jest config to collect more data (elastic#83804)
  Added default dedupKey value as an {{alertInstanceId}} to provide grouping functionality for PagerDuty incidents. (elastic#83226)
  [Security Solution] Give notice when endpoint policy is out of date (elastic#83469)
  [Security Solution] Sync url state on any changes to query string (elastic#83314)
  [CI] Initial TeamCity implementation (elastic#81043)
  ...
mistic added a commit that referenced this pull request Nov 23, 2020
* Revert "[Search] Search batching using bfetch (#83418)"

This reverts commit 5708c5d.

* chore(NA): remove yarn.lock from kbn-legacy-logging
mistic added a commit to mistic/kibana that referenced this pull request Nov 23, 2020
* Revert "[Search] Search batching using bfetch (elastic#83418)"

This reverts commit 5708c5d.

* chore(NA): remove yarn.lock from kbn-legacy-logging
mistic added a commit that referenced this pull request Nov 23, 2020
* Revert "[Search] Search batching using bfetch (#83418)"

This reverts commit 5708c5d.

* chore(NA): remove yarn.lock from kbn-legacy-logging
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:ExpressionLanguage Interpreter expression language (aka canvas pipeline) release_note:enhancement v7.11.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants