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

[new-platform] migrate ui/chrome/loading_count API to new platform #21967

Merged
merged 6 commits into from
Aug 17, 2018

Conversation

spalger
Copy link
Contributor

@spalger spalger commented Aug 14, 2018

Part of #20696, required for #20697

This migrates the chrome.loadingCount API to the new platform, which was not planned to happen before #20697 but is required as the UiSettingsClient uses the loading count to activate the global loading indicator in Kibana. This service is pretty simple, it allows adding an observable with core.loadingCount.add(observable) that will be subscribed to in order to contribute to the current "loading count", which can be retrieved with core.loadingCount.get$().

The ui/chrome/api/loading_count module is taking the start contract from the service and re-exposing it via the existing chrome.loadingCount api that we have today, including increment(), decrement(), subscribe(), and the automatic watching of the loading count exposed by the angular $http service.

@spalger spalger added review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:New Platform v7.0.0 v6.5.0 labels Aug 14, 2018
@spalger spalger requested a review from azasypkin August 14, 2018 19:08
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@azasypkin
Copy link
Member

ACK: will try to take a look today or tomorrow evening (CEST) at the latest.

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

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

Code looks good to me, just a couple of things. I haven't noticed anything bad during testing except for one weird warning in the browser console that seems to be related to this PR and that we should take care of before we merge this:

warning

}
export function __newPlatformInit__(instance) {
if (newPlatformLoadingCount) {
throw new Error('ui/chrome/loading_count already initialized with new platform apis');
Copy link
Member

Choose a reason for hiding this comment

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

nit: ui/chrome/loading_count ---> ui/chrome/api/loading_count?

},

getCount$: () => {
return this.count$.asObservable();
Copy link
Member

Choose a reason for hiding this comment

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

question: is there any reason why we don't want to use something like this this.count$.pipe(distinct()) instead? It looks like this will always fire even if delta above is 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nope, I think it makes the most sense for this API to only emit the loading count when it changes.

.subscribe({
next: ([prev, next]) => {
const delta = next - prev;
this.count$.next(this.count$.getValue() + delta);
Copy link
Member

Choose a reason for hiding this comment

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

issue: it can easily go to negative numbers, what should do we in this case? Call fatalErrors.add or just log this weird behavior and keep 0 as the minimum count?

Copy link
Member

@azasypkin azasypkin Aug 15, 2018

Choose a reason for hiding this comment

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

UPDATE: just put console.log here and indeed I've seen -1 for this.count$.getValue() + delta a couple of times (with x-pack plugins). Looks like old code didn't have this issue.

Copy link
Contributor Author

@spalger spalger Aug 15, 2018

Choose a reason for hiding this comment

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

Hmm, pretty sure we currently only have two things that are contributing to the loading count: the length of the $http.pendingRequest array (can't ever go below zero) and calls to chrome.loadingCount.increment() and decrement() from here:

chrome.loadingCount.increment();

Based on that I can't imagine how we are getting negative loading counts...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you try running in the debugger and tracing back up the call stack to see what is causing the loading count to go negative?

Copy link
Member

Choose a reason for hiding this comment

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

Can't reproduce it with the latest changes, so it's all good now! :)

subscription.unsubscribe();
}

this.subscriptions.length = 0;
Copy link
Member

Choose a reason for hiding this comment

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

question: should we this.count$.next(0) and this.count$.complete() here and restart in start (and simple test for this if you agree)? Otherwise this.count$ and its subscribers will stay in some "undefined" state.


const startContract = service.start({
fatalErrors: {
add: jest.fn(),
Copy link
Member

Choose a reason for hiding this comment

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

optional nit: maybe add a simple test for error case when we call fatalErrors.add?

@spalger spalger force-pushed the migrate-new-platform/loading-count branch from 51faa92 to 237f497 Compare August 16, 2018 01:02
@spalger
Copy link
Contributor Author

spalger commented Aug 16, 2018

@azasypkin tracked down that error, it was caused by digest cycles that get triggered when react components use methods like getBasePath() which are passed down to react components as props. ngReact automatically wraps these functions in calls to $scope.$apply() to make sure that angular sees any updates, which was causing our watcher to emit the number of active angular http requests (almost always zero). This is now prevented by using distinctUntilChanged(), but will still be triggered if someone executes a web request in a render for some reason 👍

@spalger spalger requested a review from azasypkin August 16, 2018 01:45
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@azasypkin
Copy link
Member

@azasypkin tracked down that error, it was caused by digest cycles that get triggered when react components use methods like getBasePath() which are passed down to react components as props. ngReact automatically wraps these functions in calls to $scope.$apply() to make sure that angular sees any updates, which was causing our watcher to emit the number of active angular http requests (almost always zero). This is now prevented by using distinctUntilChanged(), but will still be triggered if someone executes a web request in a render for some reason 👍

Huh, nice find!

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

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

LGTM! Tested locally one more time and haven't noticed anything suspicious.

tap(count => {
if (count < 0) {
throw new Error(
'Observables passed to loadingCount.add() must only emit possitive numbers'
Copy link
Member

Choose a reason for hiding this comment

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

typo: possitive ---> positive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Spelling is not my strong suit. Thank you 🙏

@elasticmachine
Copy link
Contributor

💔 Build Failed

@spalger
Copy link
Contributor Author

spalger commented Aug 17, 2018

Retest

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@spalger spalger merged commit 191ea1f into elastic:master Aug 17, 2018
spalger pushed a commit to spalger/kibana that referenced this pull request Aug 17, 2018
…lastic#21967)

Part of elastic#20696, required for elastic#20697

This migrates the `chrome.loadingCount` API to the new platform, which was not planned to happen before elastic#20697 but is required as the UiSettingsClient uses the loading count to activate the global loading indicator in Kibana. This service is pretty simple, it allows adding an observable with `core.loadingCount.add(observable)` that will be subscribed to in order to contribute to the current "loading count", which can be retrieved with `core.loadingCount.get$()`.

The `ui/chrome/api/loading_count` module is taking the start contract from the service and re-exposing it via the existing `chrome.loadingCount` api that we have today, including `increment()`, `decrement()`, `subscribe()`, and the automatic watching of the loading count exposed by the angular `$http` service.
spalger pushed a commit that referenced this pull request Aug 18, 2018
…orm (#21967) (#22156)

Backports the following commits to 6.x:
 - [new-platform] migrate ui/chrome/loading_count API to new platform  (#21967)
@spalger
Copy link
Contributor Author

spalger commented Aug 18, 2018

6.x/6.5: fad921d

@spalger spalger deleted the migrate-new-platform/loading-count branch August 18, 2018 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v6.5.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants