Add gantt chart for task visibility#108
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a task-history Gantt chart to the Settings → Dev page for improved task observability, backed by expanded task API data (timing/metadata/error) and incremental polling support.
Changes:
- Introduces a new Gantt chart UI (chart, axis, bars, tooltip) and a
useTaskHistorycomposable to accumulate polled task history. - Extends
/tower/tasksto optionally include exited tasks and filter exited results by asinceepoch-ms cursor. - Expands
TaskInfoacross backend + generated clients/docs to include queue/finish timestamps, metadata, and error text.
Reviewed changes
Copilot reviewed 29 out of 37 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| weblens-vue/weblens-nuxt/util/gantt.ts | Gantt model building + time parsing/helpers for rendering. |
| weblens-vue/weblens-nuxt/types/portablePath.ts | Adds relative-path helper for display logic. |
| weblens-vue/weblens-nuxt/stores/location.ts | Minor comment punctuation change. |
| weblens-vue/weblens-nuxt/pages/settings/dev.vue | Adds Gantt/Table toggle and integrates useTaskHistory. |
| weblens-vue/weblens-nuxt/pages/settings.vue | Layout tweaks (min-w-0, flex-1) for better sizing/overflow. |
| weblens-vue/weblens-nuxt/e2e/dev-actions.spec.ts | E2E coverage for Gantt visibility + toggle behavior. |
| weblens-vue/weblens-nuxt/composables/useTaskHistory.ts | Polling + session history accumulation with incremental cursor. |
| weblens-vue/weblens-nuxt/components/molecule/TaskGanttTooltip.vue | Tooltip UI for task bar hover details. |
| weblens-vue/weblens-nuxt/components/molecule/TaskGanttChart.vue | Main Gantt chart component (zoom, pin-right scrolling, virtualization). |
| weblens-vue/weblens-nuxt/components/molecule/FileSquare.vue | Supports displayName as string or PortablePath and renders paths. |
| weblens-vue/weblens-nuxt/components/molecule/FileCard.vue | Computes relative display name during search and passes to file component. |
| weblens-vue/weblens-nuxt/components/atom/GanttTimeAxis.vue | Tick rendering for the Gantt time axis. |
| weblens-vue/weblens-nuxt/components/atom/GanttBar.vue | Individual bar rendering + hover event emission. |
| weblens-vue/weblens-nuxt/components/atom/FilePath.vue | Updates path rendering with icons and truncation behavior. |
| services/reshape/task.go | Adds metadata/error and queue/finish timing to reshaped TaskInfo. |
| services/reshape/task_test.go | Unit tests for new TaskInfo timing + error propagation. |
| routers/api/v1/tower/rest_admin.go | Adds includeExited + since handling and task filtering helper. |
| routers/api/v1/tower/rest_admin_test.go | Unit tests for FilterTasks behavior. |
| modules/wlstructs/task.go | Expands TaskInfo struct with queue/finish/metadata/error. |
| models/task/worker_pool.go | Changes task retention behavior and sets finish time on panic recovery. |
| models/task/task.go | Adds GetQueueTime() accessor. |
| models/task/task_test.go | Test asserting finished tasks remain queryable. |
| models/history/file_action.go | Moves warning about empty content ID from creation to save time. |
| e2e/rest_tower_test.go | E2E validation that includeExited=true works and returns a list. |
| docs/swagger.yaml | Updates swagger artifacts for new fields/params. |
| docs/swagger.json | Updates swagger artifacts for new fields/params. |
| docs/docs.go | Updates embedded swagger doc template. |
| api/ts/generated/docs/TowersApi.md | TS client docs updated for new query params. |
| api/ts/generated/docs/TaskInfo.md | TS client docs updated for new TaskInfo fields. |
| api/ts/generated/api.ts | TS generated types + API signature updates. |
| api/ts/dist/AllApi.js | Built JS client updated for new signature/params. |
| api/ts/dist/AllApi.d.ts | Built TS declarations updated for new signature/params. |
| api/model_task_info.go | Generated Go model updated for new fields. |
| api/docs/TowersAPI.md | Generated Go client docs updated for new query params. |
| api/docs/TaskInfo.md | Generated Go client docs updated for new TaskInfo fields. |
| api/api/openapi.yaml | OpenAPI spec updated for new fields/params. |
| api/api_towers.go | Generated Go client updated for new query params. |
Files not reviewed (3)
- api/api_towers.go: Generated file
- api/model_task_info.go: Generated file
- docs/docs.go: Generated file
Comments suppressed due to low confidence (1)
models/task/worker_pool.go:555
- Finished non-persistent tasks are now retained indefinitely in
WorkerPool.taskMap. This changes the documented semantics ofOptions.Persistent(which says non-persistent tasks are removed) and can lead to unbounded memory growth and slower scans overGetTasks()(e.g.,services/embed/embed_service.goiterates all tasks). Consider adding a bounded retention policy (TTL / max count) for exited tasks, or restoring eviction for non-persistent tasks while separately tracking recent history for observability.
// Update parent task pools about completed task
directParent := t.GetTaskPool()
directParent.IncCompletedTasks(1)
// Run cleanup routines for the task
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 42 changed files in this pull request and generated 8 comments.
Files not reviewed (3)
- api/api_towers.go: Generated file
- api/model_task_info.go: Generated file
- docs/docs.go: Generated file
Comments suppressed due to low confidence (1)
models/task/worker_pool.go:556
- Finished tasks are no longer removed from
wp.taskMap, so the worker pool will retain every task ever dispatched for the lifetime of the process. Without a retention policy (max age / max count / explicit cleanup) this can grow unbounded and increase memory usage and response sizes over time (even with the newsincecursor, the server still stores everything).
// Update parent task pools about completed task
directParent := t.GetTaskPool()
directParent.IncCompletedTasks(1)
// Run cleanup routines for the task
wp.cleanupTask(t, workerID)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 42 changed files in this pull request and generated 3 comments.
Files not reviewed (3)
- api/api_towers.go: Generated file
- api/model_task_info.go: Generated file
- docs/docs.go: Generated file
Comments suppressed due to low confidence (1)
models/task/worker_pool.go:556
- Finished tasks are no longer removed from the worker pool’s
taskMap(the previous cleanup path was removed), sotaskMapwill grow unbounded over the server lifetime. This has clear memory/operational risk, and also makes the initialincludeExited=true&since=0poll potentially huge.
// Wake any waiters on this task
close(t.waitChan)
// Potentially find the task pool that houses this task pool. All child
// task pools report their status to the root task pool as well.
// Do not use any global pool as the root
rootTaskPool := t.taskPool.GetRootPool()
if t.exitStatus.Load() == TaskError && !rootTaskPool.IsGlobal() {
rootTaskPool.AddError(t)
}
// Update parent task pools about completed task
directParent := t.GetTaskPool()
directParent.IncCompletedTasks(1)
// Run cleanup routines for the task
wp.cleanupTask(t, workerID)
The empty-content-ID warning was moved from NewCreateAction into SaveAction, but its text still read "Creating FileAction...". Update it to "Saving FileAction..." so the log message reflects the actual call site and stays searchable.
The gantt chart is now the default task view on the dev settings page, so the "No running tasks" empty state only renders after toggling to the table view. Switch to the Table view before asserting the empty state.
getByText('upload-seq-N.txt') matched both the upload progress indicator
and the file-grid entry, causing a strict-mode violation under CI timing.
Scope to [id^="file-card-"] like the other upload-flow assertions.
Added gantt chart for task history observability on the dev page in the settings