Update task details view

This commit is contained in:
Ken Hibino
2021-10-16 06:48:42 -07:00
parent 36c82e380a
commit efb2aa75a8
4 changed files with 79 additions and 8 deletions

View File

@@ -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),
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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}>