Skip to content

Commit

Permalink
fix(@embark/core): Prevent unnecessary re-renderings
Browse files Browse the repository at this point in the history
The services websocket was initiated in the AppContainer and causing all child components to continuously re-render every time there was a service check (which is effectively every second). In addition, the socket was never stopped when not needed (ie when the services component was unmounted).

Create a ServicesContainer that initiates the websocket as part of the container, and stops the socket when the container is unmounted.

Move the ContractsList to be part of the ContractsContainer with a `mode` switch.

Add Deployment page title and description.
  • Loading branch information
emizzle authored and iurimatias committed Mar 11, 2019
1 parent cc495c5 commit 128ecd4
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 47 deletions.
14 changes: 14 additions & 0 deletions packages/embark-ui/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,13 @@ export const WATCH_SERVICES = 'WATCH_SERVICES';
export const WATCH_NEW_CONTRACT_LOGS = 'WATCH_NEW_CONTRACT_LOGS';
export const WATCH_NEW_CONTRACT_EVENTS = 'WATCH_NEW_CONTRACT_EVENTS';
export const WATCH_CONTRACTS = 'WATCH_CONTRACTS';
export const STOP_CONTRACTS = 'STOP_CONTRACTS';
export const INIT_BLOCK_HEADER = 'INIT_BLOCK_HEADER';
export const STOP_BLOCK_HEADER = 'STOP_BLOCK_HEADER';
export const WATCH_GAS_ORACLE = 'WATCH_GAS_ORACLE';
export const STOP_GAS_ORACLE = 'STOP_GAS_ORACLE';
export const STOP_DEBUGGER = 'STOP_DEBUGGER';
export const STOP_SERVICES = 'STOP_SERVICES';

export function listenToProcessLogs(processName) {
return {
Expand Down Expand Up @@ -509,12 +511,24 @@ export function listenToContracts(){
};
}

export function stopContracts(){
return {
type: STOP_CONTRACTS
};
}

export function stopGasOracle(){
return {
type: STOP_GAS_ORACLE
};
}

export function stopServices(){
return {
type: STOP_SERVICES
};
}

export function stopDebugger(){
return {
type: STOP_DEBUGGER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,26 @@ function iconClasses(state){
});
}

const Process = ({process}) => (
const Service = ({service}) => (
<Col xs={12} sm={6} md={4} xl={3}>
<Widget02 header={process.name} mainText={process.description} icon={iconClasses(process.state)} color={colorClasses(process.state)} variant="1" />
<Widget02 header={service.name} mainText={service.description} icon={iconClasses(service.state)} color={colorClasses(service.state)} variant="1" />
</Col>
);

Process.propTypes = {
process: PropTypes.object
Service.propTypes = {
service: PropTypes.object
};

const Processes = ({processes}) => (
const Services = ({services}) => (
<Row>
{processes
{services
.sort((a, b) => a.name < b.name ? 1 : 0)
.map((process) => <Process key={process.name} process={process} />)}
.map((service) => <Service key={service.name} service={service} />)}
</Row>
);

Processes.propTypes = {
processes: PropTypes.arrayOf(PropTypes.object)
Services.propTypes = {
services: PropTypes.arrayOf(PropTypes.object)
};

export default Processes;
export default Services;
14 changes: 1 addition & 13 deletions packages/embark-ui/src/containers/AppContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import {
processes as processesAction,
versions as versionsAction,
plugins as pluginsAction,
listenToServices as listenToServicesAction,
listenToContracts as listenToContractsAction,
initRegularTxs as initRegularTxsAction,
stopRegularTxs as stopRegularTxsAction,
changeTheme, fetchTheme
Expand Down Expand Up @@ -81,11 +79,8 @@ class AppContainer extends Component {
}

if (this.props.credentials.authenticated && !this.props.initialized) {
this.props.fetchProcesses();
this.props.fetchServices();
this.props.listenToServices();
this.props.fetchPlugins();
this.props.listenToContracts();
this.props.fetchProcesses();
if (enableRegularTxs === "true") {
this.props.initRegularTxs();
this.props.history.replace(stripQueryParam(this.props.location, ENABLE_REGULAR_TXS));
Expand Down Expand Up @@ -150,18 +145,14 @@ AppContainer.propTypes = {
authenticate: PropTypes.func,
logout: PropTypes.func,
fetchCredentials: PropTypes.func,
initBlockHeader: PropTypes.func,
fetchProcesses: PropTypes.func,
fetchServices: PropTypes.func,
fetchPlugins: PropTypes.func,
fetchVersions: PropTypes.func,
location: PropTypes.object,
theme: PropTypes.string,
changeTheme: PropTypes.func,
fetchTheme: PropTypes.func,
history: PropTypes.object,
listenToServices: PropTypes.func,
listenToContracts: PropTypes.func,
initRegularTxs: PropTypes.func,
stopRegularTxs: PropTypes.func
};
Expand All @@ -182,13 +173,10 @@ export default withRouter(connect(
logout: logout.request,
fetchCredentials: fetchCredentials.request,
fetchProcesses: processesAction.request,
fetchServices: processesAction.request,
listenToServices: listenToServicesAction,
fetchVersions: versionsAction.request,
fetchPlugins: pluginsAction.request,
changeTheme: changeTheme.request,
fetchTheme: fetchTheme.request,
listenToContracts: listenToContractsAction,
initRegularTxs: initRegularTxsAction.request,
stopRegularTxs: stopRegularTxsAction.request
},
Expand Down
34 changes: 28 additions & 6 deletions packages/embark-ui/src/containers/ContractsContainer.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import {contracts as contractsAction} from "../actions";
import {
listenToContracts as listenToContractsAction,
stopContracts as stopContractsAction,
contracts as contractsAction
} from "../actions";

import Contracts from '../components/Contracts';
import ContractsList from '../components/ContractsList';
import DataWrapper from "../components/DataWrapper";
import PageHead from "../components/PageHead";
import {getContracts} from "../reducers/selectors";

class ContractsContainer extends Component {
componentDidMount() {
this.props.fetchContracts();
this.props.listenToContracts();
}

componentWillUnmount() {
this.props.stopContracts();
}

render() {
return (
<React.Fragment>
<PageHead title="Contracts" description="Summary of all deployed contracts" />
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={({contracts}) => (
<Contracts contracts={contracts} />
)} />
{this.props.updatePageHeader && <PageHead title="Contracts" description="Summary of all deployed contracts" />}
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={({contracts}) => {
if (this.props.mode === "list") return <ContractsList contracts={contracts} />;
if (this.props.mode === "detail") return <Contracts contracts={contracts} />;
}} />
</React.Fragment>
);
}
Expand All @@ -33,13 +44,24 @@ function mapStateToProps(state) {
}

ContractsContainer.propTypes = {
listenToContracts: PropTypes.func,
stopContracts: PropTypes.func,
contracts: PropTypes.array,
fiddleContracts: PropTypes.array,
fetchContracts: PropTypes.func
fetchContracts: PropTypes.func,
mode: PropTypes.string,
updatePageHeader: PropTypes.bool
};

ContractsContainer.defaultProps = {
mode: "detail",
updatePageHeader: true
}

export default connect(
mapStateToProps,{
listenToContracts: listenToContractsAction,
stopContracts: stopContractsAction,
fetchContracts: contractsAction.request
}
)(ContractsContainer);
24 changes: 14 additions & 10 deletions packages/embark-ui/src/containers/DeploymentContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

import ContractsDeployment from '../components/ContractsDeployment';
import DataWrapper from "../components/DataWrapper";
import PageHead from '../components/PageHead';
import {getContracts, getDeploymentPipeline, getWeb3, getWeb3GasEstimates, getWeb3Deployments} from "../reducers/selectors";

class DeploymentContainer extends Component {
Expand All @@ -18,16 +19,19 @@ class DeploymentContainer extends Component {

render() {
return (
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={() => (
<ContractsDeployment contracts={this.props.contracts}
deploymentPipeline={this.props.deploymentPipeline}
web3={this.props.web3}
web3Deploy={this.props.web3Deploy}
web3EstimateGas={this.props.web3EstimateGas}
web3Deployments={this.props.web3Deployments}
web3GasEstimates={this.props.web3GasEstimates}
updateDeploymentPipeline={this.props.updateDeploymentPipeline} />
)} />
<React.Fragment>
<PageHead title="Deployment" description="Deploy your contracts using Embark or a web3-enabled browser such as Mist or MetaMask." />
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={() => (
<ContractsDeployment contracts={this.props.contracts}
deploymentPipeline={this.props.deploymentPipeline}
web3={this.props.web3}
web3Deploy={this.props.web3Deploy}
web3EstimateGas={this.props.web3EstimateGas}
web3Deployments={this.props.web3Deployments}
web3GasEstimates={this.props.web3GasEstimates}
updateDeploymentPipeline={this.props.updateDeploymentPipeline} />
)} />
</React.Fragment>
);
}
}
Expand Down
10 changes: 4 additions & 6 deletions packages/embark-ui/src/containers/HomeContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import {
} from "../actions";

import DataWrapper from "../components/DataWrapper";
import Processes from '../components/Processes';
import Console from '../components/Console';
import {EMBARK_PROCESS_NAME, LOG_LIMIT} from '../constants';
import ContractsList from '../components/ContractsList';
import PageHead from '../components/PageHead';
import ServicesContainer from './ServicesContainer';
import {getContracts, getProcesses, getProcessLogs, getServices, getCommandSuggestions} from "../reducers/selectors";
import ContractsContainer from "./ContractsContainer";

class HomeContainer extends Component {
constructor(props) {
Expand Down Expand Up @@ -53,9 +53,7 @@ class HomeContainer extends Component {
return (
<React.Fragment>
<PageHead title="Dashboard" description="Overview of available services and logs. Interact with Embark using the console. Summary of deployed contracts." />
<DataWrapper shouldRender={this.props.services.length > 0 } {...this.props} render={({services}) => (
<Processes processes={services} />
)} />
<ServicesContainer />

<DataWrapper shouldRender={this.props.processes.length > 0 } {...this.props} render={({processes, postCommand, postCommandSuggestions, processLogs, commandSuggestions}) => (
<Card>
Expand All @@ -78,7 +76,7 @@ class HomeContainer extends Component {
<CardBody>
<CardTitle>Deployed Contracts</CardTitle>
<div style={{marginBottom: '1.5rem', overflow: 'auto'}}>
<ContractsList contracts={contracts} />
<ContractsContainer contracts={contracts} mode="list" updatePageHeader={false} />
</div>
</CardBody>
</Card>
Expand Down
49 changes: 49 additions & 0 deletions packages/embark-ui/src/containers/ServicesContainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import PropTypes from "prop-types";
import React, {Component} from 'react';
import {connect} from 'react-redux';
import Services from '../components/Services';
import {
listenToServices as listenToServicesAction,
services as servicesAction,
stopServices as stopServicesAction
} from "../actions";
import DataWrapper from "../components/DataWrapper";
import {getServices} from "../reducers/selectors";

class ServicesContainer extends Component {
componentDidMount() {
this.props.fetchServices();
this.props.listenToServices();
}

componentWillUnmount() {
this.props.stopServices();
}

render() {
return <DataWrapper shouldRender={this.props.services.length > 0 } {...this.props} render={({services}) => (
<Services services={services} />
)} />;

}
}

ServicesContainer.propTypes = {
fetchServices: PropTypes.func,
listenToServices: PropTypes.func,
};

function mapStateToProps(state, _props) {
return {
services: getServices(state)
};
}

export default connect(
mapStateToProps,
{
fetchServices: servicesAction.request,
listenToServices: listenToServicesAction,
stopServices: stopServicesAction
}
)(ServicesContainer);
20 changes: 18 additions & 2 deletions packages/embark-ui/src/sagas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,15 @@ export function *listenServices() {
const socket = api.webSocketServices(credentials);
const channel = yield call(createChannel, socket);
while (true) {
const services = yield take(channel);
const { cancel, services } = yield race({
services: take(channel),
cancel: take(actions.STOP_SERVICES)
});

if (cancel) {
channel.close();
return;
}
yield put(actions.services.success(services));
}
}
Expand Down Expand Up @@ -506,7 +514,15 @@ export function *listenContracts() {
const socket = api.webSocketContracts(credentials);
const channel = yield call(createChannel, socket);
while (true) {
const contracts = yield take(channel);
const { cancel, contracts } = yield race({
contracts: take(channel),
cancel: take(actions.STOP_CONTRACTS)
});

if (cancel) {
channel.close();
return;
}
yield put(actions.contracts.success(contracts));
}
}
Expand Down

0 comments on commit 128ecd4

Please sign in to comment.