mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-01-19 11:15:53 +08:00
Add batch run button to DeadTasksTable
This commit is contained in:
parent
706e80580d
commit
9bfd373f85
@ -1,6 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
batchDeleteDeadTasks,
|
batchDeleteDeadTasks,
|
||||||
BatchDeleteTasksResponse,
|
BatchDeleteTasksResponse,
|
||||||
|
batchRunDeadTasks,
|
||||||
|
BatchRunTasksResponse,
|
||||||
cancelActiveTask,
|
cancelActiveTask,
|
||||||
deleteDeadTask,
|
deleteDeadTask,
|
||||||
deleteRetryTask,
|
deleteRetryTask,
|
||||||
@ -51,6 +53,9 @@ export const DELETE_RETRY_TASK_ERROR = "DELETE_RETRY_TASK_ERROR";
|
|||||||
export const DELETE_DEAD_TASK_BEGIN = "DELETE_DEAD_TASK_BEGIN";
|
export const DELETE_DEAD_TASK_BEGIN = "DELETE_DEAD_TASK_BEGIN";
|
||||||
export const DELETE_DEAD_TASK_SUCCESS = "DELETE_DEAD_TASK_SUCCESS";
|
export const DELETE_DEAD_TASK_SUCCESS = "DELETE_DEAD_TASK_SUCCESS";
|
||||||
export const DELETE_DEAD_TASK_ERROR = "DELETE_DEAD_TASK_ERROR";
|
export const DELETE_DEAD_TASK_ERROR = "DELETE_DEAD_TASK_ERROR";
|
||||||
|
export const BATCH_RUN_DEAD_TASKS_BEGIN = "BATCH_RUN_DEAD_TASKS_BEGIN";
|
||||||
|
export const BATCH_RUN_DEAD_TASKS_SUCCESS = "BATCH_RUN_DEAD_TASKS_SUCCESS";
|
||||||
|
export const BATCH_RUN_DEAD_TASKS_ERROR = "BATCH_RUN_DEAD_TASKS_ERROR";
|
||||||
export const BATCH_DELETE_DEAD_TASKS_BEGIN = "BATCH_DELETE_DEAD_TASKS_BEGIN";
|
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";
|
||||||
@ -255,6 +260,25 @@ interface BatchDeleteDeadTasksErrorAction {
|
|||||||
error: string;
|
error: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BatchRunDeadTasksBeginAction {
|
||||||
|
type: typeof BATCH_RUN_DEAD_TASKS_BEGIN;
|
||||||
|
queue: string;
|
||||||
|
taskKeys: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BatchRunDeadTasksSuccessAction {
|
||||||
|
type: typeof BATCH_RUN_DEAD_TASKS_SUCCESS;
|
||||||
|
queue: string;
|
||||||
|
payload: BatchRunTasksResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BatchRunDeadTasksErrorAction {
|
||||||
|
type: typeof BATCH_RUN_DEAD_TASKS_ERROR;
|
||||||
|
queue: string;
|
||||||
|
taskKeys: string[];
|
||||||
|
error: string;
|
||||||
|
}
|
||||||
|
|
||||||
// Union of all tasks related action types.
|
// Union of all tasks related action types.
|
||||||
export type TasksActionTypes =
|
export type TasksActionTypes =
|
||||||
| ListActiveTasksBeginAction
|
| ListActiveTasksBeginAction
|
||||||
@ -289,7 +313,10 @@ export type TasksActionTypes =
|
|||||||
| DeleteDeadTaskErrorAction
|
| DeleteDeadTaskErrorAction
|
||||||
| BatchDeleteDeadTasksBeginAction
|
| BatchDeleteDeadTasksBeginAction
|
||||||
| BatchDeleteDeadTasksSuccessAction
|
| BatchDeleteDeadTasksSuccessAction
|
||||||
| BatchDeleteDeadTasksErrorAction;
|
| BatchDeleteDeadTasksErrorAction
|
||||||
|
| BatchRunDeadTasksBeginAction
|
||||||
|
| BatchRunDeadTasksSuccessAction
|
||||||
|
| BatchRunDeadTasksErrorAction;
|
||||||
|
|
||||||
export function listActiveTasksAsync(
|
export function listActiveTasksAsync(
|
||||||
qname: string,
|
qname: string,
|
||||||
@ -516,3 +543,25 @@ export function batchDeleteDeadTasksAsync(queue: string, taskKeys: string[]) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function batchRunDeadTasksAsync(queue: string, taskKeys: string[]) {
|
||||||
|
return async (dispatch: Dispatch<TasksActionTypes>) => {
|
||||||
|
dispatch({ type: BATCH_RUN_DEAD_TASKS_BEGIN, queue, taskKeys });
|
||||||
|
try {
|
||||||
|
const response = await batchRunDeadTasks(queue, taskKeys);
|
||||||
|
dispatch({
|
||||||
|
type: BATCH_RUN_DEAD_TASKS_SUCCESS,
|
||||||
|
queue: queue,
|
||||||
|
payload: response,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("batchRunDeadTasksAsync: ", error);
|
||||||
|
dispatch({
|
||||||
|
type: BATCH_RUN_DEAD_TASKS_ERROR,
|
||||||
|
error: `Could not batch run tasks: ${taskKeys}`,
|
||||||
|
queue,
|
||||||
|
taskKeys,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -46,6 +46,11 @@ export interface BatchDeleteTasksResponse {
|
|||||||
failed_keys: string[];
|
failed_keys: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BatchRunTasksResponse {
|
||||||
|
pending_keys: string[];
|
||||||
|
error_keys: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Queue {
|
export interface Queue {
|
||||||
queue: string;
|
queue: string;
|
||||||
paused: boolean;
|
paused: boolean;
|
||||||
@ -299,7 +304,20 @@ export async function batchDeleteDeadTasks(
|
|||||||
task_keys: taskKeys,
|
task_keys: taskKeys,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log("debug: response:", resp);
|
return resp.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function batchRunDeadTasks(
|
||||||
|
qname: string,
|
||||||
|
taskKeys: string[]
|
||||||
|
): Promise<BatchRunTasksResponse> {
|
||||||
|
const resp = await axios({
|
||||||
|
method: "post",
|
||||||
|
url: `${BASE_URL}/queues/${qname}/dead_tasks:batch_run`,
|
||||||
|
data: {
|
||||||
|
task_keys: taskKeys,
|
||||||
|
},
|
||||||
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,10 +26,11 @@ import SyntaxHighlighter from "react-syntax-highlighter";
|
|||||||
import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/github";
|
import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/github";
|
||||||
import { AppState } from "../store";
|
import { AppState } from "../store";
|
||||||
import {
|
import {
|
||||||
|
batchDeleteDeadTasksAsync,
|
||||||
|
batchRunDeadTasksAsync,
|
||||||
|
deleteDeadTaskAsync,
|
||||||
listDeadTasksAsync,
|
listDeadTasksAsync,
|
||||||
runDeadTaskAsync,
|
runDeadTaskAsync,
|
||||||
deleteDeadTaskAsync,
|
|
||||||
batchDeleteDeadTasksAsync,
|
|
||||||
} from "../actions/tasksActions";
|
} from "../actions/tasksActions";
|
||||||
import TablePaginationActions, {
|
import TablePaginationActions, {
|
||||||
defaultPageSize,
|
defaultPageSize,
|
||||||
@ -72,6 +73,7 @@ const mapDispatchToProps = {
|
|||||||
listDeadTasksAsync,
|
listDeadTasksAsync,
|
||||||
runDeadTaskAsync,
|
runDeadTaskAsync,
|
||||||
deleteDeadTaskAsync,
|
deleteDeadTaskAsync,
|
||||||
|
batchRunDeadTasksAsync,
|
||||||
batchDeleteDeadTasksAsync,
|
batchDeleteDeadTasksAsync,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,7 +155,16 @@ function DeadTasksTable(props: Props & ReduxProps) {
|
|||||||
color="primary"
|
color="primary"
|
||||||
aria-label="text primary button group"
|
aria-label="text primary button group"
|
||||||
>
|
>
|
||||||
<Button>Run</Button>
|
<Button
|
||||||
|
disabled={props.batchActionPending}
|
||||||
|
onClick={() =>
|
||||||
|
props
|
||||||
|
.batchRunDeadTasksAsync(queue, selectedKeys)
|
||||||
|
.then(() => setSelectedKeys([]))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Run
|
||||||
|
</Button>
|
||||||
<Button>Kill</Button>
|
<Button>Kill</Button>
|
||||||
<Button
|
<Button
|
||||||
disabled={props.batchActionPending}
|
disabled={props.batchActionPending}
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
} from "../actions/queuesActions";
|
} from "../actions/queuesActions";
|
||||||
import {
|
import {
|
||||||
BATCH_DELETE_DEAD_TASKS_SUCCESS,
|
BATCH_DELETE_DEAD_TASKS_SUCCESS,
|
||||||
|
BATCH_RUN_DEAD_TASKS_SUCCESS,
|
||||||
DELETE_DEAD_TASK_SUCCESS,
|
DELETE_DEAD_TASK_SUCCESS,
|
||||||
DELETE_RETRY_TASK_SUCCESS,
|
DELETE_RETRY_TASK_SUCCESS,
|
||||||
DELETE_SCHEDULED_TASK_SUCCESS,
|
DELETE_SCHEDULED_TASK_SUCCESS,
|
||||||
@ -217,6 +218,26 @@ function queuesReducer(
|
|||||||
return { ...state, data: newData };
|
return { ...state, data: newData };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BATCH_RUN_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 +
|
||||||
|
action.payload.pending_keys.length,
|
||||||
|
dead:
|
||||||
|
queueInfo.currentStats.dead - action.payload.pending_keys.length,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return { ...state, data: newData };
|
||||||
|
}
|
||||||
|
|
||||||
case BATCH_DELETE_DEAD_TASKS_SUCCESS: {
|
case BATCH_DELETE_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) {
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
} from "../actions/snackbarActions";
|
} from "../actions/snackbarActions";
|
||||||
import {
|
import {
|
||||||
BATCH_DELETE_DEAD_TASKS_SUCCESS,
|
BATCH_DELETE_DEAD_TASKS_SUCCESS,
|
||||||
|
BATCH_RUN_DEAD_TASKS_SUCCESS,
|
||||||
DELETE_DEAD_TASK_SUCCESS,
|
DELETE_DEAD_TASK_SUCCESS,
|
||||||
DELETE_RETRY_TASK_SUCCESS,
|
DELETE_RETRY_TASK_SUCCESS,
|
||||||
DELETE_SCHEDULED_TASK_SUCCESS,
|
DELETE_SCHEDULED_TASK_SUCCESS,
|
||||||
@ -62,6 +63,14 @@ function snackbarReducer(
|
|||||||
message: `Dead task ${action.taskKey} deleted`,
|
message: `Dead task ${action.taskKey} deleted`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case BATCH_RUN_DEAD_TASKS_SUCCESS: {
|
||||||
|
const n = action.payload.pending_keys.length;
|
||||||
|
return {
|
||||||
|
isOpen: true,
|
||||||
|
message: `${n} Dead ${n === 1 ? "task is" : "tasks are"} now pending`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
case BATCH_DELETE_DEAD_TASKS_SUCCESS: {
|
case BATCH_DELETE_DEAD_TASKS_SUCCESS: {
|
||||||
const n = action.payload.deleted_keys.length;
|
const n = action.payload.deleted_keys.length;
|
||||||
return {
|
return {
|
||||||
|
@ -33,6 +33,9 @@ import {
|
|||||||
RUN_DEAD_TASK_BEGIN,
|
RUN_DEAD_TASK_BEGIN,
|
||||||
RUN_DEAD_TASK_SUCCESS,
|
RUN_DEAD_TASK_SUCCESS,
|
||||||
RUN_DEAD_TASK_ERROR,
|
RUN_DEAD_TASK_ERROR,
|
||||||
|
BATCH_RUN_DEAD_TASKS_BEGIN,
|
||||||
|
BATCH_RUN_DEAD_TASKS_ERROR,
|
||||||
|
BATCH_RUN_DEAD_TASKS_SUCCESS,
|
||||||
} from "../actions/tasksActions";
|
} from "../actions/tasksActions";
|
||||||
import {
|
import {
|
||||||
ActiveTask,
|
ActiveTask,
|
||||||
@ -464,6 +467,7 @@ function tasksReducer(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case BATCH_RUN_DEAD_TASKS_BEGIN:
|
||||||
case BATCH_DELETE_DEAD_TASKS_BEGIN:
|
case BATCH_DELETE_DEAD_TASKS_BEGIN:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@ -473,6 +477,20 @@ function tasksReducer(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case BATCH_RUN_DEAD_TASKS_SUCCESS: {
|
||||||
|
const newData = state.deadTasks.data.filter(
|
||||||
|
(task) => !action.payload.pending_keys.includes(task.key)
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
deadTasks: {
|
||||||
|
...state.deadTasks,
|
||||||
|
batchActionPending: false,
|
||||||
|
data: newData,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
case BATCH_DELETE_DEAD_TASKS_SUCCESS: {
|
case BATCH_DELETE_DEAD_TASKS_SUCCESS: {
|
||||||
const newData = state.deadTasks.data.filter(
|
const newData = state.deadTasks.data.filter(
|
||||||
(task) => !action.payload.deleted_keys.includes(task.key)
|
(task) => !action.payload.deleted_keys.includes(task.key)
|
||||||
@ -487,6 +505,7 @@ function tasksReducer(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BATCH_RUN_DEAD_TASKS_ERROR:
|
||||||
case BATCH_DELETE_DEAD_TASKS_ERROR:
|
case BATCH_DELETE_DEAD_TASKS_ERROR:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
Loading…
Reference in New Issue
Block a user