From 2085b1f34e489992898dee1cfaecf9944915de56 Mon Sep 17 00:00:00 2001 From: Lukas Bindreiter Date: Wed, 12 Aug 2026 17:32:11 +0200 Subject: [PATCH] Paginated Job Tasks view API --- apis/workflows/v1/core.proto | 15 +------- apis/workflows/v1/job.proto | 73 +++++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/apis/workflows/v1/core.proto b/apis/workflows/v1/core.proto index 358a422..055424a 100644 --- a/apis/workflows/v1/core.proto +++ b/apis/workflows/v1/core.proto @@ -25,8 +25,8 @@ message Job { google.protobuf.Timestamp submitted_at = 7; // The time the job started running. Deprecated, use execution_stats.first_task_started_at instead. google.protobuf.Timestamp started_at = 8 [deprecated = true]; - // A list of tasks of the job. - repeated TaskSummary task_summaries = 9; + reserved 9; + reserved task_summaries; // The automation that submitted the job. tilebox.v1.ID automation_id = 10; // A list of progress indicators for the job. @@ -90,17 +90,6 @@ enum JobState { JOB_STATE_CANCELED = 6; } -// A summary of a task. Mainly used in the Console. -message TaskSummary { - tilebox.v1.ID id = 1; - string display = 2; - TaskState state = 3; - tilebox.v1.ID parent_id = 4; - reserved 5; // depends_on in case we want to add that in the future - google.protobuf.Timestamp started_at = 6; - google.protobuf.Timestamp stopped_at = 7; -} - // Progress is an indicator of total and completed work units for a job. message Progress { // A human-readable label for the progress indicator. Can also be empty. diff --git a/apis/workflows/v1/job.proto b/apis/workflows/v1/job.proto index b4de968..32bad34 100644 --- a/apis/workflows/v1/job.proto +++ b/apis/workflows/v1/job.proto @@ -5,6 +5,7 @@ edition = "2023"; package workflows.v1; import "buf/validate/validate.proto"; +import "google/protobuf/timestamp.proto"; import "tilebox/v1/id.proto"; import "tilebox/v1/query.proto"; import "workflows/v1/core.proto"; @@ -45,11 +46,73 @@ message GetJobRequest { tilebox.v1.ID job_id = 1 [(buf.validate.field).required = true]; } -// GetJobProgressRequest requests a jobs progress. It returns a full job object, but only -// partially filled with progress indicators, job state and a started_at timestamp. -message GetJobProgressRequest { - // The ID of the job to get progress for. +// TaskSummary is a compact representation of a task within a job's task tree. +message TaskSummary { + // The ID of the task. Tasks are ordered by this ID within a sibling collection. + tilebox.v1.ID id = 1; + // The ID of the closest non-virtual ancestor task. It is absent for a root task. + tilebox.v1.ID parent_id = 2 [features.field_presence = EXPLICIT]; + // A human-readable representation of the task. + string display = 3; + // The current state of the task. + TaskState state = 4; + // The time the task was submitted. + google.protobuf.Timestamp submitted_at = 5; + // The time the task started running. + google.protobuf.Timestamp started_at = 6; + // The time the task stopped running. + google.protobuf.Timestamp stopped_at = 7; + // The serialized input parameters in the format expected by the task. + bytes input = 8 [features.field_presence = EXPLICIT]; + // The number of times the task has been retried. + int64 retry_count = 9; + // The maximum number of times the task may be retried. + int64 max_retries = 10; + // Whether the task has children in the user-visible tree. + bool has_children = 11; + // The ID of the cluster on which the task is scheduled to run. + tilebox.v1.ID cluster_id = 12; + // Whether failure of the task is optional, either directly or through an optional ancestor. + bool optional = 13; +} + +// JobTaskChildrenPrefetch configures the child pages included with the requested task page. +message JobTaskChildrenPrefetch { + // The maximum number of user-visible children to return for each task in the requested page. + int64 limit = 1 [(buf.validate.field).int64 = { + gte: 1 + lte: 100 + }]; +} + +// ListJobTasksRequest requests one page from a job's task tree. +message ListJobTasksRequest { + // The ID of the job whose tasks to list. tilebox.v1.ID job_id = 1 [(buf.validate.field).required = true]; + // The parent whose user-visible children to list. If absent, root tasks are listed. + tilebox.v1.ID parent_task_id = 2 [features.field_presence = EXPLICIT]; + // The pagination parameters for the requested sibling collection. + tilebox.v1.Pagination page = 3 [features.field_presence = EXPLICIT]; + // Optional configuration for prefetching one user-visible child page per returned task. + JobTaskChildrenPrefetch prefetch_children = 4 [features.field_presence = EXPLICIT]; +} + +// JobTaskPage is one page of a job's root tasks or one parent's user-visible children. +message JobTaskPage { + // The user-visible parent of this sibling collection. It is absent for the root collection. + tilebox.v1.ID parent_task_id = 1 [features.field_presence = EXPLICIT]; + // The tasks in this page, ordered by ascending task ID. + repeated TaskSummary tasks = 2; + // The pagination parameters for the next page of this sibling collection. + tilebox.v1.Pagination next_page = 3 [features.field_presence = EXPLICIT]; +} + +// ListJobTasksResponse contains the requested task page and any prefetched child pages. +message ListJobTasksResponse { + // The requested page. + JobTaskPage page = 1; + // The first user-visible child page for each task in page that has children. + repeated JobTaskPage prefetched_child_pages = 2; } // RetryJobRequest requests a retry of a job that has failed. @@ -178,7 +241,7 @@ message CloneJobRequest { service JobService { rpc SubmitJob(SubmitJobRequest) returns (Job); rpc GetJob(GetJobRequest) returns (Job); - rpc GetJobProgress(GetJobProgressRequest) returns (Job); + rpc ListJobTasks(ListJobTasksRequest) returns (ListJobTasksResponse); rpc RetryJob(RetryJobRequest) returns (RetryJobResponse); rpc CancelJob(CancelJobRequest) returns (CancelJobResponse); rpc VisualizeJob(VisualizeJobRequest) returns (Diagram);