Add run-all dead tasks action button to DeadTasksTable

This commit is contained in:
Ken Hibino 2020-12-17 06:57:30 -08:00
parent 4d5de30a57
commit bf81787115
6 changed files with 104 additions and 13 deletions

View File

@ -19,6 +19,7 @@ import {
listScheduledTasks, listScheduledTasks,
ListScheduledTasksResponse, ListScheduledTasksResponse,
PaginationOptions, PaginationOptions,
runAllDeadTasks,
runDeadTask, runDeadTask,
} from "../api"; } from "../api";
import { Dispatch } from "redux"; import { Dispatch } from "redux";
@ -61,6 +62,9 @@ export const BATCH_DELETE_DEAD_TASKS_BEGIN = "BATCH_DELETE_DEAD_TASKS_BEGIN";
export const BATCH_DELETE_DEAD_TASKS_SUCCESS = export const BATCH_DELETE_DEAD_TASKS_SUCCESS =
"BATCH_DELETE_DEAD_TASKS_SUCCESS"; "BATCH_DELETE_DEAD_TASKS_SUCCESS";
export const BATCH_DELETE_DEAD_TASKS_ERROR = "BATCH_DELETE_DEAD_TASKS_ERROR"; export const BATCH_DELETE_DEAD_TASKS_ERROR = "BATCH_DELETE_DEAD_TASKS_ERROR";
export const RUN_ALL_DEAD_TASKS_BEGIN = "RUN_ALL_DEAD_TASKS_BEGIN";
export const RUN_ALL_DEAD_TASKS_SUCCESS = "RUN_ALL_DEAD_TASKS_SUCCESS";
export const RUN_ALL_DEAD_TASKS_ERROR = "RUN_ALL_DEAD_TASKS_ERROR";
export const DELETE_ALL_DEAD_TASKS_BEGIN = "DELETE_ALL_DEAD_TASKS_BEGIN"; export const DELETE_ALL_DEAD_TASKS_BEGIN = "DELETE_ALL_DEAD_TASKS_BEGIN";
export const DELETE_ALL_DEAD_TASKS_SUCCESS = "DELETE_ALL_DEAD_TASKS_SUCCESS"; export const DELETE_ALL_DEAD_TASKS_SUCCESS = "DELETE_ALL_DEAD_TASKS_SUCCESS";
export const DELETE_ALL_DEAD_TASKS_ERROR = "DELETE_ALL_DEAD_TASKS_ERROR"; export const DELETE_ALL_DEAD_TASKS_ERROR = "DELETE_ALL_DEAD_TASKS_ERROR";
@ -283,6 +287,22 @@ interface BatchRunDeadTasksErrorAction {
error: string; error: string;
} }
interface RunAllDeadTasksBeginAction {
type: typeof RUN_ALL_DEAD_TASKS_BEGIN;
queue: string;
}
interface RunAllDeadTasksSuccessAction {
type: typeof RUN_ALL_DEAD_TASKS_SUCCESS;
queue: string;
}
interface RunAllDeadTasksErrorAction {
type: typeof RUN_ALL_DEAD_TASKS_ERROR;
queue: string;
error: string;
}
interface DeleteAllDeadTasksBeginAction { interface DeleteAllDeadTasksBeginAction {
type: typeof DELETE_ALL_DEAD_TASKS_BEGIN; type: typeof DELETE_ALL_DEAD_TASKS_BEGIN;
queue: string; queue: string;
@ -337,6 +357,9 @@ export type TasksActionTypes =
| BatchRunDeadTasksBeginAction | BatchRunDeadTasksBeginAction
| BatchRunDeadTasksSuccessAction | BatchRunDeadTasksSuccessAction
| BatchRunDeadTasksErrorAction | BatchRunDeadTasksErrorAction
| RunAllDeadTasksBeginAction
| RunAllDeadTasksSuccessAction
| RunAllDeadTasksErrorAction
| DeleteAllDeadTasksBeginAction | DeleteAllDeadTasksBeginAction
| DeleteAllDeadTasksSuccessAction | DeleteAllDeadTasksSuccessAction
| DeleteAllDeadTasksErrorAction; | DeleteAllDeadTasksErrorAction;
@ -605,3 +628,20 @@ export function deleteAllDeadTasksAsync(queue: string) {
} }
}; };
} }
export function runAllDeadTasksAsync(queue: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: RUN_ALL_DEAD_TASKS_BEGIN, queue });
try {
await runAllDeadTasks(queue);
dispatch({ type: RUN_ALL_DEAD_TASKS_SUCCESS, queue });
} catch (error) {
console.error("runAllDeadTasksAsync: ", error);
dispatch({
type: RUN_ALL_DEAD_TASKS_ERROR,
error: `Could not run all dead tasks`,
queue,
});
}
};
}

View File

@ -328,6 +328,13 @@ export async function batchRunDeadTasks(
return resp.data; return resp.data;
} }
export async function runAllDeadTasks(qname: string): Promise<void> {
await axios({
method: "post",
url: `${BASE_URL}/queues/${qname}/dead_tasks:run_all`,
});
}
export async function listSchedulerEntries(): Promise<ListSchedulerEntriesResponse> { export async function listSchedulerEntries(): Promise<ListSchedulerEntriesResponse> {
const resp = await axios({ const resp = await axios({
method: "get", method: "get",

View File

@ -34,6 +34,7 @@ import {
deleteAllDeadTasksAsync, deleteAllDeadTasksAsync,
listDeadTasksAsync, listDeadTasksAsync,
runDeadTaskAsync, runDeadTaskAsync,
runAllDeadTasksAsync,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
import TablePaginationActions, { import TablePaginationActions, {
defaultPageSize, defaultPageSize,
@ -68,7 +69,7 @@ function mapStateToProps(state: AppState) {
loading: state.tasks.deadTasks.loading, loading: state.tasks.deadTasks.loading,
tasks: state.tasks.deadTasks.data, tasks: state.tasks.deadTasks.data,
batchActionPending: state.tasks.deadTasks.batchActionPending, batchActionPending: state.tasks.deadTasks.batchActionPending,
deleteAllRequestPending: state.tasks.deadTasks.deleteAllRequestPending, allActionPending: state.tasks.deadTasks.allActionPending,
pollInterval: state.settings.pollInterval, pollInterval: state.settings.pollInterval,
}; };
} }
@ -76,6 +77,7 @@ function mapStateToProps(state: AppState) {
const mapDispatchToProps = { const mapDispatchToProps = {
listDeadTasksAsync, listDeadTasksAsync,
runDeadTaskAsync, runDeadTaskAsync,
runAllDeadTasksAsync,
deleteDeadTaskAsync, deleteDeadTaskAsync,
deleteAllDeadTasksAsync, deleteAllDeadTasksAsync,
batchRunDeadTasksAsync, batchRunDeadTasksAsync,
@ -128,6 +130,11 @@ function DeadTasksTable(props: Props & ReduxProps) {
const handleMenuClose = () => setMenuAnchor(null); const handleMenuClose = () => setMenuAnchor(null);
const handleRunAllClick = () => {
props.runAllDeadTasksAsync(queue);
setMenuAnchor(null);
};
const handleDeleteAllClick = () => { const handleDeleteAllClick = () => {
props.deleteAllDeadTasksAsync(queue); props.deleteAllDeadTasksAsync(queue);
setMenuAnchor(null); setMenuAnchor(null);
@ -177,10 +184,15 @@ function DeadTasksTable(props: Props & ReduxProps) {
open={Boolean(menuAnchor)} open={Boolean(menuAnchor)}
onClose={handleMenuClose} onClose={handleMenuClose}
> >
<MenuItem onClick={handleMenuClose}>Run All</MenuItem> <MenuItem
onClick={handleRunAllClick}
disabled={props.allActionPending}
>
Run All
</MenuItem>
<MenuItem <MenuItem
onClick={handleDeleteAllClick} onClick={handleDeleteAllClick}
disabled={props.deleteAllRequestPending} disabled={props.allActionPending}
> >
Delete All Delete All
</MenuItem> </MenuItem>
@ -258,7 +270,7 @@ function DeadTasksTable(props: Props & ReduxProps) {
onDeleteClick={() => { onDeleteClick={() => {
props.deleteDeadTaskAsync(queue, task.key); props.deleteDeadTaskAsync(queue, task.key);
}} }}
deleteAllRequestPending={props.deleteAllRequestPending} allActionPending={props.allActionPending}
/> />
))} ))}
</TableBody> </TableBody>
@ -292,7 +304,7 @@ interface RowProps {
onSelectChange: (checked: boolean) => void; onSelectChange: (checked: boolean) => void;
onRunClick: () => void; onRunClick: () => void;
onDeleteClick: () => void; onDeleteClick: () => void;
deleteAllRequestPending: boolean; allActionPending: boolean;
} }
function Row(props: RowProps) { function Row(props: RowProps) {
@ -331,13 +343,13 @@ function Row(props: RowProps) {
<TableCell> <TableCell>
<Button <Button
onClick={props.onRunClick} onClick={props.onRunClick}
disabled={task.requestPending || props.deleteAllRequestPending} disabled={task.requestPending || props.allActionPending}
> >
Run Run
</Button> </Button>
<Button <Button
onClick={props.onDeleteClick} onClick={props.onDeleteClick}
disabled={task.requestPending || props.deleteAllRequestPending} disabled={task.requestPending || props.allActionPending}
> >
Delete Delete
</Button> </Button>

View File

@ -25,6 +25,7 @@ import {
LIST_PENDING_TASKS_SUCCESS, LIST_PENDING_TASKS_SUCCESS,
LIST_RETRY_TASKS_SUCCESS, LIST_RETRY_TASKS_SUCCESS,
LIST_SCHEDULED_TASKS_SUCCESS, LIST_SCHEDULED_TASKS_SUCCESS,
RUN_ALL_DEAD_TASKS_SUCCESS,
RUN_DEAD_TASK_SUCCESS, RUN_DEAD_TASK_SUCCESS,
TasksActionTypes, TasksActionTypes,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
@ -256,6 +257,24 @@ function queuesReducer(
return { ...state, data: newData }; return { ...state, data: newData };
} }
case RUN_ALL_DEAD_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
pending:
queueInfo.currentStats.pending + queueInfo.currentStats.dead,
dead: 0,
},
};
});
return { ...state, data: newData };
}
case DELETE_ALL_DEAD_TASKS_SUCCESS: { case DELETE_ALL_DEAD_TASKS_SUCCESS: {
const newData = state.data.map((queueInfo) => { const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) { if (queueInfo.name !== action.queue) {

View File

@ -9,6 +9,7 @@ import {
DELETE_DEAD_TASK_SUCCESS, DELETE_DEAD_TASK_SUCCESS,
DELETE_RETRY_TASK_SUCCESS, DELETE_RETRY_TASK_SUCCESS,
DELETE_SCHEDULED_TASK_SUCCESS, DELETE_SCHEDULED_TASK_SUCCESS,
RUN_ALL_DEAD_TASKS_SUCCESS,
RUN_DEAD_TASK_SUCCESS, RUN_DEAD_TASK_SUCCESS,
TasksActionTypes, TasksActionTypes,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
@ -80,10 +81,16 @@ function snackbarReducer(
}; };
} }
case RUN_ALL_DEAD_TASKS_SUCCESS:
return {
isOpen: true,
message: "All dead tasks are now pending",
};
case DELETE_ALL_DEAD_TASKS_SUCCESS: case DELETE_ALL_DEAD_TASKS_SUCCESS:
return { return {
isOpen: true, isOpen: true,
message: `All dead tasks delete`, message: "All dead tasks delete",
}; };
default: default:

View File

@ -39,6 +39,9 @@ import {
DELETE_ALL_DEAD_TASKS_BEGIN, DELETE_ALL_DEAD_TASKS_BEGIN,
DELETE_ALL_DEAD_TASKS_SUCCESS, DELETE_ALL_DEAD_TASKS_SUCCESS,
DELETE_ALL_DEAD_TASKS_ERROR, DELETE_ALL_DEAD_TASKS_ERROR,
RUN_ALL_DEAD_TASKS_BEGIN,
RUN_ALL_DEAD_TASKS_ERROR,
RUN_ALL_DEAD_TASKS_SUCCESS,
} from "../actions/tasksActions"; } from "../actions/tasksActions";
import { import {
ActiveTask, ActiveTask,
@ -100,7 +103,7 @@ interface TasksState {
deadTasks: { deadTasks: {
loading: boolean; loading: boolean;
batchActionPending: boolean; batchActionPending: boolean;
deleteAllRequestPending: boolean; allActionPending: boolean;
error: string; error: string;
data: DeadTaskExtended[]; data: DeadTaskExtended[];
}; };
@ -130,7 +133,7 @@ const initialState: TasksState = {
deadTasks: { deadTasks: {
loading: false, loading: false,
batchActionPending: false, batchActionPending: false,
deleteAllRequestPending: false, allActionPending: false,
error: "", error: "",
data: [], data: [],
}, },
@ -472,31 +475,34 @@ function tasksReducer(
}, },
}; };
case RUN_ALL_DEAD_TASKS_BEGIN:
case DELETE_ALL_DEAD_TASKS_BEGIN: case DELETE_ALL_DEAD_TASKS_BEGIN:
return { return {
...state, ...state,
deadTasks: { deadTasks: {
...state.deadTasks, ...state.deadTasks,
deleteAllRequestPending: true, allActionPending: true,
}, },
}; };
case RUN_ALL_DEAD_TASKS_SUCCESS:
case DELETE_ALL_DEAD_TASKS_SUCCESS: case DELETE_ALL_DEAD_TASKS_SUCCESS:
return { return {
...state, ...state,
deadTasks: { deadTasks: {
...state.deadTasks, ...state.deadTasks,
deleteAllRequestPending: false, allActionPending: false,
data: [], data: [],
}, },
}; };
case RUN_ALL_DEAD_TASKS_ERROR:
case DELETE_ALL_DEAD_TASKS_ERROR: case DELETE_ALL_DEAD_TASKS_ERROR:
return { return {
...state, ...state,
deadTasks: { deadTasks: {
...state.deadTasks, ...state.deadTasks,
deleteAllRequestPending: false, allActionPending: false,
}, },
}; };