Skip to content

Commit

Permalink
Move OBJ requests to OBJ Landing instead of App
Browse files Browse the repository at this point in the history
App.tsx fetches `profile`, which is now used to determine if OBJ is enabled. We used to request buckets and clusters on initial App load, but now we need to wait for the profile response.

I could have:
1) Implemented getProfile().then(() => getEverythingElse()) sort of logic.
2) Added CDU logic to App.tsx to check if profile has been loaded, THEN maybe do OBJ requests.
3) Move OBJ requests to ObjectStorageLanding.

I opted for #3, because the first two options resulted in a performance hit for all users.

We could move these requests back to App.tsx once OBJ is generally available.
  • Loading branch information
johnwcallahan committed May 16, 2019
1 parent df40ff9 commit f4a6931
Showing 3 changed files with 73 additions and 16 deletions.
9 changes: 1 addition & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -207,8 +207,7 @@ export class App extends React.Component<CombinedProps, State> {
async componentDidMount() {
const {
actions,
nodeBalancerActions: { getAllNodeBalancersWithConfigs },
betaPrograms
nodeBalancerActions: { getAllNodeBalancersWithConfigs }
} = this.props;

const dataFetchingPromises: Promise<any>[] = [
@@ -224,12 +223,6 @@ export class App extends React.Component<CombinedProps, State> {
getAllNodeBalancersWithConfigs()
];

// Make these requests only if the feature is enabled.
if (isObjectStorageEnabled(betaPrograms)) {
dataFetchingPromises.push(actions.requestBuckets());
dataFetchingPromises.push(actions.requestClusters());
}

try {
await Promise.all(dataFetchingPromises);
} catch (error) {
77 changes: 70 additions & 7 deletions src/features/ObjectStorage/ObjectStorageLanding.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import * as React from 'react';
import { connect, MapDispatchToProps } from 'react-redux';
import {
matchPath,
Route,
RouteComponentProps,
Switch,
withRouter
} from 'react-router-dom';
import { compose } from 'recompose';
import { Action } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import AppBar from 'src/components/core/AppBar';
import Tab from 'src/components/core/Tab';
import Tabs from 'src/components/core/Tabs';
import Typography from 'src/components/core/Typography';
import { DocumentTitleSegment } from 'src/components/DocumentTitle';
import TabLink from 'src/components/TabLink';
import { ApplicationState } from 'src/store';
import { getAllBuckets } from 'src/store/bucket/bucket.requests';
import { requestClusters as _requestClusters } from 'src/store/clusters/clusters.actions';
import { MapState } from 'src/store/types';
import AccessKeyLanding from './AccessKeys/AccessKeyLanding';
import BucketLanding from './Buckets/BucketLanding';

type Props = RouteComponentProps<{}>;

export const ObjectStorageLanding: React.StatelessComponent<Props> = props => {
const { match } = props;
type CombinedProps = StateProps & DispatchProps & RouteComponentProps<{}>;

export const ObjectStorageLanding: React.FunctionComponent<
CombinedProps
> = props => {
const tabs = [
/* NB: These must correspond to the routes inside the Switch */
{ title: 'Buckets', routeName: `${match.url}/buckets` },
{ title: 'Access Keys', routeName: `${match.url}/access-keys` }
{ title: 'Buckets', routeName: `${props.match.url}/buckets` },
{ title: 'Access Keys', routeName: `${props.match.url}/access-keys` }
];

const handleTabChange = (
@@ -35,6 +43,28 @@ export const ObjectStorageLanding: React.StatelessComponent<Props> = props => {
history.push(`${routeName}`);
};

React.useEffect(() => {
const {
bucketsLastUpdated,
clustersLastUpdated,
requestBuckets,
requestClusters
} = props;

// When OBJ is generally available, consider moving
// these requests to App.tsx like other entities.

// Request buckets if we haven't already
if (bucketsLastUpdated === 0) {
requestBuckets();
}

// Request clusters if we haven't already
if (clustersLastUpdated === 0) {
requestClusters();
}
}, []);

const {
match: { url }
} = props;
@@ -75,4 +105,37 @@ export const ObjectStorageLanding: React.StatelessComponent<Props> = props => {
);
};

export default withRouter(ObjectStorageLanding);
interface StateProps {
bucketsLastUpdated: number;
clustersLastUpdated: number;
}

const mapStateToProps: MapState<StateProps, {}> = state => ({
bucketsLastUpdated: state.__resources.buckets.lastUpdated,
clustersLastUpdated: state.__resources.clusters.lastUpdated
});

interface DispatchProps {
requestBuckets: () => Promise<Linode.Bucket[]>;
requestClusters: () => Promise<Linode.Cluster[]>;
}

const mapDispatchToProps: MapDispatchToProps<DispatchProps, {}> = (
dispatch: ThunkDispatch<ApplicationState, undefined, Action<any>>
) => {
return {
requestBuckets: () => dispatch(getAllBuckets()),
requestClusters: () => dispatch(_requestClusters())
};
};

export const connected = connect(
mapStateToProps,
mapDispatchToProps
);

const enhanced = compose<CombinedProps, {}>(
connected,
withRouter
);
export default enhanced(ObjectStorageLanding);
3 changes: 2 additions & 1 deletion src/store/clusters/clusters.reducer.ts
Original file line number Diff line number Diff line change
@@ -35,7 +35,8 @@ const reducer: Reducer<State> = (state = defaultState, action) => {
loading: false,
lastUpdated: Date.now(),
entities: result,
results: result.map(r => r.id)
results: result.map(r => r.id),
error: undefined
};
}

0 comments on commit f4a6931

Please sign in to comment.