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

[ML] explorer controller refactor #28750

Merged
merged 33 commits into from
Jan 24, 2019

Conversation

walterra
Copy link
Contributor

@walterra walterra commented Jan 15, 2019

Summary

Refactors the application logic of Anomaly Explorer to reduce relying on angularjs. The updated event handling looks like this:

  • explorer_controller.js has been reduced to a bare wrapper. All that's left is $scope that's still necessary for now (e.g. jobs because of the job selector) and related events.
  • explorer_utils.js is a collection of functions previously housed in inline in explorer_controller.js. The function have been refactored to be more pure so they don't rely on outer state so they work stand-alone. This new structure will allow us to write unit tests for these functions in a follow up.
  • explorer_react_wrapper_directive.js no longer needs to pass through that much $scope from explorer_controller.js, it's now really just a shallow wrapper that passed through some props without applying further transformation.
  • explorer.js replaced most of explorer.html in a previous PR. Now it also includes previous methods from explorer_controller.js which managed angularjs $scope, but these methods have been refactored to manage React state.

Further updates 22.01.2019:

  • Refactored explorer.js state handling to be much more cleaned up and uni-directional. Data fetching and setState() is no longer in all kinds of different places, instead depending on actions (e.g. restoring a selection on reload, switching jobs, clicking on a cell) a stateUpdate update is prepared and passed on to updateExplorer(). Depending on stateUpdate (e.g. active Selection or not) updateExplorer() fetches necessary data and triggers setState() where appropriate. This results in much lesser render() calls and solves another race condition.
  • The above results in less spread out state related method calls, e.g. loadOverallData() is now only used 1 instead of 3 times throughout the code base, loadViewBySwimlaneData() is used 2 times instead of 6 times.
  • Most methods like loadOverallData() or loadViewBySwimlaneData() now feature a simple caching/memoizing capability. This is useful for example when the view is just resized, then the existing data doesn't need to be fetched again from the server. Instead of more complex state handling which tries to find out if for example loadOverallData() would need to be called again, using memoization the method can be just called again and acts as a state getter if the related method arguments didn't change.
  • All of the above was done to fix various issues with UI elements and the Anomaly Explorer not properly updating because the previous code was still more fragile than expected.

Review Checklist

  • Fix issue with EuiSelect value ending up as null. f2e3edf
  • Fix updating swimlanes on resize. 566b64d
  • Fix restoring swimlane selection from AppState. 031e176
  • Fix swimlane cell widths. fed6b94
  • Fix view by swimlanes showing only one job if two selected. fed6b94
  • Fix empty swimlanes after switching jobs. 0449a86

Checklist

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

For maintainers


Part of #18553 and #18374.

@walterra walterra added non-issue Indicates to automation that a pull request should not appear in the release notes v7.0.0 :ml refactoring Feature:ml-results legacy - do not use v6.7.0 labels Jan 15, 2019
@walterra walterra self-assigned this Jan 15, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/ml-ui

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

Copy link
Member

@jgowdyelastic jgowdyelastic left a comment

Choose a reason for hiding this comment

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

LGTM

x-pack/plugins/ml/public/explorer/explorer_utils.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer_utils.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer_utils.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer_controller.js Outdated Show resolved Hide resolved
@elasticmachine
Copy link
Contributor

💔 Build Failed

x-pack/plugins/ml/public/explorer/explorer.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer.js Outdated Show resolved Hide resolved
x-pack/plugins/ml/public/explorer/explorer.js Outdated Show resolved Hide resolved
@walterra walterra changed the title Ml explorer controller refactor [ML] explorer controller refactor Jan 15, 2019
@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@peteharverson peteharverson left a comment

Choose a reason for hiding this comment

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

Latest changes LGTM!

@elasticmachine
Copy link
Contributor

💔 Build Failed

Copy link
Member

@jgowdyelastic jgowdyelastic left a comment

Choose a reason for hiding this comment

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

LGTM, added a few nitpicks, feel free to ignore

stateUpdate.swimlaneViewByFieldName = VIEW_BY_JOB_LABEL;
// enforce a state update for swimlaneViewByFieldName
this.setState({ swimlaneViewByFieldName: VIEW_BY_JOB_LABEL }, () => {
this.updateExplorer(stateUpdate, true);
Copy link
Member

Choose a reason for hiding this comment

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

inconsistency nitpick - you're using stateUpdate which has been updated with Object.assign here, but a few lines down are creating the object on the fly using the spread operator.
Looks to me like either could be used, it would be good to be consistent. I'm pretty sure kibana's style guide used to have a rule about not using Object.assign but i can't find it anymore.

const { dateFormatTz } = this.props;
const { selectedCells, swimlaneViewByFieldName, selectedJobs } = this.state;
this.setState({
tableData: await loadAnomaliesTableData(
Copy link
Member

Choose a reason for hiding this comment

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

nit, IMO this would read better if you created a tableData variable just above the setState call.
Personal preferences and all that, so ignore if you disagree

state = getExplorerDefaultState();

// helper to avoid calling `setState()` in the listener for chart updates.
_isMounted = false;
Copy link
Member

Choose a reason for hiding this comment

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

the only variable to start with an underscore, is this to designate its insignificance?

this.dragSelect.setSelectables(document.getElementsByClassName('sl-cell'));
};

componentDidMount() {
Copy link
Member

Choose a reason for hiding this comment

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

nit, i would normally expect to see the componentDidMount function towards the top of the class

x-pack/plugins/ml/public/explorer/explorer.js Show resolved Hide resolved

const currentSwimlaneType = _.get(this.state, 'selectedCells.type');
const currentShowTopFieldValues = _.get(this.state, 'selectedCells.showTopFieldValues', false);
const newSwimlaneType = _.get(swimlaneSelectedCells, 'type');
Copy link
Member

Choose a reason for hiding this comment

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

nit, this could just be swimlaneSelectedCells.type

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@alvarezmelissa87 alvarezmelissa87 left a comment

Choose a reason for hiding this comment

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

LGTM ⚡️

@walterra walterra merged commit 735cc82 into elastic:master Jan 24, 2019
@walterra walterra deleted the ml-explorer-controller-refactor branch January 24, 2019 08:08
walterra added a commit to walterra/kibana that referenced this pull request Jan 24, 2019
Refactores the application logic of Anomaly Explorer to reduce relying on angularjs.
walterra added a commit that referenced this pull request Jan 24, 2019
Refactores the application logic of Anomaly Explorer to reduce relying on angularjs.
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

walterra added a commit to walterra/kibana that referenced this pull request Feb 8, 2019
This was missed during the recent migrations to React of Anomaly Explorer in elastic#28750. It removes the now unnecessary `$scope.indexPatterns`.
walterra added a commit that referenced this pull request Feb 8, 2019
This was missed during the recent migrations to React of Anomaly Explorer in #28750. It removes the now unnecessary `$scope.indexPatterns`.
walterra added a commit to walterra/kibana that referenced this pull request Feb 8, 2019
This was missed during the recent migrations to React of Anomaly Explorer in elastic#28750. It removes the now unnecessary `$scope.indexPatterns`.
walterra added a commit to walterra/kibana that referenced this pull request Feb 8, 2019
This was missed during the recent migrations to React of Anomaly Explorer in elastic#28750. It removes the now unnecessary `$scope.indexPatterns`.
lukeelmers pushed a commit to lukeelmers/kibana that referenced this pull request Feb 8, 2019
This was missed during the recent migrations to React of Anomaly Explorer in elastic#28750. It removes the now unnecessary `$scope.indexPatterns`.
peteharverson pushed a commit that referenced this pull request Feb 12, 2019
This was missed during the recent migrations to React of Anomaly Explorer in #28750. It removes the now unnecessary `$scope.indexPatterns`.
peteharverson pushed a commit that referenced this pull request Feb 13, 2019
This was missed during the recent migrations to React of Anomaly Explorer in #28750. It removes the now unnecessary `$scope.indexPatterns`.
@sophiec20 sophiec20 added the Feature:Anomaly Detection ML anomaly detection label Jun 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Anomaly Detection ML anomaly detection Feature:ml-results legacy - do not use :ml non-issue Indicates to automation that a pull request should not appear in the release notes refactoring v6.7.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants