Add "run task" button to DeadTasksTable

This commit is contained in:
Ken Hibino 2020-12-14 07:14:10 -08:00
parent d9a3e414b8
commit 903820e6c8
6 changed files with 95 additions and 0 deletions

View File

@ -16,6 +16,7 @@ import {
listScheduledTasks,
ListScheduledTasksResponse,
PaginationOptions,
runDeadTask,
} from "../api";
import { Dispatch } from "redux";
@ -38,6 +39,9 @@ export const LIST_DEAD_TASKS_ERROR = "LIST_DEAD_TASKS_ERROR";
export const CANCEL_ACTIVE_TASK_BEGIN = "CANCEL_ACTIVE_TASK_BEGIN";
export const CANCEL_ACTIVE_TASK_SUCCESS = "CANCEL_ACTIVE_TASK_SUCCESS";
export const CANCEL_ACTIVE_TASK_ERROR = "CANCEL_ACTIVE_TASK_ERROR";
export const RUN_DEAD_TASK_BEGIN = "RUN_DEAD_TASK_BEGIN";
export const RUN_DEAD_TASK_SUCCESS = "RUN_DEAD_TASK_SUCCESS";
export const RUN_DEAD_TASK_ERROR = "RUN_DEAD_TASK_ERROR";
export const DELETE_SCHEDULED_TASK_BEGIN = "DELETE_SCHEDULED_TASK_BEGIN";
export const DELETE_SCHEDULED_TASK_SUCCESS = "DELETE_SCHEDULED_TASK_SUCCESS";
export const DELETE_SCHEDULED_TASK_ERROR = "DELETE_SCHEDULED_TASK_ERROR";
@ -156,6 +160,25 @@ interface CancelActiveTaskErrorAction {
error: string;
}
interface RunDeadTaskBeginAction {
type: typeof RUN_DEAD_TASK_BEGIN;
queue: string;
taskKey: string;
}
interface RunDeadTaskSuccessAction {
type: typeof RUN_DEAD_TASK_SUCCESS;
queue: string;
taskKey: string;
}
interface RunDeadTaskErrorAction {
type: typeof RUN_DEAD_TASK_ERROR;
queue: string;
taskKey: string;
error: string;
}
interface DeleteScheduledTaskBeginAction {
type: typeof DELETE_SCHEDULED_TASK_BEGIN;
queue: string;
@ -252,6 +275,9 @@ export type TasksActionTypes =
| CancelActiveTaskBeginAction
| CancelActiveTaskSuccessAction
| CancelActiveTaskErrorAction
| RunDeadTaskBeginAction
| RunDeadTaskSuccessAction
| RunDeadTaskErrorAction
| DeleteScheduledTaskBeginAction
| DeleteScheduledTaskSuccessAction
| DeleteScheduledTaskErrorAction
@ -397,6 +423,24 @@ export function cancelActiveTaskAsync(queue: string, taskId: string) {
};
}
export function runDeadTaskAsync(queue: string, taskKey: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: RUN_DEAD_TASK_BEGIN, queue, taskKey });
try {
await runDeadTask(queue, taskKey);
dispatch({ type: RUN_DEAD_TASK_SUCCESS, queue, taskKey });
} catch (error) {
console.error("runDeadTaskAsync: ", error);
dispatch({
type: RUN_DEAD_TASK_ERROR,
error: `Could not run task: ${taskKey}`,
queue,
taskKey,
});
}
};
}
export function deleteScheduledTaskAsync(queue: string, taskKey: string) {
return async (dispatch: Dispatch<TasksActionTypes>) => {
dispatch({ type: DELETE_SCHEDULED_TASK_BEGIN, queue, taskKey });

View File

@ -268,6 +268,16 @@ export async function deleteRetryTask(
});
}
export async function runDeadTask(
qname: string,
taskKey: string
): Promise<void> {
await axios({
method: "post",
url: `${BASE_URL}/queues/${qname}/dead_tasks/${taskKey}:run`,
});
}
export async function deleteDeadTask(
qname: string,
taskKey: string

View File

@ -27,6 +27,7 @@ import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/
import { AppState } from "../store";
import {
listDeadTasksAsync,
runDeadTaskAsync,
deleteDeadTaskAsync,
batchDeleteDeadTasksAsync,
} from "../actions/tasksActions";
@ -69,6 +70,7 @@ function mapStateToProps(state: AppState) {
const mapDispatchToProps = {
listDeadTasksAsync,
runDeadTaskAsync,
deleteDeadTaskAsync,
batchDeleteDeadTasksAsync,
};
@ -203,6 +205,9 @@ function DeadTasksTable(props: Props & ReduxProps) {
);
}
}}
onRunClick={() => {
props.runDeadTaskAsync(queue, task.key);
}}
onDeleteClick={() => {
props.deleteDeadTaskAsync(queue, task.key);
}}
@ -237,6 +242,7 @@ interface RowProps {
task: DeadTaskExtended;
isSelected: boolean;
onSelectChange: (checked: boolean) => void;
onRunClick: () => void;
onDeleteClick: () => void;
}
@ -274,6 +280,9 @@ function Row(props: RowProps) {
<TableCell>{timeAgo(task.last_failed_at)}</TableCell>
<TableCell>{task.error_message}</TableCell>
<TableCell>
<Button onClick={props.onRunClick} disabled={task.requestPending}>
Run
</Button>
<Button onClick={props.onDeleteClick} disabled={task.requestPending}>
Delete
</Button>

View File

@ -23,6 +23,7 @@ import {
LIST_PENDING_TASKS_SUCCESS,
LIST_RETRY_TASKS_SUCCESS,
LIST_SCHEDULED_TASKS_SUCCESS,
RUN_DEAD_TASK_SUCCESS,
TasksActionTypes,
} from "../actions/tasksActions";
import { DailyStat, Queue } from "../api";
@ -151,6 +152,23 @@ function queuesReducer(
return { ...state, data: newData };
}
case RUN_DEAD_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {
return queueInfo;
}
return {
...queueInfo,
currentStats: {
...queueInfo.currentStats,
pending: queueInfo.currentStats.pending + 1,
dead: queueInfo.currentStats.dead - 1,
},
};
});
return { ...state, data: newData };
}
case DELETE_SCHEDULED_TASK_SUCCESS: {
const newData = state.data.map((queueInfo) => {
if (queueInfo.name !== action.queue) {

View File

@ -7,6 +7,7 @@ import {
DELETE_DEAD_TASK_SUCCESS,
DELETE_RETRY_TASK_SUCCESS,
DELETE_SCHEDULED_TASK_SUCCESS,
RUN_DEAD_TASK_SUCCESS,
TasksActionTypes,
} from "../actions/tasksActions";
@ -33,6 +34,13 @@ function snackbarReducer(
isOpen: false,
};
case RUN_DEAD_TASK_SUCCESS:
return {
isOpen: true,
// TODO: show only task id
message: `Dead task ${action.taskKey} is now pending`,
};
case DELETE_SCHEDULED_TASK_SUCCESS:
return {
isOpen: true,

View File

@ -30,6 +30,9 @@ import {
BATCH_DELETE_DEAD_TASKS_BEGIN,
BATCH_DELETE_DEAD_TASKS_SUCCESS,
BATCH_DELETE_DEAD_TASKS_ERROR,
RUN_DEAD_TASK_BEGIN,
RUN_DEAD_TASK_SUCCESS,
RUN_DEAD_TASK_ERROR,
} from "../actions/tasksActions";
import {
ActiveTask,
@ -419,6 +422,7 @@ function tasksReducer(
},
};
case RUN_DEAD_TASK_BEGIN:
case DELETE_DEAD_TASK_BEGIN:
return {
...state,
@ -433,6 +437,7 @@ function tasksReducer(
},
};
case RUN_DEAD_TASK_SUCCESS:
case DELETE_DEAD_TASK_SUCCESS:
return {
...state,
@ -444,6 +449,7 @@ function tasksReducer(
},
};
case RUN_DEAD_TASK_ERROR:
case DELETE_DEAD_TASK_ERROR:
return {
...state,