mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-01-19 11:15:53 +08:00
Add "run task" button to DeadTasksTable
This commit is contained in:
parent
d9a3e414b8
commit
903820e6c8
@ -16,6 +16,7 @@ import {
|
|||||||
listScheduledTasks,
|
listScheduledTasks,
|
||||||
ListScheduledTasksResponse,
|
ListScheduledTasksResponse,
|
||||||
PaginationOptions,
|
PaginationOptions,
|
||||||
|
runDeadTask,
|
||||||
} from "../api";
|
} from "../api";
|
||||||
import { Dispatch } from "redux";
|
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_BEGIN = "CANCEL_ACTIVE_TASK_BEGIN";
|
||||||
export const CANCEL_ACTIVE_TASK_SUCCESS = "CANCEL_ACTIVE_TASK_SUCCESS";
|
export const CANCEL_ACTIVE_TASK_SUCCESS = "CANCEL_ACTIVE_TASK_SUCCESS";
|
||||||
export const CANCEL_ACTIVE_TASK_ERROR = "CANCEL_ACTIVE_TASK_ERROR";
|
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_BEGIN = "DELETE_SCHEDULED_TASK_BEGIN";
|
||||||
export const DELETE_SCHEDULED_TASK_SUCCESS = "DELETE_SCHEDULED_TASK_SUCCESS";
|
export const DELETE_SCHEDULED_TASK_SUCCESS = "DELETE_SCHEDULED_TASK_SUCCESS";
|
||||||
export const DELETE_SCHEDULED_TASK_ERROR = "DELETE_SCHEDULED_TASK_ERROR";
|
export const DELETE_SCHEDULED_TASK_ERROR = "DELETE_SCHEDULED_TASK_ERROR";
|
||||||
@ -156,6 +160,25 @@ interface CancelActiveTaskErrorAction {
|
|||||||
error: string;
|
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 {
|
interface DeleteScheduledTaskBeginAction {
|
||||||
type: typeof DELETE_SCHEDULED_TASK_BEGIN;
|
type: typeof DELETE_SCHEDULED_TASK_BEGIN;
|
||||||
queue: string;
|
queue: string;
|
||||||
@ -252,6 +275,9 @@ export type TasksActionTypes =
|
|||||||
| CancelActiveTaskBeginAction
|
| CancelActiveTaskBeginAction
|
||||||
| CancelActiveTaskSuccessAction
|
| CancelActiveTaskSuccessAction
|
||||||
| CancelActiveTaskErrorAction
|
| CancelActiveTaskErrorAction
|
||||||
|
| RunDeadTaskBeginAction
|
||||||
|
| RunDeadTaskSuccessAction
|
||||||
|
| RunDeadTaskErrorAction
|
||||||
| DeleteScheduledTaskBeginAction
|
| DeleteScheduledTaskBeginAction
|
||||||
| DeleteScheduledTaskSuccessAction
|
| DeleteScheduledTaskSuccessAction
|
||||||
| DeleteScheduledTaskErrorAction
|
| 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) {
|
export function deleteScheduledTaskAsync(queue: string, taskKey: string) {
|
||||||
return async (dispatch: Dispatch<TasksActionTypes>) => {
|
return async (dispatch: Dispatch<TasksActionTypes>) => {
|
||||||
dispatch({ type: DELETE_SCHEDULED_TASK_BEGIN, queue, taskKey });
|
dispatch({ type: DELETE_SCHEDULED_TASK_BEGIN, queue, taskKey });
|
||||||
|
@ -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(
|
export async function deleteDeadTask(
|
||||||
qname: string,
|
qname: string,
|
||||||
taskKey: string
|
taskKey: string
|
||||||
|
@ -27,6 +27,7 @@ import syntaxHighlightStyle from "react-syntax-highlighter/dist/esm/styles/hljs/
|
|||||||
import { AppState } from "../store";
|
import { AppState } from "../store";
|
||||||
import {
|
import {
|
||||||
listDeadTasksAsync,
|
listDeadTasksAsync,
|
||||||
|
runDeadTaskAsync,
|
||||||
deleteDeadTaskAsync,
|
deleteDeadTaskAsync,
|
||||||
batchDeleteDeadTasksAsync,
|
batchDeleteDeadTasksAsync,
|
||||||
} from "../actions/tasksActions";
|
} from "../actions/tasksActions";
|
||||||
@ -69,6 +70,7 @@ function mapStateToProps(state: AppState) {
|
|||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
listDeadTasksAsync,
|
listDeadTasksAsync,
|
||||||
|
runDeadTaskAsync,
|
||||||
deleteDeadTaskAsync,
|
deleteDeadTaskAsync,
|
||||||
batchDeleteDeadTasksAsync,
|
batchDeleteDeadTasksAsync,
|
||||||
};
|
};
|
||||||
@ -203,6 +205,9 @@ function DeadTasksTable(props: Props & ReduxProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
onRunClick={() => {
|
||||||
|
props.runDeadTaskAsync(queue, task.key);
|
||||||
|
}}
|
||||||
onDeleteClick={() => {
|
onDeleteClick={() => {
|
||||||
props.deleteDeadTaskAsync(queue, task.key);
|
props.deleteDeadTaskAsync(queue, task.key);
|
||||||
}}
|
}}
|
||||||
@ -237,6 +242,7 @@ interface RowProps {
|
|||||||
task: DeadTaskExtended;
|
task: DeadTaskExtended;
|
||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
onSelectChange: (checked: boolean) => void;
|
onSelectChange: (checked: boolean) => void;
|
||||||
|
onRunClick: () => void;
|
||||||
onDeleteClick: () => void;
|
onDeleteClick: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +280,9 @@ function Row(props: RowProps) {
|
|||||||
<TableCell>{timeAgo(task.last_failed_at)}</TableCell>
|
<TableCell>{timeAgo(task.last_failed_at)}</TableCell>
|
||||||
<TableCell>{task.error_message}</TableCell>
|
<TableCell>{task.error_message}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
<Button onClick={props.onRunClick} disabled={task.requestPending}>
|
||||||
|
Run
|
||||||
|
</Button>
|
||||||
<Button onClick={props.onDeleteClick} disabled={task.requestPending}>
|
<Button onClick={props.onDeleteClick} disabled={task.requestPending}>
|
||||||
Delete
|
Delete
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -23,6 +23,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_DEAD_TASK_SUCCESS,
|
||||||
TasksActionTypes,
|
TasksActionTypes,
|
||||||
} from "../actions/tasksActions";
|
} from "../actions/tasksActions";
|
||||||
import { DailyStat, Queue } from "../api";
|
import { DailyStat, Queue } from "../api";
|
||||||
@ -151,6 +152,23 @@ function queuesReducer(
|
|||||||
return { ...state, data: newData };
|
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: {
|
case DELETE_SCHEDULED_TASK_SUCCESS: {
|
||||||
const newData = state.data.map((queueInfo) => {
|
const newData = state.data.map((queueInfo) => {
|
||||||
if (queueInfo.name !== action.queue) {
|
if (queueInfo.name !== action.queue) {
|
||||||
|
@ -7,6 +7,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_DEAD_TASK_SUCCESS,
|
||||||
TasksActionTypes,
|
TasksActionTypes,
|
||||||
} from "../actions/tasksActions";
|
} from "../actions/tasksActions";
|
||||||
|
|
||||||
@ -33,6 +34,13 @@ function snackbarReducer(
|
|||||||
isOpen: false,
|
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:
|
case DELETE_SCHEDULED_TASK_SUCCESS:
|
||||||
return {
|
return {
|
||||||
isOpen: true,
|
isOpen: true,
|
||||||
|
@ -30,6 +30,9 @@ import {
|
|||||||
BATCH_DELETE_DEAD_TASKS_BEGIN,
|
BATCH_DELETE_DEAD_TASKS_BEGIN,
|
||||||
BATCH_DELETE_DEAD_TASKS_SUCCESS,
|
BATCH_DELETE_DEAD_TASKS_SUCCESS,
|
||||||
BATCH_DELETE_DEAD_TASKS_ERROR,
|
BATCH_DELETE_DEAD_TASKS_ERROR,
|
||||||
|
RUN_DEAD_TASK_BEGIN,
|
||||||
|
RUN_DEAD_TASK_SUCCESS,
|
||||||
|
RUN_DEAD_TASK_ERROR,
|
||||||
} from "../actions/tasksActions";
|
} from "../actions/tasksActions";
|
||||||
import {
|
import {
|
||||||
ActiveTask,
|
ActiveTask,
|
||||||
@ -419,6 +422,7 @@ function tasksReducer(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case RUN_DEAD_TASK_BEGIN:
|
||||||
case DELETE_DEAD_TASK_BEGIN:
|
case DELETE_DEAD_TASK_BEGIN:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@ -433,6 +437,7 @@ function tasksReducer(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case RUN_DEAD_TASK_SUCCESS:
|
||||||
case DELETE_DEAD_TASK_SUCCESS:
|
case DELETE_DEAD_TASK_SUCCESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@ -444,6 +449,7 @@ function tasksReducer(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case RUN_DEAD_TASK_ERROR:
|
||||||
case DELETE_DEAD_TASK_ERROR:
|
case DELETE_DEAD_TASK_ERROR:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
Loading…
Reference in New Issue
Block a user