mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-10-04 03:01:59 +08:00
Update task details view
This commit is contained in:
@@ -154,6 +154,22 @@ type taskInfo struct {
|
||||
// NextProcessAt is the time the task is scheduled to be processed in RFC3339 format.
|
||||
// If not applicable, empty string.
|
||||
NextProcessAt string `json:"next_process_at"`
|
||||
// CompletedAt is the time the task was successfully processed in RFC3339 format.
|
||||
// If not applicable, empty string.
|
||||
CompletedAt string `json:"completed_at"`
|
||||
// Result is the result data associated with the task.
|
||||
Result string `json:"result"`
|
||||
// TTL is the number of seconds the task has left to be retained in the queue.
|
||||
// This is calculated by (CompletedAt + ResultTTL) - Now.
|
||||
TTL int64 `json:"ttl_seconds"`
|
||||
}
|
||||
|
||||
// taskTTL calculates TTL for the given task.
|
||||
func taskTTL(task *asynq.TaskInfo) time.Duration {
|
||||
if task.State != asynq.TaskStateCompleted {
|
||||
return 0 // N/A
|
||||
}
|
||||
return task.CompletedAt.Add(task.ResultTTL).Sub(time.Now())
|
||||
}
|
||||
|
||||
// formatTimeInRFC3339 formats t in RFC3339 if the value is non-zero.
|
||||
@@ -179,6 +195,10 @@ func toTaskInfo(info *asynq.TaskInfo, pf PayloadFormatter) *taskInfo {
|
||||
Timeout: int(info.Timeout.Seconds()),
|
||||
Deadline: formatTimeInRFC3339(info.Deadline),
|
||||
NextProcessAt: formatTimeInRFC3339(info.NextProcessAt),
|
||||
CompletedAt: formatTimeInRFC3339(info.CompletedAt),
|
||||
// TODO: Replace this with resultFormatter
|
||||
Result: defaultPayloadFormatter.FormatPayload("", info.Result),
|
||||
TTL: int64(taskTTL(info).Seconds()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +370,7 @@ type completedTask struct {
|
||||
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"`
|
||||
TTL int64 `json:"ttl_seconds"`
|
||||
}
|
||||
|
||||
func toCompletedTask(ti *asynq.TaskInfo, pf PayloadFormatter) *completedTask {
|
||||
@@ -363,11 +383,10 @@ 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()),
|
||||
TTL: int64(taskTTL(ti).Seconds()),
|
||||
// TODO: Use resultFormatter instead
|
||||
Result: defaultPayloadFormatter.FormatPayload("", ti.Result),
|
||||
}
|
||||
|
@@ -276,6 +276,9 @@ export interface TaskInfo {
|
||||
next_process_at: string;
|
||||
timeout_seconds: number;
|
||||
deadline: string;
|
||||
completed_at: string;
|
||||
result: string;
|
||||
ttl_seconds: number;
|
||||
}
|
||||
|
||||
export interface ActiveTask extends BaseTask {
|
||||
@@ -330,7 +333,7 @@ export interface CompletedTask extends BaseTask {
|
||||
retried: number;
|
||||
completed_at: string;
|
||||
result: string;
|
||||
result_ttl_seconds: number
|
||||
ttl_seconds: number
|
||||
}
|
||||
|
||||
export interface ServerInfo {
|
||||
|
@@ -325,10 +325,8 @@ function Row(props: RowProps) {
|
||||
</SyntaxHighlighter>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{task.result_ttl_seconds > 0
|
||||
? `${stringifyDuration(
|
||||
durationFromSeconds(task.result_ttl_seconds)
|
||||
)} left`
|
||||
{task.ttl_seconds > 0
|
||||
? `${stringifyDuration(durationFromSeconds(task.ttl_seconds))} left`
|
||||
: `expired`}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
|
@@ -18,6 +18,7 @@ import { TaskDetailsRouteParams } from "../paths";
|
||||
import { usePolling } from "../hooks";
|
||||
import { listQueuesAsync } from "../actions/queuesActions";
|
||||
import SyntaxHighlighter from "../components/SyntaxHighlighter";
|
||||
import { durationFromSeconds, stringifyDuration } from "../utils";
|
||||
|
||||
function mapStateToProps(state: AppState) {
|
||||
return {
|
||||
@@ -232,6 +233,56 @@ function TaskDetailsView(props: Props) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
/* Completed Task Only */ taskInfo?.state === "completed" && (
|
||||
<>
|
||||
<div className={classes.infoRow}>
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
className={classes.infoKeyCell}
|
||||
>
|
||||
Completed:{" "}
|
||||
</Typography>
|
||||
<div className={classes.infoValueCell}>
|
||||
<Typography>{taskInfo.completed_at}</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.infoRow}>
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
className={classes.infoKeyCell}
|
||||
>
|
||||
Result:{" "}
|
||||
</Typography>
|
||||
<div className={classes.infoValueCell}>
|
||||
<SyntaxHighlighter
|
||||
language="json"
|
||||
customStyle={{ margin: 0, maxWidth: 400 }}
|
||||
>
|
||||
{taskInfo.result}
|
||||
</SyntaxHighlighter>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.infoRow}>
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
className={classes.infoKeyCell}
|
||||
>
|
||||
TTL:{" "}
|
||||
</Typography>
|
||||
<Typography className={classes.infoValueCell}>
|
||||
<Typography>
|
||||
{taskInfo.ttl_seconds > 0
|
||||
? `${stringifyDuration(
|
||||
durationFromSeconds(taskInfo.ttl_seconds)
|
||||
)} left`
|
||||
: "expired"}
|
||||
</Typography>
|
||||
</Typography>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</Paper>
|
||||
)}
|
||||
<div className={classes.footer}>
|
||||
|
Reference in New Issue
Block a user