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

UI Performance Updates #1976

Merged
merged 6 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class SingularityConfiguration extends Configuration {

private long cacheDeploysForMillis = TimeUnit.DAYS.toMillis(5);

private long cacheStateForMillis = TimeUnit.SECONDS.toMillis(30);
private long cacheStateForMillis = TimeUnit.SECONDS.toMillis(60);

private long checkDeploysEverySeconds = 5;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
Expand Down Expand Up @@ -459,14 +458,9 @@ public List<SingularityTask> getActiveTasks(boolean useWebCache) {
return webCache.getActiveTasks();
}

List<String> children = Lists.transform(getActiveTaskIds(), new Function<SingularityTaskId, String>() {

@Override
public String apply(SingularityTaskId taskId) {
return getTaskPath(taskId);
}

});
List<String> children = getActiveTaskIds().stream()
.map(this::getTaskPath)
.collect(Collectors.toList());

List<SingularityTask> activeTasks = getAsync("getActiveTasks", children, taskTranscoder, taskCache);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,16 @@ public List<SingularityTask> getActiveTasks(
return authorizationHelper.filterByAuthorizedRequests(user, taskManager.getActiveTasks(useWebCache(useWebCache)), SingularityTransformHelpers.TASK_TO_REQUEST_ID, SingularityAuthorizationScope.READ);
}

@GET
@PropertyFiltering
@Path("/active/ids")
@Operation(summary = "Retrieve the list of active task ids for all requests")
public List<SingularityTaskId> getActiveTaskIds(
@Parameter(hidden = true) @Auth SingularityUser user,
@Parameter(description = "Use the cached version of this data to limit expensive api calls") @QueryParam("useWebCache") Boolean useWebCache) {
return authorizationHelper.filterByAuthorizedRequests(user, taskManager.getActiveTaskIds(), SingularityTransformHelpers.TASK_ID_TO_REQUEST_ID, SingularityAuthorizationScope.READ);
}

@GET
@PropertyFiltering
@Path("/cleaning")
Expand Down
16 changes: 11 additions & 5 deletions SingularityUI/app/actions/api/tasks.es6
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@ import { buildApiAction, buildJsonApiAction } from './base';

export const FetchTasksInState = buildApiAction(
'FETCH_TASKS',
(state, renderNotFoundIf404) => {
(state, renderNotFoundIf404, showResources) => {
const stateToFetch = state !== 'decommissioning' ? state : 'active';

let ids = ""
let propertyString = '?property=';
const propertyJoin = '&property=';

switch (stateToFetch) {
case 'active':
propertyString += ['offers', 'taskId', 'mesosTask.resources', 'rackId', 'taskRequest.request.requestType'].join(propertyJoin);
if (showResources) {
propertyString += ['offers', 'taskId', 'mesosTask.resources', 'rackId', 'taskRequest.request.requestType'].join(propertyJoin);
} else {
ids = "/ids"
propertyString = '';
}
break;
case 'scheduled':
propertyString += ['offers', 'taskId', 'mesosTask.resources', 'rackId', 'taskRequest.request.requestType', 'pendingTask'].join(propertyJoin);
ids = "/ids"
propertyString = '';
break;
default:
propertyString = '';
}

return {
url: `/tasks/${stateToFetch}${propertyString}`,
url: `/tasks/${stateToFetch}${ids}${propertyString}`,
renderNotFoundIf404
};
}
Expand Down
4 changes: 2 additions & 2 deletions SingularityUI/app/actions/ui/tasks.es6
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FetchTasksInState, FetchTaskCleanups } from '../../actions/api/tasks';

export const refresh = (state) => (dispatch) =>
export const refresh = (state, showResources) => (dispatch) =>
Promise.all([
dispatch(FetchTasksInState.trigger(state || 'active', true)),
dispatch(FetchTasksInState.trigger(state || 'active', true, showResources)),
dispatch(FetchTaskCleanups.trigger()),
]);
3 changes: 2 additions & 1 deletion SingularityUI/app/components/common/Application.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Title from './Title';
import Utils from '../../utils';

const DISMISS_TASK_LAG_NOFICATION_DURATION_IN_MS = 1000 * 60 * 60;
const MAX_LATE_REQUESTS = 10;
const MAX_LATE_REQUESTS = 20;

class Application extends Component {
constructor(props) {
Expand Down Expand Up @@ -47,6 +47,7 @@ class Application extends Component {
Singularity is experiencing some delays. The team has already been
notified.
`,
hideAfter: 5,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const mapStateToProps = (state, ownProps) => {
}};

const mapDispatchToProps = (dispatch, ownProps) => ({
fetchTaskHistoryForRequest: () => dispatch(FetchTaskHistoryForRequest.trigger(ownProps.requestId, ownProps.taskHistoryPage, ownProps.taskHistoryPageSize))
fetchTaskHistoryForRequest: () => dispatch(FetchTaskHistoryForRequest.trigger(ownProps.requestId, ownProps.taskHistoryPageSize, ownProps.taskHistoryPage))
});

export default connect(
Expand Down
56 changes: 18 additions & 38 deletions SingularityUI/app/components/tasks/Columns.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export const NextRun = (
id="nextRun"
key="nextRun"
cellData={
(rowData) => rowData.pendingTask.pendingTaskId.nextRunAt
(rowData) => rowData.nextRunAt
}
cellRender={(cellData) => {
let label = <span className={`label label-${Utils.getLabelClassFromTaskState('TASK_SCHEDULED')}`}>SCHEDULED</span>;
Expand All @@ -257,7 +257,7 @@ export const PendingType = (
id="pendingType"
key="pendingType"
cellData={
(rowData) => rowData.pendingTask.pendingTaskId.pendingType
(rowData) => rowData.pendingType
}
cellRender={(cellData) => (
<div>
Expand All @@ -283,55 +283,35 @@ export const DeployId = (
/>
);

export const PendingDeployId = (
export const RequestId = (
<Column
label="Deploy ID"
id="pendingDeployId"
key="pendingDeployId"
label="Request ID"
id="requestId"
key="requestId"
cellData={
(rowData) => rowData.pendingTask.pendingTaskId
(rowData) => rowData
}
sortData={(cellData) => cellData.deployId}
sortData={(cellData) => cellData.requestId}
cellRender={(cellData) =>
<Link to={`request/${cellData.requestId}/deploy/${cellData.deployId}`}>{cellData.deployId}</Link>
<Link to={`request/${cellData.requestId}`}>{cellData.requestId}</Link>
}
sortable={true}
/>
);

export const ScheduledActions = (
<Column
label=""
id="actions"
key="actions"
className="actions-column"
cellRender={(cellData) => (
<div className="hidden-xs">
<RunNowButton requestId={cellData.pendingTask.pendingTaskId.requestId} />
{cellData.request && cellData.request.requestType == "ON_DEMAND" &&
<DeletePendingTaskButton
taskId={cellData.pendingTask.pendingTaskId.id}
requestType={cellData.request.requestType}
/>
}
<JSONButton className="inline" object={cellData} showOverlay={true}>
{'{ }'}
</JSONButton>
</div>
)}
/>
);

export const ScheduledTaskId = (
export const PendingDeployId = (
<Column
label="Task ID"
id="taskId"
key="taskId"
label="Deploy ID"
id="pendingDeployId"
key="pendingDeployId"
cellData={
(rowData) => rowData.pendingTask.pendingTaskId.id
(rowData) => rowData
}
sortData={(cellData) => cellData.deployId}
cellRender={(cellData) =>
<Link to={`request/${cellData.requestId}/deploy/${cellData.deployId}`}>{cellData.deployId}</Link>
}
sortable={true}
className="keep-in-check"
/>
);

Expand Down
28 changes: 27 additions & 1 deletion SingularityUI/app/components/tasks/TaskFilters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ export default class TaskFilters extends React.Component {
this.props.onFilterChange(_.extend({}, this.props.filter, {requestTypes: selected}));
}

toggleShowResources(active) {
this.props.onFilterChange(_.extend({}, this.props.filter, {showResources: active}));
}

renderStatusFilter() {
const selectedIndex = _.findIndex(TaskFilters.TASK_STATES, (taskState) => taskState.filterVal === this.props.filter.taskStatus);
const navItems = TaskFilters.TASK_STATES.map((taskState, index) => {
Expand Down Expand Up @@ -106,6 +110,9 @@ export default class TaskFilters extends React.Component {
}

renderRequestTypeFilter() {
if (!this.props.filter.showResources) {
return null;
}
const filterItems = this.props.displayRequestTypeFilters && TaskFilters.REQUEST_TYPES.map((requestType, index) => {
const isActive = _.contains(this.props.filter.requestTypes, requestType);
return (
Expand All @@ -126,6 +133,21 @@ export default class TaskFilters extends React.Component {
);
}

renderShowResourcesToggle() {
const isActive = this.props.filter.showResources;
return this.props.displayRequestTypeFilters && (
<div className="requests-filter-container pull-right">
<ul className="nav nav-pills nav-pills-multi-select">
<li key='show-resources' className={isActive ? 'active' : ''}>
<a onClick={() => this.toggleShowResources(!isActive)}>
{isActive ? <Glyphicon glyph="ok" /> : <span className="icon-placeholder" />} Show Resources
</a>
</li>
</ul>
</div>
);
}

render() {
return (
<div>
Expand All @@ -138,9 +160,12 @@ export default class TaskFilters extends React.Component {
<div className="col-md-12">
{this.renderSearchInput()}
</div>
<div className="col-md-12">
<div className="col-md-9">
{this.renderRequestTypeFilter()}
</div>
<div className="col-md-3">
{this.renderShowResourcesToggle()}
</div>
</div>
</div>
);
Expand All @@ -150,6 +175,7 @@ export default class TaskFilters extends React.Component {
TaskFilters.propTypes = {
onFilterChange: React.PropTypes.func.isRequired,
filter: React.PropTypes.shape({
showResources: React.PropTypes.bool.isRequired,
taskStatus: React.PropTypes.string.isRequired,
requestTypes: React.PropTypes.array.isRequired,
filterText: React.PropTypes.string.isRequired
Expand Down
Loading