diff --git a/api-contracts/openapi/paths/v1/webhooks/webhook.yaml b/api-contracts/openapi/paths/v1/webhooks/webhook.yaml index f591b075ad..8f3d5a1b64 100644 --- a/api-contracts/openapi/paths/v1/webhooks/webhook.yaml +++ b/api-contracts/openapi/paths/v1/webhooks/webhook.yaml @@ -140,6 +140,12 @@ V1WebhookGetDeleteReceiveUpdate: schema: $ref: "../../../components/schemas/_index.yaml#/APIErrors" description: Forbidden + "429": + content: + application/json: + schema: + $ref: "../../../components/schemas/_index.yaml#/APIErrors" + description: Resource limit exceeded for the tenant summary: Post a webhook message tags: - Webhook diff --git a/api-contracts/openapi/paths/worker/worker.yaml b/api-contracts/openapi/paths/worker/worker.yaml index 4bff58ed78..03e9daec4d 100644 --- a/api-contracts/openapi/paths/worker/worker.yaml +++ b/api-contracts/openapi/paths/worker/worker.yaml @@ -35,6 +35,16 @@ withTenant: type: array items: $ref: "../../components/schemas/_index.yaml#/WorkerStatus" + - description: Filter by worker labels + in: query + name: labels + required: false + schema: + type: array + items: + type: string + description: The label key-value pairs (delimited by a `:`) to filter by + minLength: 1 responses: "200": content: diff --git a/api/v1/server/handlers/v1/webhooks/receive.go b/api/v1/server/handlers/v1/webhooks/receive.go index e0e96a5905..6f964ddaee 100644 --- a/api/v1/server/handlers/v1/webhooks/receive.go +++ b/api/v1/server/handlers/v1/webhooks/receive.go @@ -321,6 +321,16 @@ func (w *V1WebhooksService) V1WebhookReceive(ctx echo.Context, request gen.V1Web ) if err != nil { + if errors.Is(err, repository.ErrResourceExhausted) { + return gen.V1WebhookReceive429JSONResponse{ + Errors: []gen.APIError{ + { + Description: "resource limit exceeded: task run or event limit reached for tenant", + }, + }, + }, nil + } + return nil, fmt.Errorf("failed to ingest event") } diff --git a/api/v1/server/handlers/workers/list.go b/api/v1/server/handlers/workers/list.go index bc5754651f..3635cc6489 100644 --- a/api/v1/server/handlers/workers/list.go +++ b/api/v1/server/handlers/workers/list.go @@ -3,11 +3,13 @@ package workers import ( "fmt" "math" + "strings" "time" "github.com/google/uuid" "github.com/labstack/echo/v4" + "github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors" "github.com/hatchet-dev/hatchet/api/v1/server/oas/gen" "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers" transformersv1 "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1" @@ -30,6 +32,25 @@ func (t *WorkerService) WorkerList(ctx echo.Context, request gen.WorkerListReque } } +func parseLabelFilters(labels *[]string) (keys []string, values []string, err error) { + if labels == nil { + return nil, nil, nil + } + + for _, l := range *labels { + split := strings.SplitN(l, ":", 2) + + if len(split) != 2 || split[0] == "" || split[1] == "" { + return nil, nil, fmt.Errorf("invalid label filter format: %s, expected key:value", l) + } + + keys = append(keys, split[0]) + values = append(values, split[1]) + } + + return keys, values, nil +} + func (t *WorkerService) workerListV0(ctx echo.Context, tenant *sqlcv1.Tenant, request gen.WorkerListRequestObject) (gen.WorkerListResponseObject, error) { reqCtx := ctx.Request().Context() tenantId := tenant.ID @@ -63,6 +84,13 @@ func (t *WorkerService) workerListV0(ctx echo.Context, tenant *sqlcv1.Tenant, re opts.Statuses = statuses } + labelKeys, labelValues, err := parseLabelFilters(request.Params.Labels) + if err != nil { + return gen.WorkerList400JSONResponse(apierrors.NewAPIErrors(err.Error())), nil + } + opts.LabelKeys = labelKeys + opts.LabelValues = labelValues + _, listSpan := telemetry.NewSpan(reqCtx, "worker-service.v0.list-workers") defer listSpan.End() @@ -152,6 +180,13 @@ func (t *WorkerService) workerListV1(ctx echo.Context, tenant *sqlcv1.Tenant, re opts.Statuses = statuses } + labelKeys, labelValues, err := parseLabelFilters(request.Params.Labels) + if err != nil { + return gen.WorkerList400JSONResponse(apierrors.NewAPIErrors(err.Error())), nil + } + opts.LabelKeys = labelKeys + opts.LabelValues = labelValues + listCtx, listSpan := telemetry.NewSpan(reqCtx, "worker-service.v1.list-workers") defer listSpan.End() diff --git a/api/v1/server/oas/gen/openapi.gen.go b/api/v1/server/oas/gen/openapi.gen.go index 47a70e923a..a1a95d5f2c 100644 --- a/api/v1/server/oas/gen/openapi.gen.go +++ b/api/v1/server/oas/gen/openapi.gen.go @@ -3090,6 +3090,9 @@ type WorkerListParams struct { // Statuses Filter by worker status Statuses *[]WorkerStatus `form:"statuses,omitempty" json:"statuses,omitempty"` + + // Labels Filter by worker labels + Labels *[]string `form:"labels,omitempty" json:"labels,omitempty"` } // WorkflowRunListStepRunEventsParams defines parameters for WorkflowRunListStepRunEvents. @@ -6703,6 +6706,13 @@ func (w *ServerInterfaceWrapper) WorkerList(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter statuses: %s", err)) } + // ------------- Optional query parameter "labels" ------------- + + err = runtime.BindQueryParameter("form", true, false, "labels", ctx.QueryParams(), ¶ms.Labels) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter labels: %s", err)) + } + // Invoke the callback with all the unmarshaled arguments err = w.Handler.WorkerList(ctx, tenant, params) return err @@ -9877,6 +9887,15 @@ func (response V1WebhookReceive403JSONResponse) VisitV1WebhookReceiveResponse(w return json.NewEncoder(w).Encode(response) } +type V1WebhookReceive429JSONResponse APIErrors + +func (response V1WebhookReceive429JSONResponse) VisitV1WebhookReceiveResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(429) + + return json.NewEncoder(w).Encode(response) +} + type V1WorkflowRunListRequestObject struct { Tenant openapi_types.UUID `json:"tenant"` Params V1WorkflowRunListParams @@ -17577,373 +17596,374 @@ func (sh *strictHandler) WorkflowVersionGet(ctx echo.Context, workflow openapi_t // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "/wsAAP//rHEJ3i2LAwA=", + "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", + "FwAA//+fA3otlYwDAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/frontend/app/src/components/v1/molecules/data-table/data-table-toolbar.tsx b/frontend/app/src/components/v1/molecules/data-table/data-table-toolbar.tsx index d18a68c6db..1c8f8c5520 100644 --- a/frontend/app/src/components/v1/molecules/data-table/data-table-toolbar.tsx +++ b/frontend/app/src/components/v1/molecules/data-table/data-table-toolbar.tsx @@ -119,7 +119,7 @@ export function DataTableToolbar({ return (
-
+
{!leftActions && isLoading && } {leftActions} diff --git a/frontend/app/src/components/v1/ui/command.tsx b/frontend/app/src/components/v1/ui/command.tsx index 9387105b78..ce11d0e95b 100644 --- a/frontend/app/src/components/v1/ui/command.tsx +++ b/frontend/app/src/components/v1/ui/command.tsx @@ -60,13 +60,23 @@ CommandInput.displayName = CommandPrimitive.Input.displayName; const CommandList = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( +>(({ className, onWheel, ...props }, ref) => ( select workflow dropdown) render their content in a portal outside + // of any enclosing modal Dialog's content. Radix Dialog's scroll lock + // (react-remove-scroll) installs a document-level wheel listener that calls + // preventDefault() on wheel events outside the dialog's content/shards, which + // blocks trackpad/wheel scrolling here (scrollbar drag still works since that + // doesn't dispatch wheel events). Stop the event from bubbling to that listener. + onWheel={(e) => { + e.stopPropagation(); + onWheel?.(e); + }} {...props} /> )); diff --git a/frontend/app/src/lib/api/generated/Api.ts b/frontend/app/src/lib/api/generated/Api.ts index f899b87777..ebba3b4378 100644 --- a/frontend/app/src/lib/api/generated/Api.ts +++ b/frontend/app/src/lib/api/generated/Api.ts @@ -3603,6 +3603,8 @@ export class Api< limit?: number; /** Filter by worker status */ statuses?: WorkerStatus[]; + /** Filter by worker labels */ + labels?: string[]; }, params: RequestParams = {}, ) => diff --git a/frontend/app/src/pages/error/components/new-version-available.tsx b/frontend/app/src/pages/error/components/new-version-available.tsx index 02da9a5638..3b04023a66 100644 --- a/frontend/app/src/pages/error/components/new-version-available.tsx +++ b/frontend/app/src/pages/error/components/new-version-available.tsx @@ -9,7 +9,9 @@ export function NewVersionAvailable() { const navigate = useNavigate(); const location = useLocation(); - const queryParams = new URLSearchParams(location.search); + const queryParams = new URLSearchParams( + location.search as Record, + ); if (!queryParams.has('updated')) { queryParams.set('updated', 'true'); diff --git a/frontend/app/src/pages/main/v1/workers/components/worker-columns.tsx b/frontend/app/src/pages/main/v1/workers/components/worker-columns.tsx index 98f78f63d4..b6f3eeb25c 100644 --- a/frontend/app/src/pages/main/v1/workers/components/worker-columns.tsx +++ b/frontend/app/src/pages/main/v1/workers/components/worker-columns.tsx @@ -28,7 +28,7 @@ const startedAtKey: WorkerColumnKeys = 'startedAt'; const slotsKey: WorkerColumnKeys = 'slots'; const lastHeartbeatAtKey: WorkerColumnKeys = 'lastHeartbeatAt'; const runtimeKey: WorkerColumnKeys = 'runtime'; -const labelsKey: WorkerColumnKeys = 'labels'; +export const labelsKey: WorkerColumnKeys = 'labels'; interface WorkerStatusBadgeProps extends BadgeProps { status?: string; diff --git a/frontend/app/src/pages/main/v1/workers/index.tsx b/frontend/app/src/pages/main/v1/workers/index.tsx index f261b0f91e..77ef169d14 100644 --- a/frontend/app/src/pages/main/v1/workers/index.tsx +++ b/frontend/app/src/pages/main/v1/workers/index.tsx @@ -1,4 +1,9 @@ -import { columns, statusKey, WorkerColumn } from './components/worker-columns'; +import { + columns, + labelsKey, + statusKey, + WorkerColumn, +} from './components/worker-columns'; import { ToolbarType } from '@/components/v1/molecules/data-table/data-table-toolbar'; import { DataTable } from '@/components/v1/molecules/data-table/data-table.tsx'; import { EmptyState } from '@/components/v1/molecules/empty-state/empty-state'; @@ -21,10 +26,12 @@ import { z } from 'zod'; const workersQuerySchema = z .object({ s: z.array(z.enum(['ACTIVE', 'INACTIVE', 'PAUSED'])).optional(), // status + l: z.array(z.string()).optional(), // labels }) .default({}) .transform((data) => ({ s: data.s ?? ['ACTIVE', 'PAUSED'], + l: data.l ?? [], })); export default function Workers() { @@ -52,16 +59,19 @@ function WorkersTable() { ); const { - state: { s: statuses }, + state: { s: statuses, l: labels }, columnFilters, setColumnFilters, resetFilters, - } = useZodColumnFilters(workersQuerySchema, paramKey, { s: statusKey }); + } = useZodColumnFilters(workersQuerySchema, paramKey, { + s: statusKey, + l: labelsKey, + }); const { pagination, setPagination, limit, offset, setPageSize } = usePagination({ key: paramKey, - resetPageOnChange: [statuses], + resetPageOnChange: [statuses, labels], }); const [columnVisibility, setColumnVisibility] = @@ -82,6 +92,7 @@ function WorkersTable() { offset, limit, statuses: statuses as WorkerStatus[], + labels: labels.length > 0 ? labels : undefined, }), refetchInterval, }); @@ -110,6 +121,11 @@ function WorkersTable() { { value: 'INACTIVE', label: 'Inactive' }, ], }, + { + columnId: labelsKey, + title: 'Labels', + type: ToolbarType.KeyValue, + }, ]} emptyState={ ({ ...prev, wasRedirectedFromTrigger: 'true' }), + search: (prev) => ({ ...prev, wasRedirectedFromTrigger: true }), }); }, onError: handleApiError, diff --git a/frontend/app/src/router.tsx b/frontend/app/src/router.tsx index afa5c75ee8..ed97d527ae 100644 --- a/frontend/app/src/router.tsx +++ b/frontend/app/src/router.tsx @@ -613,7 +613,7 @@ const tenantRunsRoute = createRoute({ }); const runSearchSchema = z.object({ - wasRedirectedFromTrigger: z.enum(['true', 'false']).optional(), // hack to preserve typing elsewhere + wasRedirectedFromTrigger: z.boolean().optional(), }); export const tenantRunRoute = createRoute({ diff --git a/pkg/client/rest/gen.go b/pkg/client/rest/gen.go index ce7f0a8c01..2a07f14070 100644 --- a/pkg/client/rest/gen.go +++ b/pkg/client/rest/gen.go @@ -3087,6 +3087,9 @@ type WorkerListParams struct { // Statuses Filter by worker status Statuses *[]WorkerStatus `form:"statuses,omitempty" json:"statuses,omitempty"` + + // Labels Filter by worker labels + Labels *[]string `form:"labels,omitempty" json:"labels,omitempty"` } // WorkflowRunListStepRunEventsParams defines parameters for WorkflowRunListStepRunEvents. @@ -11753,6 +11756,22 @@ func NewWorkerListRequest(server string, tenant openapi_types.UUID, params *Work } + if params.Labels != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "labels", runtime.ParamLocationQuery, *params.Labels); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + queryURL.RawQuery = queryValues.Encode() } @@ -16021,6 +16040,7 @@ type V1WebhookReceiveResponse struct { JSON200 *V1WebhookResponse JSON400 *APIErrors JSON403 *APIErrors + JSON429 *APIErrors } // Status returns HTTPResponse.Status @@ -21866,6 +21886,13 @@ func ParseV1WebhookReceiveResponse(rsp *http.Response) (*V1WebhookReceiveRespons } response.JSON403 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429: + var dest APIErrors + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON429 = &dest + } return response, nil diff --git a/pkg/repository/sqlcv1/workers.sql b/pkg/repository/sqlcv1/workers.sql index 266167ad9f..859002fccd 100644 --- a/pkg/repository/sqlcv1/workers.sql +++ b/pkg/repository/sqlcv1/workers.sql @@ -150,6 +150,29 @@ WHERE ELSE 'ACTIVE' END = ANY(sqlc.narg('statuses')::text[]) ) + AND ( + sqlc.narg('labelKeys')::text[] IS NULL + OR sqlc.narg('labelValues')::text[] IS NULL + OR ( + SELECT BOOL_AND( + EXISTS ( + SELECT 1 + FROM "WorkerLabel" wl + WHERE wl."workerId" = workers."id" + AND wl."key" = lf.k + AND ( + wl."strValue" = lf.v + OR wl."intValue"::text = lf.v + ) + ) + ) + FROM ( + SELECT + UNNEST(sqlc.narg('labelKeys')::text[]) AS k, + UNNEST(sqlc.narg('labelValues')::text[]) AS v + ) AS lf + ) + ) ORDER BY workers."createdAt" DESC OFFSET @@ -195,6 +218,29 @@ WHERE WHEN workers."isPaused" = true THEN 'PAUSED' ELSE 'ACTIVE' END = ANY(sqlc.narg('statuses')::text[]) + ) + AND ( + sqlc.narg('labelKeys')::text[] IS NULL + OR sqlc.narg('labelValues')::text[] IS NULL + OR ( + SELECT BOOL_AND( + EXISTS ( + SELECT 1 + FROM "WorkerLabel" wl + WHERE wl."workerId" = workers."id" + AND wl."key" = lf.k + AND ( + wl."strValue" = lf.v + OR wl."intValue"::text = lf.v + ) + ) + ) + FROM ( + SELECT + UNNEST(sqlc.narg('labelKeys')::text[]) AS k, + UNNEST(sqlc.narg('labelValues')::text[]) AS v + ) AS lf + ) ); -- name: GetWorkerById :one diff --git a/pkg/repository/sqlcv1/workers.sql.go b/pkg/repository/sqlcv1/workers.sql.go index e788de174f..6e723145c9 100644 --- a/pkg/repository/sqlcv1/workers.sql.go +++ b/pkg/repository/sqlcv1/workers.sql.go @@ -77,6 +77,29 @@ WHERE ELSE 'ACTIVE' END = ANY($5::text[]) ) + AND ( + $6::text[] IS NULL + OR $7::text[] IS NULL + OR ( + SELECT BOOL_AND( + EXISTS ( + SELECT 1 + FROM "WorkerLabel" wl + WHERE wl."workerId" = workers."id" + AND wl."key" = lf.k + AND ( + wl."strValue" = lf.v + OR wl."intValue"::text = lf.v + ) + ) + ) + FROM ( + SELECT + UNNEST($6::text[]) AS k, + UNNEST($7::text[]) AS v + ) AS lf + ) + ) ` type CountWorkersParams struct { @@ -85,6 +108,8 @@ type CountWorkersParams struct { LastHeartbeatAfter pgtype.Timestamp `json:"lastHeartbeatAfter"` Assignable pgtype.Bool `json:"assignable"` Statuses []string `json:"statuses"` + LabelKeys []string `json:"labelKeys"` + LabelValues []string `json:"labelValues"` } func (q *Queries) CountWorkers(ctx context.Context, db DBTX, arg CountWorkersParams) (int64, error) { @@ -94,6 +119,8 @@ func (q *Queries) CountWorkers(ctx context.Context, db DBTX, arg CountWorkersPar arg.LastHeartbeatAfter, arg.Assignable, arg.Statuses, + arg.LabelKeys, + arg.LabelValues, ) var count int64 err := row.Scan(&count) @@ -1340,12 +1367,35 @@ WHERE ELSE 'ACTIVE' END = ANY($5::text[]) ) + AND ( + $6::text[] IS NULL + OR $7::text[] IS NULL + OR ( + SELECT BOOL_AND( + EXISTS ( + SELECT 1 + FROM "WorkerLabel" wl + WHERE wl."workerId" = workers."id" + AND wl."key" = lf.k + AND ( + wl."strValue" = lf.v + OR wl."intValue"::text = lf.v + ) + ) + ) + FROM ( + SELECT + UNNEST($6::text[]) AS k, + UNNEST($7::text[]) AS v + ) AS lf + ) + ) ORDER BY workers."createdAt" DESC OFFSET - COALESCE($6, 0) + COALESCE($8, 0) LIMIT - COALESCE($7, 10000) + COALESCE($9, 10000) ` type ListWorkersParams struct { @@ -1354,6 +1404,8 @@ type ListWorkersParams struct { LastHeartbeatAfter pgtype.Timestamp `json:"lastHeartbeatAfter"` Assignable pgtype.Bool `json:"assignable"` Statuses []string `json:"statuses"` + LabelKeys []string `json:"labelKeys"` + LabelValues []string `json:"labelValues"` Offset interface{} `json:"offset"` Limit interface{} `json:"limit"` } @@ -1369,6 +1421,8 @@ func (q *Queries) ListWorkers(ctx context.Context, db DBTX, arg ListWorkersParam arg.LastHeartbeatAfter, arg.Assignable, arg.Statuses, + arg.LabelKeys, + arg.LabelValues, arg.Offset, arg.Limit, ) diff --git a/pkg/repository/worker.go b/pkg/repository/worker.go index 0fa43dbe45..1fde465884 100644 --- a/pkg/repository/worker.go +++ b/pkg/repository/worker.go @@ -76,6 +76,11 @@ type ListWorkersOpts struct { Offset *int Statuses []string + + // LabelKeys and LabelValues are positionally paired label filters. A worker + // must have a label matching every key/value pair to be included. + LabelKeys []string + LabelValues []string } type UpsertWorkerLabelOpts struct { @@ -189,6 +194,17 @@ func (w *workerRepository) ListWorkers(ctx context.Context, tenantId uuid.UUID, countParams.Statuses = opts.Statuses } + if len(opts.LabelKeys) > 0 || len(opts.LabelValues) > 0 { + if len(opts.LabelKeys) != len(opts.LabelValues) { + return nil, 0, fmt.Errorf("label filter keys/values must be paired: got %d keys and %d values", len(opts.LabelKeys), len(opts.LabelValues)) + } + + queryParams.LabelKeys = opts.LabelKeys + queryParams.LabelValues = opts.LabelValues + countParams.LabelKeys = opts.LabelKeys + countParams.LabelValues = opts.LabelValues + } + if opts.Limit != nil { queryParams.Limit = pgtype.Int4{ Int32: int32(*opts.Limit), // nolint: gosec diff --git a/sdks/python/hatchet_sdk/clients/rest/api/webhook_api.py b/sdks/python/hatchet_sdk/clients/rest/api/webhook_api.py index 428849ffe4..d2e846f57e 100644 --- a/sdks/python/hatchet_sdk/clients/rest/api/webhook_api.py +++ b/sdks/python/hatchet_sdk/clients/rest/api/webhook_api.py @@ -1342,6 +1342,7 @@ def v1_webhook_receive( "204": None, "400": "APIErrors", "403": "APIErrors", + "429": "APIErrors", } response_data = self.api_client.call_api( *_param, _request_timeout=_request_timeout @@ -1418,6 +1419,7 @@ def v1_webhook_receive_with_http_info( "204": None, "400": "APIErrors", "403": "APIErrors", + "429": "APIErrors", } response_data = self.api_client.call_api( *_param, _request_timeout=_request_timeout @@ -1494,6 +1496,7 @@ def v1_webhook_receive_without_preload_content( "204": None, "400": "APIErrors", "403": "APIErrors", + "429": "APIErrors", } response_data = self.api_client.call_api( *_param, _request_timeout=_request_timeout diff --git a/sdks/python/hatchet_sdk/clients/rest/api/worker_api.py b/sdks/python/hatchet_sdk/clients/rest/api/worker_api.py index b14bfe9cf6..9c84dd40b3 100644 --- a/sdks/python/hatchet_sdk/clients/rest/api/worker_api.py +++ b/sdks/python/hatchet_sdk/clients/rest/api/worker_api.py @@ -322,6 +322,10 @@ def worker_list( statuses: Annotated[ Optional[List[WorkerStatus]], Field(description="Filter by worker status") ] = None, + labels: Annotated[ + Optional[List[Annotated[str, Field(min_length=1, strict=True)]]], + Field(description="Filter by worker labels"), + ] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -346,6 +350,8 @@ def worker_list( :type limit: int :param statuses: Filter by worker status :type statuses: List[WorkerStatus] + :param labels: Filter by worker labels + :type labels: List[str] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -373,6 +379,7 @@ def worker_list( offset=offset, limit=limit, statuses=statuses, + labels=labels, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -411,6 +418,10 @@ def worker_list_with_http_info( statuses: Annotated[ Optional[List[WorkerStatus]], Field(description="Filter by worker status") ] = None, + labels: Annotated[ + Optional[List[Annotated[str, Field(min_length=1, strict=True)]]], + Field(description="Filter by worker labels"), + ] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -435,6 +446,8 @@ def worker_list_with_http_info( :type limit: int :param statuses: Filter by worker status :type statuses: List[WorkerStatus] + :param labels: Filter by worker labels + :type labels: List[str] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -462,6 +475,7 @@ def worker_list_with_http_info( offset=offset, limit=limit, statuses=statuses, + labels=labels, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -500,6 +514,10 @@ def worker_list_without_preload_content( statuses: Annotated[ Optional[List[WorkerStatus]], Field(description="Filter by worker status") ] = None, + labels: Annotated[ + Optional[List[Annotated[str, Field(min_length=1, strict=True)]]], + Field(description="Filter by worker labels"), + ] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -524,6 +542,8 @@ def worker_list_without_preload_content( :type limit: int :param statuses: Filter by worker status :type statuses: List[WorkerStatus] + :param labels: Filter by worker labels + :type labels: List[str] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -551,6 +571,7 @@ def worker_list_without_preload_content( offset=offset, limit=limit, statuses=statuses, + labels=labels, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -573,6 +594,7 @@ def _worker_list_serialize( offset, limit, statuses, + labels, _request_auth, _content_type, _headers, @@ -583,6 +605,7 @@ def _worker_list_serialize( _collection_formats: Dict[str, str] = { "statuses": "multi", + "labels": "multi", } _path_params: Dict[str, str] = {} @@ -610,6 +633,10 @@ def _worker_list_serialize( _query_params.append(("statuses", statuses)) + if labels is not None: + + _query_params.append(("labels", labels)) + # process the header parameters # process the form parameters # process the body parameter diff --git a/sdks/ruby/src/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/worker_api.rb b/sdks/ruby/src/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/worker_api.rb index 77c4d14aa3..d0534c69e3 100644 --- a/sdks/ruby/src/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/worker_api.rb +++ b/sdks/ruby/src/lib/hatchet/clients/rest/lib/hatchet-sdk-rest/api/worker_api.rb @@ -97,6 +97,7 @@ def worker_get_with_http_info(worker, opts = {}) # @option opts [Integer] :offset The number to skip # @option opts [Integer] :limit The number to limit by # @option opts [Array] :statuses Filter by worker status + # @option opts [Array] :labels Filter by worker labels # @return [WorkerList] def worker_list(tenant, opts = {}) data, _status_code, _headers = worker_list_with_http_info(tenant, opts) @@ -110,6 +111,7 @@ def worker_list(tenant, opts = {}) # @option opts [Integer] :offset The number to skip # @option opts [Integer] :limit The number to limit by # @option opts [Array] :statuses Filter by worker status + # @option opts [Array] :labels Filter by worker labels # @return [Array<(WorkerList, Integer, Hash)>] WorkerList data, response status code and response headers def worker_list_with_http_info(tenant, opts = {}) if @api_client.config.debugging @@ -135,6 +137,7 @@ def worker_list_with_http_info(tenant, opts = {}) query_params[:'offset'] = opts[:'offset'] if !opts[:'offset'].nil? query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil? query_params[:'statuses'] = @api_client.build_collection_param(opts[:'statuses'], :multi) if !opts[:'statuses'].nil? + query_params[:'labels'] = @api_client.build_collection_param(opts[:'labels'], :multi) if !opts[:'labels'].nil? # header parameters header_params = opts[:header_params] || {} diff --git a/sdks/typescript/src/clients/rest/generated/Api.ts b/sdks/typescript/src/clients/rest/generated/Api.ts index 26eb44ea24..360fb76c85 100644 --- a/sdks/typescript/src/clients/rest/generated/Api.ts +++ b/sdks/typescript/src/clients/rest/generated/Api.ts @@ -3339,6 +3339,8 @@ export class Api extends HttpClient diff --git a/sdks/typescript/src/protoc/dispatcher/dispatcher.ts b/sdks/typescript/src/protoc/dispatcher/dispatcher.ts index 4cac0ea433..74e1e5cd6e 100644 --- a/sdks/typescript/src/protoc/dispatcher/dispatcher.ts +++ b/sdks/typescript/src/protoc/dispatcher/dispatcher.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: dispatcher/dispatcher.proto diff --git a/sdks/typescript/src/protoc/events/events.ts b/sdks/typescript/src/protoc/events/events.ts index 2d3a4cb1fd..7ac27ac148 100644 --- a/sdks/typescript/src/protoc/events/events.ts +++ b/sdks/typescript/src/protoc/events/events.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: events/events.proto diff --git a/sdks/typescript/src/protoc/google/protobuf/any.ts b/sdks/typescript/src/protoc/google/protobuf/any.ts index 3bbab777c9..9a2e4c7699 100644 --- a/sdks/typescript/src/protoc/google/protobuf/any.ts +++ b/sdks/typescript/src/protoc/google/protobuf/any.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.6 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: google/protobuf/any.proto diff --git a/sdks/typescript/src/protoc/google/protobuf/timestamp.ts b/sdks/typescript/src/protoc/google/protobuf/timestamp.ts index ee4b6339ba..f242659581 100644 --- a/sdks/typescript/src/protoc/google/protobuf/timestamp.ts +++ b/sdks/typescript/src/protoc/google/protobuf/timestamp.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: google/protobuf/timestamp.proto diff --git a/sdks/typescript/src/protoc/google/rpc/status.ts b/sdks/typescript/src/protoc/google/rpc/status.ts index 85f43dede6..cfb73677c5 100644 --- a/sdks/typescript/src/protoc/google/rpc/status.ts +++ b/sdks/typescript/src/protoc/google/rpc/status.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.6 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: google/rpc/status.proto diff --git a/sdks/typescript/src/protoc/v1/dispatcher.ts b/sdks/typescript/src/protoc/v1/dispatcher.ts index 29545fe45f..bfe19f3782 100644 --- a/sdks/typescript/src/protoc/v1/dispatcher.ts +++ b/sdks/typescript/src/protoc/v1/dispatcher.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: v1/dispatcher.proto diff --git a/sdks/typescript/src/protoc/v1/shared/condition.ts b/sdks/typescript/src/protoc/v1/shared/condition.ts index ae8ce105c0..4230d3426c 100644 --- a/sdks/typescript/src/protoc/v1/shared/condition.ts +++ b/sdks/typescript/src/protoc/v1/shared/condition.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: v1/shared/condition.proto diff --git a/sdks/typescript/src/protoc/v1/shared/trigger.ts b/sdks/typescript/src/protoc/v1/shared/trigger.ts index 6b3a49268d..fdab232b19 100644 --- a/sdks/typescript/src/protoc/v1/shared/trigger.ts +++ b/sdks/typescript/src/protoc/v1/shared/trigger.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: v1/shared/trigger.proto diff --git a/sdks/typescript/src/protoc/v1/workflows.ts b/sdks/typescript/src/protoc/v1/workflows.ts index d19aab155d..607d0c748d 100644 --- a/sdks/typescript/src/protoc/v1/workflows.ts +++ b/sdks/typescript/src/protoc/v1/workflows.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: v1/workflows.proto @@ -166,6 +166,39 @@ export function runStatusToJSON(object: RunStatus): string { } } +export enum IdempotencyMethod { + TTL = 0, + STATUS = 1, + UNRECOGNIZED = -1, +} + +export function idempotencyMethodFromJSON(object: any): IdempotencyMethod { + switch (object) { + case 0: + case 'TTL': + return IdempotencyMethod.TTL; + case 1: + case 'STATUS': + return IdempotencyMethod.STATUS; + case -1: + case 'UNRECOGNIZED': + default: + return IdempotencyMethod.UNRECOGNIZED; + } +} + +export function idempotencyMethodToJSON(object: IdempotencyMethod): string { + switch (object) { + case IdempotencyMethod.TTL: + return 'TTL'; + case IdempotencyMethod.STATUS: + return 'STATUS'; + case IdempotencyMethod.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + export enum ConcurrencyLimitStrategy { CANCEL_IN_PROGRESS = 0, /** DROP_NEWEST - deprecated */ @@ -219,39 +252,6 @@ export function concurrencyLimitStrategyToJSON(object: ConcurrencyLimitStrategy) } } -export enum IdempotencyMethod { - TTL = 0, - STATUS = 1, - UNRECOGNIZED = -1, -} - -export function idempotencyMethodFromJSON(object: any): IdempotencyMethod { - switch (object) { - case 0: - case 'TTL': - return IdempotencyMethod.TTL; - case 1: - case 'STATUS': - return IdempotencyMethod.STATUS; - case -1: - case 'UNRECOGNIZED': - default: - return IdempotencyMethod.UNRECOGNIZED; - } -} - -export function idempotencyMethodToJSON(object: IdempotencyMethod): string { - switch (object) { - case IdempotencyMethod.TTL: - return 'TTL'; - case IdempotencyMethod.STATUS: - return 'STATUS'; - case IdempotencyMethod.UNRECOGNIZED: - default: - return 'UNRECOGNIZED'; - } -} - export interface CancelTasksRequest { /** a list of external UUIDs */ externalIds: string[]; @@ -361,6 +361,8 @@ export interface IdempotencyConfig { export interface IdempotencyCollisionError { /** the external ID of the existing workflow run that caused the collision */ existingRunExternalId: string; + /** the external ID of the workflow run that caused the collision */ + collidingRunExternalId: string; } export interface BulkTriggerIdempotencyCollisionError { @@ -1933,7 +1935,7 @@ export const IdempotencyConfig: MessageFns = { }; function createBaseIdempotencyCollisionError(): IdempotencyCollisionError { - return { existingRunExternalId: '' }; + return { existingRunExternalId: '', collidingRunExternalId: '' }; } export const IdempotencyCollisionError: MessageFns = { @@ -1944,6 +1946,9 @@ export const IdempotencyCollisionError: MessageFns = if (message.existingRunExternalId !== '') { writer.uint32(10).string(message.existingRunExternalId); } + if (message.collidingRunExternalId !== '') { + writer.uint32(18).string(message.collidingRunExternalId); + } return writer; }, @@ -1962,6 +1967,14 @@ export const IdempotencyCollisionError: MessageFns = message.existingRunExternalId = reader.string(); continue; } + case 2: { + if (tag !== 18) { + break; + } + + message.collidingRunExternalId = reader.string(); + continue; + } } if ((tag & 7) === 4 || tag === 0) { break; @@ -1978,6 +1991,11 @@ export const IdempotencyCollisionError: MessageFns = : isSet(object.existing_run_external_id) ? globalThis.String(object.existing_run_external_id) : '', + collidingRunExternalId: isSet(object.collidingRunExternalId) + ? globalThis.String(object.collidingRunExternalId) + : isSet(object.colliding_run_external_id) + ? globalThis.String(object.colliding_run_external_id) + : '', }; }, @@ -1986,6 +2004,9 @@ export const IdempotencyCollisionError: MessageFns = if (message.existingRunExternalId !== '') { obj.existingRunExternalId = message.existingRunExternalId; } + if (message.collidingRunExternalId !== '') { + obj.collidingRunExternalId = message.collidingRunExternalId; + } return obj; }, @@ -1995,6 +2016,7 @@ export const IdempotencyCollisionError: MessageFns = fromPartial(object: DeepPartial): IdempotencyCollisionError { const message = createBaseIdempotencyCollisionError(); message.existingRunExternalId = object.existingRunExternalId ?? ''; + message.collidingRunExternalId = object.collidingRunExternalId ?? ''; return message; }, }; @@ -2010,10 +2032,10 @@ export const BulkTriggerIdempotencyCollisionError: MessageFns ): BulkTriggerIdempotencyCollisionError { const message = createBaseBulkTriggerIdempotencyCollisionError(); message.successfulWorkflowRunExternalIds = - object.successfulWorkflowRunExternalIds?.map((e) => e) ?? []; + object.successfulWorkflowRunExternalIds?.map((e) => e) || []; message.collisions = - object.collisions?.map((e) => IdempotencyCollisionError.fromPartial(e)) ?? []; + object.collisions?.map((e) => IdempotencyCollisionError.fromPartial(e)) || []; return message; }, }; diff --git a/sdks/typescript/src/protoc/workflows/workflows.ts b/sdks/typescript/src/protoc/workflows/workflows.ts index 4dfdce3ef0..1e6489b8d6 100644 --- a/sdks/typescript/src/protoc/workflows/workflows.ts +++ b/sdks/typescript/src/protoc/workflows/workflows.ts @@ -1,6 +1,6 @@ // Code generated by protoc-gen-ts_proto. DO NOT EDIT. // versions: -// protoc-gen-ts_proto v2.11.8 +// protoc-gen-ts_proto v2.12.0 // protoc v3.19.1 // source: workflows/workflows.proto diff --git a/sdks/typescript/src/v1/client/admin.test.ts b/sdks/typescript/src/v1/client/admin.test.ts index 29fd2c94ef..6f11c417a3 100644 --- a/sdks/typescript/src/v1/client/admin.test.ts +++ b/sdks/typescript/src/v1/client/admin.test.ts @@ -11,7 +11,10 @@ function makeBulkTriggerAlreadyExistsError( ): Error { const collisionProto = BulkTriggerIdempotencyCollisionErrorProto.encode({ successfulWorkflowRunExternalIds: successfulIds, - collisions: collisions.map((c) => ({ existingRunExternalId: c.existingRunExternalId })), + collisions: collisions.map((c) => ({ + existingRunExternalId: c.existingRunExternalId, + collidingRunExternalId: '', + })), }).finish(); const statusBin = RpcStatus.encode({