diff --git a/packages/cp-frontend/package.json b/packages/cp-frontend/package.json index efb4786b..a9e3a80d 100644 --- a/packages/cp-frontend/package.json +++ b/packages/cp-frontend/package.json @@ -35,6 +35,7 @@ "lodash.isstring": "^4.0.1", "lodash.remove": "^4.7.0", "lodash.uniq": "^4.5.0", + "lodash.uniqby": "^4.7.0", "normalized-styled-components": "^1.0.8", "param-case": "^2.1.1", "prop-types": "^15.5.10", diff --git a/packages/cp-frontend/src/containers/metrics/metrics-data-hoc.js b/packages/cp-frontend/src/containers/metrics/metrics-data-hoc.js index 81ece34d..048fcb6e 100644 --- a/packages/cp-frontend/src/containers/metrics/metrics-data-hoc.js +++ b/packages/cp-frontend/src/containers/metrics/metrics-data-hoc.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { compose, graphql } from 'react-apollo'; -import get from 'lodash.get'; import moment from 'moment'; +import uniqBy from 'lodash.uniqby'; export const MetricNames = [ 'AVG_MEM_BYTES', @@ -10,22 +10,17 @@ export const MetricNames = [ ]; export const withServiceMetricsPolling = ({ - pollingInterval = 1000 // in milliseconds + pollingInterval = 1000, // in milliseconds + getPreviousEnd = () => moment().utc().format() }) => { return WrappedComponent => { return class extends Component { componentDidMount() { this._poll = setInterval(() => { const { loading, error, service, fetchMoreMetrics } = this.props; + const previousEnd = getPreviousEnd(this.props); - if (!loading && !error && service) { - const previousEnd = get( - service, - 'instances[0].metrics[0].end', - moment() - .utc() - .format() - ); + if (previousEnd) { fetchMoreMetrics(previousEnd); } }, pollingInterval); // TODO this is the polling interval - think about amount is the todo I guess... @@ -63,7 +58,8 @@ export const withServiceMetricsGql = ({ const getNextResult = (previousResult, fetchNextResult) => { const deploymentGroup = fetchNextResult.deploymentGroup; - const nextResult = { + + return { deploymentGroup: { ...deploymentGroup, services: deploymentGroup.services.map(service => ({ @@ -72,18 +68,17 @@ export const withServiceMetricsGql = ({ ...instance, metrics: instance.metrics.map(metric => ({ ...metric, - metrics: getPreviousMetrics( + metrics: uniqBy(getPreviousMetrics( previousResult, service.id, instance.id, metric.name - ).concat(metric.metrics) + ).concat(metric.metrics), 'time') })) })) })) } }; - return nextResult; }; return graphql(gqlQuery, { diff --git a/packages/cp-frontend/src/containers/service/metrics.js b/packages/cp-frontend/src/containers/service/metrics.js index 2b1d2d22..06e1b029 100644 --- a/packages/cp-frontend/src/containers/service/metrics.js +++ b/packages/cp-frontend/src/containers/service/metrics.js @@ -70,6 +70,15 @@ export default compose( error }) }), - withServiceMetricsPolling({ pollingInterval: 1000 }), + withServiceMetricsPolling({ + pollingInterval: 1000, + getPreviousEnd: ({ loading, error, service = [] }) => { + if (loading) { + return false; + } + + return get(service, 'instances[0].metrics[0].end', moment().utc().format()); + } + }), withNotFound([GqlPaths.DEPLOYMENT_GROUP, GqlPaths.SERVICES]) )(ServiceMetrics); diff --git a/packages/cp-frontend/src/containers/services/list.js b/packages/cp-frontend/src/containers/services/list.js index 8e248024..1f18a4dc 100644 --- a/packages/cp-frontend/src/containers/services/list.js +++ b/packages/cp-frontend/src/containers/services/list.js @@ -5,13 +5,10 @@ import { connect } from 'react-redux'; import styled from 'styled-components'; import forceArray from 'force-array'; import sortBy from 'lodash.sortby'; +import get from 'lodash.get'; +import moment from 'moment'; import ServicesQuery from '@graphql/Services.gql'; - -import { - processServices, - processInstancesMetrics -} from '@root/state/selectors'; import { toggleServicesQuickActions } from '@root/state/actions'; import { withNotFound, GqlPaths } from '@containers/navigation'; import { LayoutContainer } from '@components/layout'; @@ -23,6 +20,11 @@ import { withServiceMetricsGql } from '@containers/metrics'; +import { + processServices, + processInstancesMetrics +} from '@root/state/selectors'; + // 'width' of graph, i.e. total duration of time it'll display and truncate data to // amount of data we'll need to initially fetch const GraphDurationSeconds = 90; @@ -182,7 +184,21 @@ export default compose( error }) }), - withServiceMetricsPolling({ pollingInterval: 1000 }), + withServiceMetricsPolling({ + pollingInterval: 1000, + getPreviousEnd: ({ loading, error, services = [] }) => { + if (loading) { + return false; + } + + const previousEnd = services + .map(service => get(service, 'instances[0].metrics[0].end', null)) + .filter(Boolean) + .shift(); + + return previousEnd || moment().utc().format(); + } + }), UiConnect, withNotFound([GqlPaths.DEPLOYMENT_GROUP]) )(ServiceList);