Skip to content

Commit c71912b

Browse files
authored
Do more requests in parallel. (#8895)
* Do more requests in parallel. * Start fetching the pushes before the /api/repository/ request returns the data needed to render the PushList component.
1 parent a49bdba commit c71912b

File tree

5 files changed

+36
-12
lines changed

5 files changed

+36
-12
lines changed

ui/job-view/App.jsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import DetailsPanel from './details/DetailsPanel';
3434
import PushList from './pushes/PushList';
3535
import KeyboardShortcuts from './KeyboardShortcuts';
3636
import { clearExpiredNotifications } from './redux/stores/notifications';
37+
import { fetchPushes } from './redux/stores/pushes';
3738

3839
import '../css/treeherder.css';
3940
import '../css/treeherder-navbar-panels.css';
@@ -107,13 +108,15 @@ class App extends React.Component {
107108

108109
async componentDidMount() {
109110
const { repoName, landoCommitID } = this.state;
111+
const { fetchPushes } = this.props;
112+
113+
// Start all API requests in parallel - including pushes.
110114
getData(getApiUrl(endpoints.frameworks)).then((response) =>
111115
this.setState({ frameworks: response.data }),
112116
);
113117

114118
RepositoryModel.getList().then((repos) => {
115119
const newRepo = repos.find((repo) => repo.name === repoName);
116-
117120
this.setState({ currentRepo: newRepo, repos });
118121
});
119122

@@ -124,6 +127,10 @@ class App extends React.Component {
124127
});
125128
});
126129

130+
// Start (pre)fetching pushes immediately. The PushList component needs
131+
// currentRepo but it is not needed to start the network request.
132+
fetchPushes();
133+
127134
window.addEventListener('resize', this.updateDimensions, false);
128135
window.addEventListener('storage', this.handleStorageEvent);
129136
window.addEventListener(thEvents.filtersUpdated, this.handleFiltersUpdated);
@@ -498,6 +505,7 @@ App.propTypes = {
498505
jobMap: PropTypes.shape({}).isRequired,
499506
router: PropTypes.shape({}).isRequired,
500507
pushRoute: PropTypes.func.isRequired,
508+
fetchPushes: PropTypes.func.isRequired,
501509
};
502510

503511
const mapStateToProps = ({ pushes: { jobMap }, router }) => ({
@@ -508,4 +516,5 @@ const mapStateToProps = ({ pushes: { jobMap }, router }) => ({
508516
export default connect(mapStateToProps, {
509517
pushRoute,
510518
clearExpiredNotifications,
519+
fetchPushes,
511520
})(hot(App));

ui/job-view/pushes/Push.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,18 @@ class Push extends React.PureComponent {
117117
// this allows someone to more quickly load ranges of revisions
118118
// when they don't care about the specific jobs and results.
119119
const allParams = getAllUrlParams();
120+
const promises = [];
121+
120122
if (!allParams.has('nojobs')) {
121-
await this.fetchJobs();
123+
promises.push(this.fetchJobs());
122124
}
123125
if (allParams.has('test_paths')) {
124-
await this.fetchTestManifests();
126+
promises.push(this.fetchTestManifests());
125127
}
126128

129+
// Execute jobs and test manifests in parallel
130+
await Promise.all(promises);
131+
127132
this.testForFilteredTry();
128133

129134
window.addEventListener(thEvents.applyNewJobs, this.handleApplyNewJobs);

ui/job-view/pushes/PushList.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class PushList extends React.Component {
3131
componentDidMount() {
3232
const { fetchPushes } = this.props;
3333

34+
// Fetch pushes regardless of whether App started the request,
35+
// the Redux action will handle deduplication if needed.
3436
fetchPushes();
3537
this.poll();
3638
}

ui/job-view/redux/stores/pushes.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,15 @@ export const fetchPushes = (
248248
) => {
249249
return async (dispatch, getState) => {
250250
const {
251-
pushes: { pushList, jobMap, oldestPushTimestamp },
251+
pushes: { pushList, jobMap, oldestPushTimestamp, loadingPushes },
252252
router,
253253
} = getState();
254254

255+
// Prevent duplicate requests when already loading initial data.
256+
if (loadingPushes && !setFromchange) {
257+
return;
258+
}
259+
255260
dispatch({ type: LOADING });
256261

257262
const locationSearch = parseQueryParams(window.location.search);
@@ -423,7 +428,7 @@ export const initialState = {
423428
decisionTaskMap: {},
424429
revisionTips: [],
425430
jobsLoaded: false,
426-
loadingPushes: true,
431+
loadingPushes: false,
427432
oldestPushTimestamp: null,
428433
allUnclassifiedFailureCount: 0,
429434
filteredUnclassifiedFailureCount: 0,

ui/shared/PushHealthStatus.jsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,22 @@ class PushHealthStatus extends Component {
2222
}
2323

2424
async componentDidMount() {
25-
const {
26-
jobCounts: { completed },
27-
} = this.props;
28-
29-
if (completed > 0) {
30-
await this.loadLatestStatus();
31-
}
25+
// Load health status immediately without waiting for job completion
26+
await this.loadLatestStatus();
3227
}
3328

3429
async componentDidUpdate(prevProps) {
3530
const { jobCounts } = this.props;
3631
const fields = ['completed', 'fixedByCommit', 'pending', 'running'];
3732

33+
// Skip if this is the initial load (all previous counts were zero)
34+
const isInitialLoad = !fields.some(
35+
(field) => prevProps.jobCounts[field] > 0,
36+
);
37+
if (isInitialLoad) {
38+
return;
39+
}
40+
3841
if (didObjectsChange(jobCounts, prevProps.jobCounts, fields)) {
3942
await this.loadLatestStatus();
4043
}

0 commit comments

Comments
 (0)