mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-10-03 18:52:01 +08:00
(ui): Add Completed section in QueueSizeChart
This commit is contained in:
@@ -348,6 +348,9 @@ func toArchivedTasks(in []*asynq.TaskInfo, pf PayloadFormatter) []*archivedTask
|
||||
type completedTask struct {
|
||||
*baseTask
|
||||
CompletedAt time.Time `json:"completed_at"`
|
||||
Result string `json:"result"`
|
||||
// Number of seconds left for retention (i.e. (CompletedAt + ResultTTL) - Now)
|
||||
ResultTTL int64 `json:"result_ttl_seconds"`
|
||||
}
|
||||
|
||||
func toCompletedTask(ti *asynq.TaskInfo, pf PayloadFormatter) *completedTask {
|
||||
@@ -360,9 +363,13 @@ func toCompletedTask(ti *asynq.TaskInfo, pf PayloadFormatter) *completedTask {
|
||||
Retried: ti.Retried,
|
||||
LastError: ti.LastErr,
|
||||
}
|
||||
ttl := ti.CompletedAt.Add(ti.ResultTTL).Sub(time.Now())
|
||||
return &completedTask{
|
||||
baseTask: base,
|
||||
CompletedAt: ti.CompletedAt,
|
||||
ResultTTL: int64(ttl.Seconds()),
|
||||
// TODO: Use resultFormatter instead
|
||||
Result: defaultPayloadFormatter.FormatPayload("", ti.Result),
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -329,6 +329,8 @@ export interface CompletedTask extends BaseTask {
|
||||
max_retry: number;
|
||||
retried: number;
|
||||
completed_at: string;
|
||||
result: string;
|
||||
result_ttl_seconds: number
|
||||
}
|
||||
|
||||
export interface ServerInfo {
|
||||
|
@@ -26,7 +26,12 @@ import TablePaginationActions, {
|
||||
} from "./TablePaginationActions";
|
||||
import { taskRowsPerPageChange } from "../actions/settingsActions";
|
||||
import TableActions from "./TableActions";
|
||||
import { timeAgo, uuidPrefix } from "../utils";
|
||||
import {
|
||||
durationFromSeconds,
|
||||
stringifyDuration,
|
||||
timeAgo,
|
||||
uuidPrefix,
|
||||
} from "../utils";
|
||||
import { usePolling } from "../hooks";
|
||||
import { CompletedTaskExtended } from "../reducers/tasksReducer";
|
||||
import { TableColumn } from "../types/table";
|
||||
@@ -132,8 +137,9 @@ function CompletedTasksTable(props: Props & ReduxProps) {
|
||||
{ key: "id", label: "ID", align: "left" },
|
||||
{ key: "type", label: "Type", align: "left" },
|
||||
{ key: "payload", label: "Payload", align: "left" },
|
||||
{ key: "completed_at", label: "Completed Time", align: "left" },
|
||||
{ key: "completed_at", label: "Completed", align: "left" },
|
||||
{ key: "result", label: "Result", align: "left" },
|
||||
{ key: "ttl", label: "TTL", align: "left" },
|
||||
{ key: "actions", label: "Actions", align: "center" },
|
||||
];
|
||||
|
||||
@@ -310,7 +316,21 @@ function Row(props: RowProps) {
|
||||
</SyntaxHighlighter>
|
||||
</TableCell>
|
||||
<TableCell>{timeAgo(task.completed_at)}</TableCell>
|
||||
<TableCell>{"TODO: Result data here"}</TableCell>
|
||||
<TableCell>
|
||||
<SyntaxHighlighter
|
||||
language="json"
|
||||
customStyle={{ margin: 0, maxWidth: 400 }}
|
||||
>
|
||||
{task.result}
|
||||
</SyntaxHighlighter>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{task.result_ttl_seconds > 0
|
||||
? `${stringifyDuration(
|
||||
durationFromSeconds(task.result_ttl_seconds)
|
||||
)} left`
|
||||
: `expired`}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
align="center"
|
||||
className={classes.actionCell}
|
||||
|
@@ -23,6 +23,7 @@ interface TaskBreakdown {
|
||||
scheduled: number; // number of scheduled tasks in the queue.
|
||||
retry: number; // number of retry tasks in the queue.
|
||||
archived: number; // number of archived tasks in the queue.
|
||||
completed: number; // number of completed tasks in the queue.
|
||||
}
|
||||
|
||||
function QueueSizeChart(props: Props) {
|
||||
@@ -55,6 +56,7 @@ function QueueSizeChart(props: Props) {
|
||||
<Bar dataKey="scheduled" stackId="a" fill="#fdd663" />
|
||||
<Bar dataKey="retry" stackId="a" fill="#f666a9" />
|
||||
<Bar dataKey="archived" stackId="a" fill="#ac4776" />
|
||||
<Bar dataKey="completed" stackId="a" fill="#4bb543" />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
);
|
||||
|
@@ -25,17 +25,22 @@ interface Duration {
|
||||
totalSeconds: number;
|
||||
}
|
||||
|
||||
// start and end are in milliseconds.
|
||||
function durationBetween(start: number, end: number): Duration {
|
||||
const durationInMillisec = start - end;
|
||||
const totalSeconds = Math.floor(durationInMillisec / 1000);
|
||||
// Returns a duration from the number of seconds provided.
|
||||
export function durationFromSeconds(totalSeconds: number): Duration {
|
||||
const hour = Math.floor(totalSeconds / 3600);
|
||||
const minute = Math.floor((totalSeconds - 3600 * hour) / 60);
|
||||
const second = totalSeconds - 3600 * hour - 60 * minute;
|
||||
return { hour, minute, second, totalSeconds };
|
||||
}
|
||||
|
||||
function stringifyDuration(d: Duration): string {
|
||||
// start and end are in milliseconds.
|
||||
function durationBetween(start: number, end: number): Duration {
|
||||
const durationInMillisec = start - end;
|
||||
const totalSeconds = Math.floor(durationInMillisec / 1000);
|
||||
return durationFromSeconds(totalSeconds);
|
||||
}
|
||||
|
||||
export function stringifyDuration(d: Duration): string {
|
||||
if (d.hour > 24) {
|
||||
const n = Math.floor(d.hour / 24);
|
||||
return n + (n === 1 ? " day" : " days");
|
||||
|
Reference in New Issue
Block a user