Feat scheduled improvements (#992)

* wip: stub schedule page

* wip: stub list

* fix: 2025 bug...

* feat: wip cron list

* feat: addl meta

* feat: expose metadata column

* feat: sort and created at

* cron to recurring

* scheduled: with statuses

* fix: links

* feat: expose schedule ids

* feat: delete run

* fix: remove search

* feat: filterable scheduled

* fix: remove broken features

* chore: lint

* rm metadata for now

* chore: lint

* chore: recurring to cron job

* fix: review comments

* fix: populator
This commit is contained in:
Gabe Ruttner
2024-11-01 04:16:20 -07:00
committed by GitHub
parent 831c6cfd9f
commit 44addbb47e
48 changed files with 8332 additions and 505 deletions
@@ -152,6 +152,20 @@ ReplayWorkflowRunsResponse:
$ref: "./workflow_run.yaml#/ReplayWorkflowRunsResponse"
WorkflowRunList:
$ref: "./workflow_run.yaml#/WorkflowRunList"
ScheduledWorkflows:
$ref: "./workflow_run.yaml#/ScheduledWorkflows"
ScheduledWorkflowsList:
$ref: "./workflow_run.yaml#/ScheduledWorkflowsList"
ScheduledWorkflowsOrderByField:
$ref: "./workflow_run.yaml#/ScheduledWorkflowsOrderByField"
ScheduledRunStatus:
$ref: "./workflow_run.yaml#/ScheduledRunStatus"
CronWorkflows:
$ref: "./workflow_run.yaml#/CronWorkflows"
CronWorkflowsList:
$ref: "./workflow_run.yaml#/CronWorkflowsList"
CronWorkflowsOrderByField:
$ref: "./workflow_run.yaml#/CronWorkflowsOrderByField"
WorkflowRunOrderByField:
$ref: "./workflow_run.yaml#/WorkflowRunOrderByField"
WorkflowRunOrderByDirection:
@@ -6,6 +6,17 @@ WorkflowRunOrderByField:
- finishedAt
- duration
ScheduledWorkflowsOrderByField:
type: string
enum:
- triggerAt
- createdAt
CronWorkflowsOrderByField:
type: string
enum:
- createdAt
WorkflowRunOrderByDirection:
type: string
enum:
@@ -161,6 +172,98 @@ WorkflowRunList:
pagination:
$ref: "./metadata.yaml#/PaginationResponse"
ScheduledWorkflows:
type: object
properties:
metadata:
$ref: "./metadata.yaml#/APIResourceMeta"
tenantId:
type: string
workflowVersionId:
type: string
workflowId:
type: string
workflowName:
type: string
triggerAt:
type: string
format: date-time
input:
type: object
additionalProperties: true
additionalMetadata:
type: object
additionalProperties: true
workflowRunCreatedAt:
type: string
format: date-time
workflowRunName:
type: string
workflowRunStatus:
$ref: "#/WorkflowRunStatus"
workflowRunId:
type: string
example: bb214807-246e-43a5-a25d-41761d1cff9e
minLength: 36
maxLength: 36
format: uuid
required:
- metadata
- tenantId
- workflowVersionId
- workflowName
- workflowId
- triggerAt
ScheduledWorkflowsList:
type: object
properties:
rows:
type: array
items:
$ref: "#/ScheduledWorkflows"
pagination:
$ref: "./metadata.yaml#/PaginationResponse"
CronWorkflows:
type: object
properties:
metadata:
$ref: "./metadata.yaml#/APIResourceMeta"
tenantId:
type: string
workflowVersionId:
type: string
workflowId:
type: string
workflowName:
type: string
cron:
type: string
input:
type: object
additionalProperties: true
additionalMetadata:
type: object
additionalProperties: true
required:
- metadata
- tenantId
- workflowVersionId
- workflowName
- workflowId
- cron
CronWorkflowsList:
type: object
properties:
rows:
type: array
items:
$ref: "#/CronWorkflows"
pagination:
$ref: "./metadata.yaml#/PaginationResponse"
WorkflowRunsMetricsCounts:
type: object
properties:
@@ -213,6 +316,17 @@ WorkflowRunStatus:
- CANCELLED
- QUEUED
ScheduledRunStatus:
type: string
enum:
- PENDING
- RUNNING
- SUCCEEDED
- FAILED
- CANCELLED
- QUEUED
- SCHEDULED
WorkflowKind:
type: string
enum:
+6
View File
@@ -116,6 +116,12 @@ paths:
$ref: "./paths/event/event.yaml#/keys"
/api/v1/tenants/{tenant}/workflows:
$ref: "./paths/workflow/workflow.yaml#/withTenant"
/api/v1/tenants/{tenant}/workflows/scheduled:
$ref: "./paths/workflow/workflow.yaml#/scheduledList"
/api/v1/tenants/{tenant}/workflows/scheduled/{scheduledId}:
$ref: "./paths/workflow/workflow.yaml#/scheduled"
/api/v1/tenants/{tenant}/workflows/crons:
$ref: "./paths/workflow/workflow.yaml#/cronsList"
/api/v1/tenants/{tenant}/workflows/cancel:
$ref: "./paths/workflow/workflow.yaml#/cancelWorkflowRuns"
/api/v1/workflows/{workflow}:
@@ -629,7 +629,7 @@ workflowRunsMetrics:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: Forbidden
summary: Get workflow runs
summary: Get workflow runs metrics
tags:
- Workflow
workflowRun:
@@ -826,3 +826,288 @@ workflowWorkersCount:
summary: Get workflow worker count
tags:
- Workflow
scheduledList:
get:
x-resources: ["tenant"]
description: Get all scheduled workflow runs for a tenant
operationId: workflow-scheduled:list
parameters:
- description: The tenant id
in: path
name: tenant
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: The number to skip
in: query
name: offset
required: false
schema:
type: integer
format: int64
- description: The number to limit by
in: query
name: limit
required: false
schema:
type: integer
format: int64
- description: The order by field
in: query
name: orderByField
required: false
schema:
$ref: "../../components/schemas/_index.yaml#/ScheduledWorkflowsOrderByField"
- description: The order by direction
in: query
name: orderByDirection
required: false
schema:
$ref: "../../components/schemas/_index.yaml#/WorkflowRunOrderByDirection"
- description: The workflow id to get runs for.
in: query
name: workflowId
required: false
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: The parent workflow run id
in: query
name: parentWorkflowRunId
required: false
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: The parent step run id
in: query
name: parentStepRunId
required: false
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: A list of metadata key value pairs to filter by
in: query
name: additionalMetadata
example: ["key1:value1", "key2:value2"]
required: false
schema:
type: array
items:
type: string
- description: A list of scheduled run statuses to filter by
in: query
name: statuses
required: false
schema:
type: array
items:
$ref: "../../components/schemas/_index.yaml#/ScheduledRunStatus"
responses:
"200":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/ScheduledWorkflowsList"
description: Successfully retrieved the workflow runs
"400":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: A malformed or bad request
"403":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: Forbidden
summary: Get scheduled workflow runs
tags:
- Workflow
scheduled:
get:
x-resources: ["tenant"]
description: Get a scheduled workflow run for a tenant
operationId: workflow-scheduled:get
parameters:
- description: The tenant id
in: path
name: tenant
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: The scheduled workflow id
in: path
name: scheduledId
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
responses:
"200":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/ScheduledWorkflows"
description: Successfully retrieved the workflow runs
"400":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: A malformed or bad request
"403":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: Forbidden
"404":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: Forbidden
summary: Get scheduled workflow run
tags:
- Workflow
delete:
x-resources: ["tenant", "scheduled-workflow-run"]
description: Delete a scheduled workflow run for a tenant
operationId: workflow-scheduled:delete
parameters:
- description: The tenant id
in: path
name: tenant
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: The scheduled workflow id
in: path
name: scheduledId
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
responses:
"204":
description: Successfully deleted the scheduled workflow run
"400":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: A malformed or bad request
"403":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIError"
description: Forbidden
summary: Delete scheduled workflow run
tags:
- Workflow
cronsList:
get:
x-resources: ["tenant"]
description: Get all cron job workflow runs for a tenant
operationId: cron-workflow:list
parameters:
- description: The tenant id
in: path
name: tenant
required: true
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: The number to skip
in: query
name: offset
required: false
schema:
type: integer
format: int64
- description: The number to limit by
in: query
name: limit
required: false
schema:
type: integer
format: int64
- description: The workflow id to get runs for.
in: query
name: workflowId
required: false
schema:
type: string
format: uuid
minLength: 36
maxLength: 36
- description: A list of metadata key value pairs to filter by
in: query
name: additionalMetadata
example: ["key1:value1", "key2:value2"]
required: false
schema:
type: array
items:
type: string
- description: The order by field
in: query
name: orderByField
required: false
schema:
$ref: "../../components/schemas/_index.yaml#/CronWorkflowsOrderByField"
- description: The order by direction
in: query
name: orderByDirection
required: false
schema:
$ref: "../../components/schemas/_index.yaml#/WorkflowRunOrderByDirection"
responses:
"200":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/CronWorkflowsList"
description: Successfully retrieved the workflow runs
"400":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: A malformed or bad request
"403":
content:
application/json:
schema:
$ref: "../../components/schemas/_index.yaml#/APIErrors"
description: Forbidden
summary: Get cron job workflows
tags:
- Workflow
+12 -1
View File
@@ -149,6 +149,15 @@ message ScheduleWorkflowRequest {
// (optional) the key for the child. if this is set, matches on the index or the
// child key will be a no-op, even if the schedule has changed.
optional string child_key = 7;
// (optional) the additional metadata for the workflow
optional string additional_metadata = 8;
}
// ScheduledWorkflow represents a scheduled workflow.
message ScheduledWorkflow {
string id = 1;
google.protobuf.Timestamp trigger_at = 2;
}
// WorkflowVersion represents the WorkflowVersion model.
@@ -157,10 +166,12 @@ message WorkflowVersion {
google.protobuf.Timestamp created_at = 2;
google.protobuf.Timestamp updated_at = 3;
string version = 5;
int32 order = 6;
int64 order = 6;
string workflow_id = 7;
repeated ScheduledWorkflow scheduled_workflows = 8;
}
// WorkflowTriggerEventRef represents the WorkflowTriggerEventRef model.
message WorkflowTriggerEventRef {
string parent_id = 1;
@@ -0,0 +1,29 @@
package workflows
import (
"context"
"time"
"github.com/labstack/echo/v4"
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/dbsqlc"
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
)
func (t *WorkflowService) WorkflowScheduledDelete(ctx echo.Context, request gen.WorkflowScheduledDeleteRequestObject) (gen.WorkflowScheduledDeleteResponseObject, error) {
_ = ctx.Get("tenant").(*db.TenantModel)
scheduled := ctx.Get("scheduled-workflow-run").(*dbsqlc.ListScheduledWorkflowsRow)
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 30*time.Second)
defer cancel()
err := t.config.APIRepository.WorkflowRun().DeleteScheduledWorkflow(dbCtx, sqlchelpers.UUIDToStr(scheduled.TenantId), request.ScheduledId.String())
if err != nil {
return nil, err
}
return gen.WorkflowScheduledDelete204Response{}, nil
}
@@ -0,0 +1,34 @@
package workflows
import (
"context"
"time"
"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"
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
)
func (t *WorkflowService) WorkflowScheduledGet(ctx echo.Context, request gen.WorkflowScheduledGetRequestObject) (gen.WorkflowScheduledGetResponseObject, error) {
tenant := ctx.Get("tenant").(*db.TenantModel)
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 30*time.Second)
defer cancel()
scheduled, err := t.config.APIRepository.WorkflowRun().GetScheduledWorkflow(dbCtx, tenant.ID, request.ScheduledId.String())
if err != nil {
return nil, err
}
if scheduled == nil {
return gen.WorkflowScheduledGet404JSONResponse(apierrors.NewAPIErrors("Scheduled workflow not found.")), nil
}
return gen.WorkflowScheduledGet200JSONResponse(
*transformers.ToScheduledWorkflowsFromSQLC(scheduled),
), nil
}
@@ -0,0 +1,111 @@
package workflows
import (
"context"
"fmt"
"math"
"strings"
"time"
"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"
"github.com/hatchet-dev/hatchet/pkg/repository"
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
)
func (t *WorkflowService) CronWorkflowList(ctx echo.Context, request gen.CronWorkflowListRequestObject) (gen.CronWorkflowListResponseObject, error) {
tenant := ctx.Get("tenant").(*db.TenantModel)
limit := 50
offset := 0
orderDirection := "DESC"
orderBy := "triggerAt"
listOpts := &repository.ListCronWorkflowsOpts{
Limit: &limit,
Offset: &offset,
OrderBy: &orderBy,
OrderDirection: &orderDirection,
}
if request.Params.OrderByField != nil {
orderBy = string(*request.Params.OrderByField)
listOpts.OrderBy = &orderBy
}
if request.Params.OrderByDirection != nil {
orderDirection = string(*request.Params.OrderByDirection)
listOpts.OrderDirection = &orderDirection
}
if request.Params.Limit != nil {
limit = int(*request.Params.Limit)
listOpts.Limit = &limit
}
if request.Params.Offset != nil {
offset = int(*request.Params.Offset)
listOpts.Offset = &offset
}
if request.Params.WorkflowId != nil {
workflowIdStr := request.Params.WorkflowId.String()
listOpts.WorkflowId = &workflowIdStr
}
if request.Params.AdditionalMetadata != nil {
additionalMetadata := make(map[string]interface{}, len(*request.Params.AdditionalMetadata))
for _, v := range *request.Params.AdditionalMetadata {
splitValue := strings.Split(fmt.Sprintf("%v", v), ":")
if len(splitValue) == 2 {
additionalMetadata[splitValue[0]] = splitValue[1]
} else {
return gen.CronWorkflowList400JSONResponse(apierrors.NewAPIErrors("Additional metadata filters must be in the format key:value.")), nil
}
}
listOpts.AdditionalMetadata = additionalMetadata
}
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 30*time.Second)
defer cancel()
scheduled, count, err := t.config.APIRepository.WorkflowRun().ListCronWorkflows(dbCtx, tenant.ID, listOpts)
if err != nil {
return nil, err
}
rows := make([]gen.CronWorkflows, len(scheduled))
for i, workflow := range scheduled {
workflowCp := workflow
rows[i] = *transformers.ToCronWorkflowsFromSQLC(workflowCp)
}
// use the total rows and limit to calculate the total pages
totalPages := int64(math.Ceil(float64(count) / float64(limit)))
currPage := 1 + int64(math.Ceil(float64(offset)/float64(limit)))
nextPage := currPage + 1
if currPage == totalPages {
nextPage = currPage
}
return gen.CronWorkflowList200JSONResponse(
gen.CronWorkflowsList{
Rows: &rows,
Pagination: &gen.PaginationResponse{
NumPages: &totalPages,
CurrentPage: &currPage,
NextPage: &nextPage,
},
},
), nil
}
@@ -0,0 +1,121 @@
package workflows
import (
"context"
"fmt"
"math"
"strings"
"time"
"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"
"github.com/hatchet-dev/hatchet/pkg/repository"
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
)
func (t *WorkflowService) WorkflowScheduledList(ctx echo.Context, request gen.WorkflowScheduledListRequestObject) (gen.WorkflowScheduledListResponseObject, error) {
tenant := ctx.Get("tenant").(*db.TenantModel)
limit := 50
offset := 0
orderDirection := "DESC"
orderBy := "triggerAt"
listOpts := &repository.ListScheduledWorkflowsOpts{
Limit: &limit,
Offset: &offset,
OrderBy: &orderBy,
OrderDirection: &orderDirection,
}
if request.Params.OrderByField != nil {
orderBy = string(*request.Params.OrderByField)
listOpts.OrderBy = &orderBy
}
if request.Params.OrderByDirection != nil {
orderDirection = string(*request.Params.OrderByDirection)
listOpts.OrderDirection = &orderDirection
}
if request.Params.Limit != nil {
limit = int(*request.Params.Limit)
listOpts.Limit = &limit
}
if request.Params.Offset != nil {
offset = int(*request.Params.Offset)
listOpts.Offset = &offset
}
if request.Params.WorkflowId != nil {
workflowIdStr := request.Params.WorkflowId.String()
listOpts.WorkflowId = &workflowIdStr
}
if request.Params.Statuses != nil {
statuses := make([]db.WorkflowRunStatus, len(*request.Params.Statuses))
for i, status := range *request.Params.Statuses {
statuses[i] = db.WorkflowRunStatus(status)
}
listOpts.Statuses = &statuses
}
if request.Params.AdditionalMetadata != nil {
additionalMetadata := make(map[string]interface{}, len(*request.Params.AdditionalMetadata))
for _, v := range *request.Params.AdditionalMetadata {
splitValue := strings.Split(fmt.Sprintf("%v", v), ":")
if len(splitValue) == 2 {
additionalMetadata[splitValue[0]] = splitValue[1]
} else {
return gen.WorkflowScheduledList400JSONResponse(apierrors.NewAPIErrors("Additional metadata filters must be in the format key:value.")), nil
}
}
listOpts.AdditionalMetadata = additionalMetadata
}
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 30*time.Second)
defer cancel()
scheduled, count, err := t.config.APIRepository.WorkflowRun().ListScheduledWorkflows(dbCtx, tenant.ID, listOpts)
if err != nil {
return nil, err
}
rows := make([]gen.ScheduledWorkflows, len(scheduled))
for i, workflow := range scheduled {
workflowCp := workflow
rows[i] = *transformers.ToScheduledWorkflowsFromSQLC(workflowCp)
}
// use the total rows and limit to calculate the total pages
totalPages := int64(math.Ceil(float64(count) / float64(limit)))
currPage := 1 + int64(math.Ceil(float64(offset)/float64(limit)))
nextPage := currPage + 1
if currPage == totalPages {
nextPage = currPage
}
return gen.WorkflowScheduledList200JSONResponse(
gen.ScheduledWorkflowsList{
Rows: &rows,
Pagination: &gen.PaginationResponse{
NumPages: &totalPages,
CurrentPage: &currPage,
NextPage: &nextPage,
},
},
), nil
}
File diff suppressed because it is too large Load Diff
@@ -504,3 +504,67 @@ func ToWorkflowRunFromSQLC(row *dbsqlc.ListWorkflowRunsRow) *gen.WorkflowRun {
return res
}
func ToScheduledWorkflowsFromSQLC(scheduled *dbsqlc.ListScheduledWorkflowsRow) *gen.ScheduledWorkflows {
var additionalMetadata map[string]interface{}
if scheduled.AdditionalMetadata != nil {
err := json.Unmarshal(scheduled.AdditionalMetadata, &additionalMetadata)
if err != nil {
return nil
}
}
var workflowRunStatus gen.WorkflowRunStatus
if scheduled.WorkflowRunStatus.Valid {
workflowRunStatus = gen.WorkflowRunStatus(scheduled.WorkflowRunStatus.WorkflowRunStatus)
}
var workflowRunIdPtr *uuid.UUID
if scheduled.WorkflowRunId.Valid {
workflowRunId := uuid.MustParse(sqlchelpers.UUIDToStr(scheduled.WorkflowRunId))
workflowRunIdPtr = &workflowRunId
}
res := &gen.ScheduledWorkflows{
Metadata: *toAPIMetadata(sqlchelpers.UUIDToStr(scheduled.ID), scheduled.CreatedAt.Time, scheduled.UpdatedAt.Time),
WorkflowVersionId: sqlchelpers.UUIDToStr(scheduled.WorkflowVersionId),
WorkflowId: sqlchelpers.UUIDToStr(scheduled.WorkflowId),
WorkflowName: scheduled.Name,
TenantId: sqlchelpers.UUIDToStr(scheduled.TenantId),
TriggerAt: scheduled.TriggerAt.Time,
AdditionalMetadata: &additionalMetadata,
WorkflowRunCreatedAt: &scheduled.WorkflowRunCreatedAt.Time,
WorkflowRunStatus: &workflowRunStatus,
WorkflowRunId: workflowRunIdPtr,
WorkflowRunName: &scheduled.WorkflowRunName.String,
}
return res
}
func ToCronWorkflowsFromSQLC(cron *dbsqlc.ListCronWorkflowsRow) *gen.CronWorkflows {
var additionalMetadata map[string]interface{}
if cron.AdditionalMetadata != nil {
err := json.Unmarshal(cron.AdditionalMetadata, &additionalMetadata)
if err != nil {
return nil
}
}
res := &gen.CronWorkflows{
Metadata: *toAPIMetadata(sqlchelpers.UUIDToStr(cron.ID), cron.CreatedAt.Time, cron.UpdatedAt.Time),
WorkflowVersionId: sqlchelpers.UUIDToStr(cron.WorkflowVersionId),
WorkflowId: sqlchelpers.UUIDToStr(cron.WorkflowId),
WorkflowName: cron.Name,
TenantId: sqlchelpers.UUIDToStr(cron.TenantId),
Cron: cron.Cron,
AdditionalMetadata: &additionalMetadata,
}
return res
}
+19
View File
@@ -252,6 +252,16 @@ func (t *APIServer) registerSpec(g *echo.Group, spec *openapi3.T) (*populator.Po
return workflowRun, sqlchelpers.UUIDToStr(workflowRun.TenantId), nil
})
populatorMW.RegisterGetter("scheduled-workflow-run", func(config *server.ServerConfig, parentId, id string) (result interface{}, uniqueParentId string, err error) {
scheduled, err := config.APIRepository.WorkflowRun().GetScheduledWorkflow(context.Background(), parentId, id)
if err != nil {
return nil, "", err
}
return scheduled, sqlchelpers.UUIDToStr(scheduled.TenantId), nil
})
populatorMW.RegisterGetter("step-run", func(config *server.ServerConfig, parentId, id string) (result interface{}, uniqueParentId string, err error) {
stepRun, err := config.APIRepository.StepRun().GetStepRunById(id)
@@ -295,6 +305,15 @@ func (t *APIServer) registerSpec(g *echo.Group, spec *openapi3.T) (*populator.Po
return webhookWorker, webhookWorker.TenantID, nil
})
populatorMW.RegisterGetter("webhook", func(config *server.ServerConfig, parentId, id string) (result interface{}, uniqueParentId string, err error) {
webhookWorker, err := config.APIRepository.WebhookWorker().GetWebhookWorkerByID(id)
if err != nil {
return nil, "", err
}
return webhookWorker, webhookWorker.TenantID, nil
})
authnMW := authn.NewAuthN(t.config)
authzMW := authz.NewAuthZ(t.config)
@@ -65,6 +65,10 @@ const RelativeDate: React.FC<RelativeDateProps> = ({
}
}, [formattedDate, future]);
if (date == '0001-01-01T00:00:00Z') {
return null;
}
return (
<TooltipProvider>
<Tooltip>
+154 -1
View File
@@ -24,6 +24,8 @@ import {
CreateTenantAlertEmailGroupRequest,
CreateTenantInviteRequest,
CreateTenantRequest,
CronWorkflowsList,
CronWorkflowsOrderByField,
Event,
EventData,
EventKey,
@@ -49,6 +51,10 @@ import {
ReplayWorkflowRunsRequest,
ReplayWorkflowRunsResponse,
RerunStepRunRequest,
ScheduledRunStatus,
ScheduledWorkflows,
ScheduledWorkflowsList,
ScheduledWorkflowsOrderByField,
SNSIntegration,
StepRun,
StepRunArchiveList,
@@ -1115,6 +1121,153 @@ export class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType
format: 'json',
...params,
});
/**
* @description Get all scheduled workflow runs for a tenant
*
* @tags Workflow
* @name WorkflowScheduledList
* @summary Get scheduled workflow runs
* @request GET:/api/v1/tenants/{tenant}/workflows/scheduled
* @secure
*/
workflowScheduledList = (
tenant: string,
query?: {
/**
* The number to skip
* @format int64
*/
offset?: number;
/**
* The number to limit by
* @format int64
*/
limit?: number;
/** The order by field */
orderByField?: ScheduledWorkflowsOrderByField;
/** The order by direction */
orderByDirection?: WorkflowRunOrderByDirection;
/**
* The workflow id to get runs for.
* @format uuid
* @minLength 36
* @maxLength 36
*/
workflowId?: string;
/**
* The parent workflow run id
* @format uuid
* @minLength 36
* @maxLength 36
*/
parentWorkflowRunId?: string;
/**
* The parent step run id
* @format uuid
* @minLength 36
* @maxLength 36
*/
parentStepRunId?: string;
/**
* A list of metadata key value pairs to filter by
* @example ["key1:value1","key2:value2"]
*/
additionalMetadata?: string[];
/** A list of scheduled run statuses to filter by */
statuses?: ScheduledRunStatus[];
},
params: RequestParams = {},
) =>
this.request<ScheduledWorkflowsList, APIErrors>({
path: `/api/v1/tenants/${tenant}/workflows/scheduled`,
method: 'GET',
query: query,
secure: true,
format: 'json',
...params,
});
/**
* @description Get a scheduled workflow run for a tenant
*
* @tags Workflow
* @name WorkflowScheduledGet
* @summary Get scheduled workflow run
* @request GET:/api/v1/tenants/{tenant}/workflows/scheduled/{scheduledId}
* @secure
*/
workflowScheduledGet = (tenant: string, scheduledId: string, params: RequestParams = {}) =>
this.request<ScheduledWorkflows, APIErrors>({
path: `/api/v1/tenants/${tenant}/workflows/scheduled/${scheduledId}`,
method: 'GET',
secure: true,
format: 'json',
...params,
});
/**
* @description Delete a scheduled workflow run for a tenant
*
* @tags Workflow
* @name WorkflowScheduledDelete
* @summary Delete scheduled workflow run
* @request DELETE:/api/v1/tenants/{tenant}/workflows/scheduled/{scheduledId}
* @secure
*/
workflowScheduledDelete = (tenant: string, scheduledId: string, params: RequestParams = {}) =>
this.request<void, APIErrors | APIError>({
path: `/api/v1/tenants/${tenant}/workflows/scheduled/${scheduledId}`,
method: 'DELETE',
secure: true,
...params,
});
/**
* @description Get all cron job workflow runs for a tenant
*
* @tags Workflow
* @name CronWorkflowList
* @summary Get cron job workflows
* @request GET:/api/v1/tenants/{tenant}/workflows/crons
* @secure
*/
cronWorkflowList = (
tenant: string,
query?: {
/**
* The number to skip
* @format int64
*/
offset?: number;
/**
* The number to limit by
* @format int64
*/
limit?: number;
/**
* The workflow id to get runs for.
* @format uuid
* @minLength 36
* @maxLength 36
*/
workflowId?: string;
/**
* A list of metadata key value pairs to filter by
* @example ["key1:value1","key2:value2"]
*/
additionalMetadata?: string[];
/** The order by field */
orderByField?: CronWorkflowsOrderByField;
/** The order by direction */
orderByDirection?: WorkflowRunOrderByDirection;
},
params: RequestParams = {},
) =>
this.request<CronWorkflowsList, APIErrors>({
path: `/api/v1/tenants/${tenant}/workflows/crons`,
method: 'GET',
query: query,
secure: true,
format: 'json',
...params,
});
/**
* @description Cancel a batch of workflow runs
*
@@ -1556,7 +1709,7 @@ export class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType
*
* @tags Workflow
* @name WorkflowRunGetMetrics
* @summary Get workflow runs
* @summary Get workflow runs metrics
* @request GET:/api/v1/tenants/{tenant}/workflows/runs/metrics
* @secure
*/
@@ -760,6 +760,69 @@ export interface WorkflowRunList {
pagination?: PaginationResponse;
}
export interface ScheduledWorkflows {
metadata: APIResourceMeta;
tenantId: string;
workflowVersionId: string;
workflowId: string;
workflowName: string;
/** @format date-time */
triggerAt: string;
input?: Record<string, any>;
additionalMetadata?: Record<string, any>;
/** @format date-time */
workflowRunCreatedAt?: string;
workflowRunName?: string;
workflowRunStatus?: WorkflowRunStatus;
/**
* @format uuid
* @minLength 36
* @maxLength 36
* @example "bb214807-246e-43a5-a25d-41761d1cff9e"
*/
workflowRunId?: string;
}
export interface ScheduledWorkflowsList {
rows?: ScheduledWorkflows[];
pagination?: PaginationResponse;
}
export enum ScheduledWorkflowsOrderByField {
TriggerAt = 'triggerAt',
CreatedAt = 'createdAt',
}
export enum ScheduledRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
QUEUED = 'QUEUED',
SCHEDULED = 'SCHEDULED',
}
export interface CronWorkflows {
metadata: APIResourceMeta;
tenantId: string;
workflowVersionId: string;
workflowId: string;
workflowName: string;
cron: string;
input?: Record<string, any>;
additionalMetadata?: Record<string, any>;
}
export interface CronWorkflowsList {
rows?: CronWorkflows[];
pagination?: PaginationResponse;
}
export enum CronWorkflowsOrderByField {
CreatedAt = 'createdAt',
}
export enum WorkflowRunOrderByField {
CreatedAt = 'createdAt',
StartedAt = 'startedAt',
+15
View File
@@ -14,6 +14,8 @@ type WorkflowRunMetrics = Parameters<typeof api.workflowRunGetMetrics>[1];
type WorkflowRunEventsMetrics = Parameters<
typeof cloudApi.workflowRunEventsGetMetrics
>[1];
type WorkflowScheduledQuery = Parameters<typeof api.workflowScheduledList>[1];
type CronWorkflowsQuery = Parameters<typeof api.cronWorkflowList>[1];
export const queries = createQueryKeyStore({
cloud: {
@@ -179,6 +181,19 @@ export const queries = createQueryKeyStore({
// ).data,
// }),
},
scheduledRuns: {
list: (tenant: string, query: WorkflowScheduledQuery) => ({
queryKey: ['scheduled-run:list', tenant, query],
queryFn: async () =>
(await api.workflowScheduledList(tenant, query)).data,
}),
},
cronRuns: {
list: (tenant: string, query: CronWorkflowsQuery) => ({
queryKey: ['cron-run:list', tenant, query],
queryFn: async () => (await api.cronWorkflowList(tenant, query)).data,
}),
},
workflowRuns: {
list: (tenant: string, query: ListWorkflowRunsQuery) => ({
queryKey: ['workflow-run:list', tenant, query],
+24 -2
View File
@@ -2,6 +2,7 @@ import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import {
AdjustmentsHorizontalIcon,
CalendarDaysIcon,
QueueListIcon,
ScaleIcon,
ServerStackIcon,
@@ -10,7 +11,7 @@ import {
import { Link, Outlet, useLocation, useOutletContext } from 'react-router-dom';
import { Tenant, TenantMember } from '@/lib/api';
import { GearIcon } from '@radix-ui/react-icons';
import { ClockIcon, GearIcon } from '@radix-ui/react-icons';
import React, { useCallback } from 'react';
import {
MembershipsContextType,
@@ -134,6 +135,27 @@ function Sidebar({ className, memberships, currTenant }: SidebarProps) {
/>
</div>
</div>
<div className="py-2">
<h2 className="mb-2 text-lg font-semibold tracking-tight">
Triggers
</h2>
<div className="space-y-1">
<SidebarButtonPrimary
key={4}
onNavLinkClick={onNavLinkClick}
to="/scheduled"
name="Scheduled Runs"
icon={<CalendarDaysIcon className="mr-2 h-4 w-4" />}
/>
<SidebarButtonPrimary
key={5}
onNavLinkClick={onNavLinkClick}
to="/cron-jobs"
name="Cron Jobs"
icon={<ClockIcon className="mr-2 h-4 w-4" />}
/>
</div>
</div>
<div className="py-2">
<h2 className="mb-2 text-lg font-semibold tracking-tight">
Resources
@@ -156,7 +178,7 @@ function Sidebar({ className, memberships, currTenant }: SidebarProps) {
collapsibleChildren={workers}
/>
<SidebarButtonPrimary
key={1}
key={3}
onNavLinkClick={onNavLinkClick}
to="/rate-limits"
name="Rate Limits"
@@ -0,0 +1,83 @@
import { ColumnDef } from '@tanstack/react-table';
import { DataTableColumnHeader } from '../../../../components/molecules/data-table/data-table-column-header';
import { CronWorkflows, RateLimit } from '@/lib/api';
import CronPrettifier from 'cronstrue';
import RelativeDate from '@/components/molecules/relative-date';
import { Link } from 'react-router-dom';
export type RateLimitRow = RateLimit & {
metadata: {
id: string;
};
};
export const columns: ColumnDef<CronWorkflows>[] = [
{
accessorKey: 'crons',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Cron" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
{row.original.cron}
</div>
),
enableSorting: false,
},
{
accessorKey: 'readable',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Readable" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
(runs {CronPrettifier.toString(row.original.cron).toLowerCase()} UTC)
</div>
),
enableSorting: false,
},
{
accessorKey: 'Workflow',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Workflow" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
<div className="cursor-pointer hover:underline min-w-fit whitespace-nowrap">
<Link to={`/workflows/${row.original.workflowId}`}>
{row.original.workflowName}
</Link>
</div>
</div>
),
enableSorting: false,
enableHiding: true,
},
// {
// accessorKey: 'Metadata',
// header: ({ column }) => (
// <DataTableColumnHeader column={column} title="Metadata" />
// ),
// cell: ({ row }) => {
// if (!row.original.additionalMetadata) {
// return <div></div>;
// }
// return <AdditionalMetadata metadata={row.original.additionalMetadata} />;
// },
// enableSorting: false,
// },
{
accessorKey: 'createdAt',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Created At" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
<RelativeDate date={row.original.metadata.createdAt} />
</div>
),
enableSorting: true,
enableHiding: true,
},
];
@@ -0,0 +1,140 @@
import { useEffect, useMemo, useState } from 'react';
import {
ColumnFiltersState,
PaginationState,
RowSelectionState,
SortingState,
VisibilityState,
} from '@tanstack/react-table';
import { useQuery } from '@tanstack/react-query';
import {
CronWorkflowsOrderByField,
WorkflowRunOrderByDirection,
queries,
} from '@/lib/api';
import invariant from 'tiny-invariant';
import { useOutletContext, useSearchParams } from 'react-router-dom';
import { TenantContextType } from '@/lib/outlet';
import { DataTable } from '@/components/molecules/data-table/data-table';
import { columns } from './recurring-columns';
export function CronsTable() {
const { tenant } = useOutletContext<TenantContextType>();
const [searchParams, setSearchParams] = useSearchParams();
invariant(tenant);
const [sorting, setSorting] = useState<SortingState>(() => {
const sortParam = searchParams.get('sort');
if (sortParam) {
const [id, desc] = sortParam.split(':');
return [{ id, desc: desc === 'desc' }];
}
return [];
});
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(() => {
const filtersParam = searchParams.get('filters');
if (filtersParam) {
return JSON.parse(filtersParam);
}
return [];
});
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({
createdAt: false,
});
const [pagination, setPagination] = useState<PaginationState>(() => {
const pageIndex = Number(searchParams.get('pageIndex')) || 0;
const pageSize = Number(searchParams.get('pageSize')) || 50;
return { pageIndex, pageSize };
});
const [pageSize, setPageSize] = useState<number>(
Number(searchParams.get('pageSize')) || 50,
);
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
useEffect(() => {
const newSearchParams = new URLSearchParams(searchParams);
newSearchParams.set(
'sort',
sorting.map((s) => `${s.id}:${s.desc ? 'desc' : 'asc'}`).join(','),
);
newSearchParams.set('filters', JSON.stringify(columnFilters));
newSearchParams.set('pageIndex', pagination.pageIndex.toString());
newSearchParams.set('pageSize', pagination.pageSize.toString());
setSearchParams(newSearchParams);
}, [sorting, columnFilters, pagination, setSearchParams, searchParams]);
const orderByDirection = useMemo(():
| WorkflowRunOrderByDirection
| undefined => {
if (!sorting.length) {
return;
}
return sorting[0]?.desc
? WorkflowRunOrderByDirection.DESC
: WorkflowRunOrderByDirection.ASC;
}, [sorting]);
const orderByField = useMemo((): CronWorkflowsOrderByField | undefined => {
if (!sorting.length) {
return;
}
switch (sorting[0]?.id) {
case 'triggerAt':
return CronWorkflowsOrderByField.CreatedAt;
default:
return CronWorkflowsOrderByField.CreatedAt;
}
}, [sorting]);
const offset = useMemo(() => {
if (!pagination) {
return;
}
return pagination.pageIndex * pagination.pageSize;
}, [pagination]);
const {
data,
isLoading: queryIsLoading,
error: queryError,
} = useQuery({
...queries.cronRuns.list(tenant.metadata.id, {
// TODO: add filters
orderByField,
orderByDirection,
offset,
limit: pageSize,
}),
refetchInterval: 2000,
});
return (
<DataTable
error={queryError}
isLoading={queryIsLoading}
columns={columns}
data={data?.rows || []}
filters={[]}
showColumnToggle={true}
columnVisibility={columnVisibility}
setColumnVisibility={setColumnVisibility}
sorting={sorting}
setSorting={setSorting}
columnFilters={columnFilters}
setColumnFilters={setColumnFilters}
pagination={pagination}
setPagination={setPagination}
onSetPageSize={setPageSize}
pageCount={data?.pagination?.num_pages || 0}
rowSelection={rowSelection}
setRowSelection={setRowSelection}
getRowId={(row) => row.metadata.id}
/>
);
}
@@ -0,0 +1,16 @@
import { Separator } from '@/components/ui/separator';
import { CronsTable } from './components/recurring-table';
export default function Crons() {
return (
<div className="flex-grow h-full w-full">
<div className="mx-auto max-w-7xl py-8 px-4 sm:px-6 lg:px-8">
<h2 className="text-2xl font-bold leading-tight text-foreground">
Cron Jobs
</h2>
<Separator className="my-4" />
<CronsTable />
</div>
</div>
);
}
@@ -0,0 +1,114 @@
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Spinner } from '@/components/ui/loading';
import api, { ScheduledWorkflows } from '@/lib/api';
import { useApiError } from '@/lib/hooks';
import { useMutation } from '@tanstack/react-query';
interface DeleteScheduledRunFormProps {
isFutureRun: boolean;
className?: string;
onCancel: () => void;
isLoading: boolean;
onSubmit: () => void;
}
export function DeleteScheduledRun({
tenant,
scheduledRun,
setShowScheduledRunRevoke,
onSuccess,
}: {
tenant: string;
scheduledRun?: ScheduledWorkflows;
setShowScheduledRunRevoke: (show?: ScheduledWorkflows) => void;
onSuccess: () => void;
}) {
const { handleApiError } = useApiError({});
const deleteMutation = useMutation({
mutationKey: ['scheduled-run:delete', tenant, scheduledRun],
mutationFn: async () => {
if (!scheduledRun) {
return;
}
await api.workflowScheduledDelete(tenant, scheduledRun.metadata.id);
},
onSuccess: onSuccess,
onError: handleApiError,
});
return (
<Dialog
open={!!scheduledRun}
onOpenChange={(open) =>
setShowScheduledRunRevoke(open ? scheduledRun : undefined)
}
>
<DeleteScheduledRunForm
isLoading={deleteMutation.isPending}
onSubmit={() => deleteMutation.mutate()}
onCancel={() => setShowScheduledRunRevoke(undefined)}
isFutureRun={
scheduledRun?.triggerAt
? new Date(scheduledRun.triggerAt) > new Date()
: false
}
/>
</Dialog>
);
}
export function DeleteScheduledRunForm({
className,
isFutureRun,
...props
}: DeleteScheduledRunFormProps) {
return (
<DialogContent className="w-fit max-w-[80%] min-w-[500px]">
<DialogHeader>
<DialogTitle>Delete scheduled run</DialogTitle>
</DialogHeader>
<div>
<div className="text-sm text-foreground mb-4">
Are you sure you want to delete the scheduled run?
{isFutureRun ? (
<>
This action will prevent the run from running in the future and
cannot be undone.
</>
) : (
<>
This action will delete the scheduled run trigger, but will not
affect the run itself and cannot be undone.
</>
)}
</div>
<div className="flex flex-row gap-4 justify-end">
<Button
variant="ghost"
onClick={() => {
props.onCancel();
}}
>
Cancel
</Button>
<Button
variant="destructive"
onClick={() => {
props.onSubmit();
}}
>
{props.isLoading && <Spinner />}
Delete scheduled run
</Button>
</div>
</div>
</DialogContent>
);
}
@@ -0,0 +1,124 @@
import { ColumnDef } from '@tanstack/react-table';
import { DataTableColumnHeader } from '../../../../components/molecules/data-table/data-table-column-header';
import { RateLimit, ScheduledWorkflows } from '@/lib/api';
import RelativeDate from '@/components/molecules/relative-date';
import { AdditionalMetadata } from '../../events/components/additional-metadata';
import { RunStatus } from '../../workflow-runs/components/run-statuses';
import { Link } from 'react-router-dom';
import { DataTableRowActions } from '@/components/molecules/data-table/data-table-row-actions';
export type RateLimitRow = RateLimit & {
metadata: {
id: string;
};
};
export const columns = ({
onDeleteClick,
}: {
onDeleteClick: (row: ScheduledWorkflows) => void;
}): ColumnDef<ScheduledWorkflows>[] => {
return [
{
accessorKey: 'runId',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Run ID" />
),
cell: ({ row }) => {
return row.original.workflowRunId ? (
<Link to={`/workflow-runs/${row.original.workflowRunId}`}>
<div className="cursor-pointer hover:underline min-w-fit whitespace-nowrap">
{row.original.workflowRunName}
</div>
</Link>
) : null;
},
},
{
accessorKey: 'status',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Status" />
),
cell: ({ row }) => (
<RunStatus status={row.original.workflowRunStatus || 'SCHEDULED'} />
),
},
{
accessorKey: 'triggerAt',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Trigger At" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
<RelativeDate date={row.original.triggerAt} />
</div>
),
},
{
accessorKey: 'Workflow',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Workflow" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
<div className="cursor-pointer hover:underline min-w-fit whitespace-nowrap">
<a href={`/workflows/${row.original.workflowId}`}>
{row.original.workflowName}
</a>
</div>
</div>
),
enableSorting: false,
enableHiding: true,
},
{
accessorKey: 'Metadata',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Metadata" />
),
cell: ({ row }) => {
if (!row.original.additionalMetadata) {
return <div></div>;
}
return (
<AdditionalMetadata metadata={row.original.additionalMetadata} />
);
},
enableSorting: false,
},
{
accessorKey: 'createdAt',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Created At" />
),
cell: ({ row }) => (
<div className="flex flex-row items-center gap-4 pl-4">
<RelativeDate date={row.original.metadata.createdAt} />
</div>
),
enableSorting: true,
enableHiding: true,
},
{
accessorKey: 'actions',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Actions" />
),
cell: ({ row }) => (
<div className="flex flex-row justify-center">
<DataTableRowActions
row={row}
actions={[
{
label: 'Delete',
onClick: () => onDeleteClick(row.original),
},
]}
/>
</div>
),
enableHiding: true,
enableSorting: false,
},
];
};
@@ -0,0 +1,364 @@
import { DataTable } from '@/components/molecules/data-table/data-table.tsx';
import { useEffect, useMemo, useState } from 'react';
import {
ColumnFiltersState,
PaginationState,
RowSelectionState,
SortingState,
VisibilityState,
} from '@tanstack/react-table';
import { useQuery } from '@tanstack/react-query';
import invariant from 'tiny-invariant';
import {
ScheduledRunStatus,
ScheduledWorkflows,
ScheduledWorkflowsOrderByField,
WorkflowRunOrderByDirection,
queries,
} from '@/lib/api';
import { TenantContextType } from '@/lib/outlet';
import { useOutletContext, useSearchParams } from 'react-router-dom';
import {
FilterOption,
ToolbarFilters,
ToolbarType,
} from '@/components/molecules/data-table/data-table-toolbar';
import { Button } from '@/components/ui/button';
import { ArrowPathIcon } from '@heroicons/react/24/outline';
import { columns } from './scheduled-runs-columns';
import { DeleteScheduledRun } from './delete-scheduled-runs';
export interface ScheduledWorkflowRunsTableProps {
createdAfter?: string;
createdBefore?: string;
workflowId?: string;
parentWorkflowRunId?: string;
parentStepRunId?: string;
initColumnVisibility?: VisibilityState;
filterVisibility?: { [key: string]: boolean };
refetchInterval?: number;
showMetrics?: boolean;
}
export function ScheduledRunsTable({
workflowId,
initColumnVisibility = {
createdAt: false,
},
filterVisibility = {},
parentWorkflowRunId,
parentStepRunId,
refetchInterval = 5000,
}: ScheduledWorkflowRunsTableProps) {
const [searchParams, setSearchParams] = useSearchParams();
const { tenant } = useOutletContext<TenantContextType>();
invariant(tenant);
const [sorting, setSorting] = useState<SortingState>(() => {
const sortParam = searchParams.get('sort');
if (sortParam) {
return sortParam.split(',').map((param) => {
const [id, desc] = param.split(':');
return { id, desc: desc === 'desc' };
});
}
return [];
});
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(() => {
const filtersParam = searchParams.get('filters');
if (filtersParam) {
return JSON.parse(filtersParam);
}
return [];
});
const [columnVisibility, setColumnVisibility] =
useState<VisibilityState>(initColumnVisibility);
const [pagination, setPagination] = useState<PaginationState>(() => {
const pageIndex = Number(searchParams.get('pageIndex')) || 0;
const pageSize = Number(searchParams.get('pageSize')) || 50;
return { pageIndex, pageSize };
});
useEffect(() => {
const newSearchParams = new URLSearchParams(searchParams);
if (sorting.length) {
newSearchParams.set(
'orderDirection',
sorting.map((s) => `${s.id}:${s.desc ? 'desc' : 'asc'}`).join(','),
);
} else {
newSearchParams.delete('orderDirection');
}
if (columnFilters.length) {
newSearchParams.set('filters', JSON.stringify(columnFilters));
} else {
newSearchParams.delete('filters');
}
newSearchParams.set('pageIndex', pagination.pageIndex.toString());
newSearchParams.set('pageSize', pagination.pageSize.toString());
if (newSearchParams.toString() !== searchParams.toString()) {
setSearchParams(newSearchParams, { replace: true });
}
}, [sorting, columnFilters, pagination, setSearchParams, searchParams]);
const [pageSize, setPageSize] = useState<number>(50);
const offset = useMemo(() => {
if (!pagination) {
return;
}
return pagination.pageIndex * pagination.pageSize;
}, [pagination]);
const workflow = useMemo<string | undefined>(() => {
if (workflowId) {
return workflowId;
}
const filter = columnFilters.find((filter) => filter.id === 'Workflow');
if (!filter) {
return;
}
const vals = filter?.value as Array<string>;
return vals[0];
}, [columnFilters, workflowId]);
const statuses = useMemo(() => {
const filter = columnFilters.find((filter) => filter.id === 'status');
if (!filter) {
return;
}
return filter?.value as Array<ScheduledRunStatus>;
}, [columnFilters]);
const AdditionalMetadataFilter = useMemo(() => {
const filter = columnFilters.find((filter) => filter.id === 'Metadata');
if (!filter) {
return;
}
return filter?.value as Array<string>;
}, [columnFilters]);
const orderByDirection = useMemo(():
| WorkflowRunOrderByDirection
| undefined => {
if (!sorting.length) {
return;
}
return sorting[0]?.desc
? WorkflowRunOrderByDirection.DESC
: WorkflowRunOrderByDirection.ASC;
}, [sorting]);
const orderByField = useMemo(():
| ScheduledWorkflowsOrderByField
| undefined => {
if (!sorting.length) {
return;
}
switch (sorting[0]?.id) {
case 'createdAt':
return ScheduledWorkflowsOrderByField.CreatedAt;
case 'triggerAt':
default:
return ScheduledWorkflowsOrderByField.TriggerAt;
}
}, [sorting]);
const listWorkflowRunsQuery = useQuery({
...queries.scheduledRuns.list(tenant.metadata.id, {
offset,
limit: pageSize,
statuses,
workflowId: workflow,
parentWorkflowRunId,
parentStepRunId,
orderByDirection,
orderByField,
additionalMetadata: AdditionalMetadataFilter,
}),
placeholderData: (prev) => prev,
refetchInterval,
});
const {
data: workflowKeys,
isLoading: workflowKeysIsLoading,
error: workflowKeysError,
} = useQuery({
...queries.workflows.list(tenant.metadata.id),
});
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
// const selectedRuns = useMemo(() => {
// return Object.entries(rowSelection)
// .filter(([, selected]) => !!selected)
// .map(([id]) => (listWorkflowRunsQuery.data?.rows || [])[Number(id)]);
// }, [listWorkflowRunsQuery.data?.rows, rowSelection]);
// const { handleApiError } = useApiError({});
// const cancelWorkflowRunMutation = useMutation({
// mutationKey: ['workflow-run:cancel', tenant.metadata.id, selectedRuns],
// mutationFn: async () => {
// const tenantId = tenant.metadata.id;
// const workflowRunIds = selectedRuns.map((wr) => wr.metadata.id);
// invariant(tenantId, 'has tenantId');
// invariant(workflowRunIds, 'has runIds');
// const res = await api.workflowRunCancel(tenantId, {
// workflowRunIds,
// });
// return res.data;
// },
// onSuccess: () => {
// queryClient.invalidateQueries({
// queryKey: queries.workflowRuns.list(tenant.metadata.id, {}).queryKey,
// });
// },
// onError: handleApiError,
// });
const workflowKeyFilters = useMemo((): FilterOption[] => {
return (
workflowKeys?.rows?.map((key) => ({
value: key.metadata.id,
label: key.name,
})) || []
);
}, [workflowKeys]);
const workflowRunStatusFilters = useMemo((): FilterOption[] => {
return [
{
value: ScheduledRunStatus.SCHEDULED,
label: 'Scheduled',
},
{
value: ScheduledRunStatus.SUCCEEDED,
label: 'Succeeded',
},
{
value: ScheduledRunStatus.FAILED,
label: 'Failed',
},
{
value: ScheduledRunStatus.RUNNING,
label: 'Running',
},
{
value: ScheduledRunStatus.QUEUED,
label: 'Queued',
},
{
value: ScheduledRunStatus.PENDING,
label: 'Pending',
},
];
}, []);
const filters: ToolbarFilters = [
{
columnId: 'Workflow',
title: 'Workflow',
options: workflowKeyFilters,
type: ToolbarType.Radio,
},
{
columnId: 'status',
title: 'Status',
options: workflowRunStatusFilters,
},
{
columnId: 'Metadata',
title: 'Metadata',
type: ToolbarType.KeyValue,
},
].filter((filter) => filterVisibility[filter.columnId] != false);
const [rotate, setRotate] = useState(false);
const refetch = () => {
listWorkflowRunsQuery.refetch();
};
const actions = [
<Button
key="refresh"
className="h-8 px-2 lg:px-3"
size="sm"
onClick={() => {
refetch();
setRotate(!rotate);
}}
variant={'outline'}
aria-label="Refresh events list"
>
<ArrowPathIcon
className={`h-4 w-4 transition-transform ${rotate ? 'rotate-180' : ''}`}
/>
</Button>,
];
const [showScheduledRunRevoke, setShowScheduledRunRevoke] = useState<
ScheduledWorkflows | undefined
>(undefined);
const isLoading = listWorkflowRunsQuery.isFetching || workflowKeysIsLoading;
return (
<>
<DeleteScheduledRun
tenant={tenant.metadata.id}
scheduledRun={showScheduledRunRevoke}
setShowScheduledRunRevoke={setShowScheduledRunRevoke}
onSuccess={() => {
refetch();
setShowScheduledRunRevoke(undefined);
}}
/>
<DataTable
emptyState={<>No workflow runs found with the given filters.</>}
error={workflowKeysError}
isLoading={isLoading}
columns={columns({
onDeleteClick: (row) => {
setShowScheduledRunRevoke(row);
},
})}
columnVisibility={columnVisibility}
setColumnVisibility={setColumnVisibility}
data={listWorkflowRunsQuery.data?.rows || []}
filters={filters}
actions={actions}
sorting={sorting}
setSorting={setSorting}
columnFilters={columnFilters}
setColumnFilters={setColumnFilters}
pagination={pagination}
setPagination={setPagination}
onSetPageSize={setPageSize}
rowSelection={rowSelection}
setRowSelection={setRowSelection}
pageCount={listWorkflowRunsQuery.data?.pagination?.num_pages || 0}
showColumnToggle={true}
/>
</>
);
}
@@ -0,0 +1,16 @@
import { Separator } from '@/components/ui/separator';
import { ScheduledRunsTable } from './components/scheduled-runs-table';
export default function RateLimits() {
return (
<div className="flex-grow h-full w-full">
<div className="mx-auto max-w-7xl py-8 px-4 sm:px-6 lg:px-8">
<h2 className="text-2xl font-bold leading-tight text-foreground">
Scheduled Runs
</h2>
<Separator className="my-4" />
<ScheduledRunsTable />
</div>
</div>
);
}
@@ -8,7 +8,8 @@ import {
import { JobRunStatus, StepRunStatus, WorkflowRunStatus } from '@/lib/api';
import { capitalize, cn } from '@/lib/utils';
type RunStatusType = `${StepRunStatus | WorkflowRunStatus | JobRunStatus}`;
type RunStatusType =
`${StepRunStatus | WorkflowRunStatus | JobRunStatus | 'SCHEDULED'}`;
type RunStatusVariant = {
text: string;
@@ -52,6 +53,10 @@ const RUN_STATUS_VARIANTS: Record<RunStatusType, RunStatusVariant> = {
text: 'Assigned',
variant: 'inProgress',
},
SCHEDULED: {
text: 'Scheduled',
variant: 'outline',
},
};
const RUN_STATUS_REASONS: Record<string, string> = {
+18
View File
@@ -132,6 +132,24 @@ const routes: RouteObject[] = [
};
}),
},
{
path: '/scheduled',
lazy: async () =>
import('./pages/main/scheduled-runs').then((res) => {
return {
Component: res.default,
};
}),
},
{
path: '/cron-jobs',
lazy: async () =>
import('./pages/main/recurring').then((res) => {
return {
Component: res.default,
};
}),
},
{
path: '/workflows',
lazy: async () =>
+319 -216
View File
@@ -969,6 +969,8 @@ type ScheduleWorkflowRequest struct {
// (optional) the key for the child. if this is set, matches on the index or the
// child key will be a no-op, even if the schedule has changed.
ChildKey *string `protobuf:"bytes,7,opt,name=child_key,json=childKey,proto3,oneof" json:"child_key,omitempty"`
// (optional) the additional metadata for the workflow
AdditionalMetadata *string `protobuf:"bytes,8,opt,name=additional_metadata,json=additionalMetadata,proto3,oneof" json:"additional_metadata,omitempty"`
}
func (x *ScheduleWorkflowRequest) Reset() {
@@ -1052,24 +1054,88 @@ func (x *ScheduleWorkflowRequest) GetChildKey() string {
return ""
}
func (x *ScheduleWorkflowRequest) GetAdditionalMetadata() string {
if x != nil && x.AdditionalMetadata != nil {
return *x.AdditionalMetadata
}
return ""
}
// ScheduledWorkflow represents a scheduled workflow.
type ScheduledWorkflow struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
TriggerAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=trigger_at,json=triggerAt,proto3" json:"trigger_at,omitempty"`
}
func (x *ScheduledWorkflow) Reset() {
*x = ScheduledWorkflow{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ScheduledWorkflow) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ScheduledWorkflow) ProtoMessage() {}
func (x *ScheduledWorkflow) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ScheduledWorkflow.ProtoReflect.Descriptor instead.
func (*ScheduledWorkflow) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{9}
}
func (x *ScheduledWorkflow) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *ScheduledWorkflow) GetTriggerAt() *timestamppb.Timestamp {
if x != nil {
return x.TriggerAt
}
return nil
}
// WorkflowVersion represents the WorkflowVersion model.
type WorkflowVersion struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"`
Order int32 `protobuf:"varint,6,opt,name=order,proto3" json:"order,omitempty"`
WorkflowId string `protobuf:"bytes,7,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"`
Order int64 `protobuf:"varint,6,opt,name=order,proto3" json:"order,omitempty"`
WorkflowId string `protobuf:"bytes,7,opt,name=workflow_id,json=workflowId,proto3" json:"workflow_id,omitempty"`
ScheduledWorkflows []*ScheduledWorkflow `protobuf:"bytes,8,rep,name=scheduled_workflows,json=scheduledWorkflows,proto3" json:"scheduled_workflows,omitempty"`
}
func (x *WorkflowVersion) Reset() {
*x = WorkflowVersion{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[9]
mi := &file_workflows_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1082,7 +1148,7 @@ func (x *WorkflowVersion) String() string {
func (*WorkflowVersion) ProtoMessage() {}
func (x *WorkflowVersion) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[9]
mi := &file_workflows_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1095,7 +1161,7 @@ func (x *WorkflowVersion) ProtoReflect() protoreflect.Message {
// Deprecated: Use WorkflowVersion.ProtoReflect.Descriptor instead.
func (*WorkflowVersion) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{9}
return file_workflows_proto_rawDescGZIP(), []int{10}
}
func (x *WorkflowVersion) GetId() string {
@@ -1126,7 +1192,7 @@ func (x *WorkflowVersion) GetVersion() string {
return ""
}
func (x *WorkflowVersion) GetOrder() int32 {
func (x *WorkflowVersion) GetOrder() int64 {
if x != nil {
return x.Order
}
@@ -1140,6 +1206,13 @@ func (x *WorkflowVersion) GetWorkflowId() string {
return ""
}
func (x *WorkflowVersion) GetScheduledWorkflows() []*ScheduledWorkflow {
if x != nil {
return x.ScheduledWorkflows
}
return nil
}
// WorkflowTriggerEventRef represents the WorkflowTriggerEventRef model.
type WorkflowTriggerEventRef struct {
state protoimpl.MessageState
@@ -1153,7 +1226,7 @@ type WorkflowTriggerEventRef struct {
func (x *WorkflowTriggerEventRef) Reset() {
*x = WorkflowTriggerEventRef{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[10]
mi := &file_workflows_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1166,7 +1239,7 @@ func (x *WorkflowTriggerEventRef) String() string {
func (*WorkflowTriggerEventRef) ProtoMessage() {}
func (x *WorkflowTriggerEventRef) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[10]
mi := &file_workflows_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1179,7 +1252,7 @@ func (x *WorkflowTriggerEventRef) ProtoReflect() protoreflect.Message {
// Deprecated: Use WorkflowTriggerEventRef.ProtoReflect.Descriptor instead.
func (*WorkflowTriggerEventRef) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{10}
return file_workflows_proto_rawDescGZIP(), []int{11}
}
func (x *WorkflowTriggerEventRef) GetParentId() string {
@@ -1209,7 +1282,7 @@ type WorkflowTriggerCronRef struct {
func (x *WorkflowTriggerCronRef) Reset() {
*x = WorkflowTriggerCronRef{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[11]
mi := &file_workflows_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1222,7 +1295,7 @@ func (x *WorkflowTriggerCronRef) String() string {
func (*WorkflowTriggerCronRef) ProtoMessage() {}
func (x *WorkflowTriggerCronRef) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[11]
mi := &file_workflows_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1235,7 +1308,7 @@ func (x *WorkflowTriggerCronRef) ProtoReflect() protoreflect.Message {
// Deprecated: Use WorkflowTriggerCronRef.ProtoReflect.Descriptor instead.
func (*WorkflowTriggerCronRef) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{11}
return file_workflows_proto_rawDescGZIP(), []int{12}
}
func (x *WorkflowTriggerCronRef) GetParentId() string {
@@ -1263,7 +1336,7 @@ type BulkTriggerWorkflowRequest struct {
func (x *BulkTriggerWorkflowRequest) Reset() {
*x = BulkTriggerWorkflowRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[12]
mi := &file_workflows_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1276,7 +1349,7 @@ func (x *BulkTriggerWorkflowRequest) String() string {
func (*BulkTriggerWorkflowRequest) ProtoMessage() {}
func (x *BulkTriggerWorkflowRequest) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[12]
mi := &file_workflows_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1289,7 +1362,7 @@ func (x *BulkTriggerWorkflowRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use BulkTriggerWorkflowRequest.ProtoReflect.Descriptor instead.
func (*BulkTriggerWorkflowRequest) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{12}
return file_workflows_proto_rawDescGZIP(), []int{13}
}
func (x *BulkTriggerWorkflowRequest) GetWorkflows() []*TriggerWorkflowRequest {
@@ -1310,7 +1383,7 @@ type BulkTriggerWorkflowResponse struct {
func (x *BulkTriggerWorkflowResponse) Reset() {
*x = BulkTriggerWorkflowResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[13]
mi := &file_workflows_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1323,7 +1396,7 @@ func (x *BulkTriggerWorkflowResponse) String() string {
func (*BulkTriggerWorkflowResponse) ProtoMessage() {}
func (x *BulkTriggerWorkflowResponse) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[13]
mi := &file_workflows_proto_msgTypes[14]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1336,7 +1409,7 @@ func (x *BulkTriggerWorkflowResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use BulkTriggerWorkflowResponse.ProtoReflect.Descriptor instead.
func (*BulkTriggerWorkflowResponse) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{13}
return file_workflows_proto_rawDescGZIP(), []int{14}
}
func (x *BulkTriggerWorkflowResponse) GetWorkflowRunIds() []string {
@@ -1378,7 +1451,7 @@ type TriggerWorkflowRequest struct {
func (x *TriggerWorkflowRequest) Reset() {
*x = TriggerWorkflowRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[14]
mi := &file_workflows_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1391,7 +1464,7 @@ func (x *TriggerWorkflowRequest) String() string {
func (*TriggerWorkflowRequest) ProtoMessage() {}
func (x *TriggerWorkflowRequest) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[14]
mi := &file_workflows_proto_msgTypes[15]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1404,7 +1477,7 @@ func (x *TriggerWorkflowRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use TriggerWorkflowRequest.ProtoReflect.Descriptor instead.
func (*TriggerWorkflowRequest) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{14}
return file_workflows_proto_rawDescGZIP(), []int{15}
}
func (x *TriggerWorkflowRequest) GetName() string {
@@ -1481,7 +1554,7 @@ type TriggerWorkflowResponse struct {
func (x *TriggerWorkflowResponse) Reset() {
*x = TriggerWorkflowResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[15]
mi := &file_workflows_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1494,7 +1567,7 @@ func (x *TriggerWorkflowResponse) String() string {
func (*TriggerWorkflowResponse) ProtoMessage() {}
func (x *TriggerWorkflowResponse) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[15]
mi := &file_workflows_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1507,7 +1580,7 @@ func (x *TriggerWorkflowResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use TriggerWorkflowResponse.ProtoReflect.Descriptor instead.
func (*TriggerWorkflowResponse) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{15}
return file_workflows_proto_rawDescGZIP(), []int{16}
}
func (x *TriggerWorkflowResponse) GetWorkflowRunId() string {
@@ -1533,7 +1606,7 @@ type PutRateLimitRequest struct {
func (x *PutRateLimitRequest) Reset() {
*x = PutRateLimitRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[16]
mi := &file_workflows_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1546,7 +1619,7 @@ func (x *PutRateLimitRequest) String() string {
func (*PutRateLimitRequest) ProtoMessage() {}
func (x *PutRateLimitRequest) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[16]
mi := &file_workflows_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1559,7 +1632,7 @@ func (x *PutRateLimitRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use PutRateLimitRequest.ProtoReflect.Descriptor instead.
func (*PutRateLimitRequest) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{16}
return file_workflows_proto_rawDescGZIP(), []int{17}
}
func (x *PutRateLimitRequest) GetKey() string {
@@ -1592,7 +1665,7 @@ type PutRateLimitResponse struct {
func (x *PutRateLimitResponse) Reset() {
*x = PutRateLimitResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_workflows_proto_msgTypes[17]
mi := &file_workflows_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1605,7 +1678,7 @@ func (x *PutRateLimitResponse) String() string {
func (*PutRateLimitResponse) ProtoMessage() {}
func (x *PutRateLimitResponse) ProtoReflect() protoreflect.Message {
mi := &file_workflows_proto_msgTypes[17]
mi := &file_workflows_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1618,7 +1691,7 @@ func (x *PutRateLimitResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use PutRateLimitResponse.ProtoReflect.Descriptor instead.
func (*PutRateLimitResponse) Descriptor() ([]byte, []int) {
return file_workflows_proto_rawDescGZIP(), []int{17}
return file_workflows_proto_rawDescGZIP(), []int{18}
}
var File_workflows_proto protoreflect.FileDescriptor
@@ -1768,7 +1841,7 @@ var file_workflows_proto_rawDesc = []byte{
0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0b, 0x0a, 0x09,
0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x4c, 0x69, 0x73,
0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x22, 0xdc, 0x02, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x57, 0x6f,
0x74, 0x22, 0xaa, 0x03, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x12, 0x38, 0x0a, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02,
@@ -1785,143 +1858,158 @@ var file_workflows_proto_rawDesc = []byte{
0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x68,
0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x63,
0x68, 0x69, 0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03,
0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a,
0x0a, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x42, 0x15, 0x0a, 0x13, 0x5f,
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x72, 0x75, 0x6e, 0x5f,
0x69, 0x64, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79,
0x22, 0xe8, 0x01, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f,
0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12,
0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20,
0x01, 0x28, 0x05, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x22, 0x53, 0x0a, 0x17, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x45, 0x76,
0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79,
0x22, 0x49, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x72, 0x69, 0x67,
0x67, 0x65, 0x72, 0x43, 0x72, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61,
0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x22, 0x53, 0x0a, 0x1a, 0x42,
0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x09, 0x77, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x54,
0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73,
0x22, 0x47, 0x0a, 0x1b, 0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x28, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f,
0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x73, 0x22, 0xe4, 0x03, 0x0a, 0x16, 0x54, 0x72,
0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x20,
0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01,
0x12, 0x30, 0x0a, 0x12, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f,
0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0f,
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x88,
0x01, 0x01, 0x12, 0x24, 0x0a, 0x0b, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x64, 0x65,
0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x68, 0x69, 0x6c, 0x64,
0x49, 0x6e, 0x64, 0x65, 0x78, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x68, 0x69, 0x6c,
0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x08, 0x63,
0x68, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x13, 0x61, 0x64,
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x12, 0x61, 0x64, 0x64, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01,
0x12, 0x2f, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6b,
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x05, 0x52, 0x0f, 0x64,
0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01,
0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20,
0x01, 0x28, 0x05, 0x48, 0x06, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x88,
0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x42, 0x15, 0x0a, 0x13, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70,
0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x68, 0x69, 0x6c,
0x64, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x68, 0x69, 0x6c,
0x64, 0x5f, 0x6b, 0x65, 0x79, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x14, 0x0a,
0x12, 0x5f, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x5f, 0x69, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
0x22, 0x41, 0x0a, 0x17, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x77,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75,
0x6e, 0x49, 0x64, 0x22, 0x6d, 0x0a, 0x13, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x12, 0x2e, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74,
0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d,
0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x24, 0x0a, 0x0e, 0x53, 0x74,
0x69, 0x63, 0x6b, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04,
0x53, 0x4f, 0x46, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x41, 0x52, 0x44, 0x10, 0x01,
0x2a, 0x32, 0x0a, 0x0c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4b, 0x69, 0x6e, 0x64,
0x12, 0x0c, 0x0a, 0x08, 0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0b,
0x0a, 0x07, 0x44, 0x55, 0x52, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x44,
0x41, 0x47, 0x10, 0x02, 0x2a, 0x6c, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65,
0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x12, 0x16, 0x0a, 0x12, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52,
0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x52, 0x4f, 0x50,
0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x51, 0x55, 0x45,
0x55, 0x45, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x47,
0x52, 0x4f, 0x55, 0x50, 0x5f, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x4f, 0x42, 0x49, 0x4e,
0x10, 0x03, 0x2a, 0x85, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62,
0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x09, 0x0a, 0x05,
0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x45,
0x51, 0x55, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x52, 0x45, 0x41, 0x54, 0x45,
0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x52, 0x45, 0x41,
0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f, 0x45, 0x51, 0x55, 0x41,
0x4c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x41, 0x4e,
0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x5f,
0x4f, 0x52, 0x5f, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x05, 0x2a, 0x5d, 0x0a, 0x11, 0x52, 0x61,
0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x0a, 0x0a, 0x06, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4d,
0x49, 0x4e, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x55, 0x52, 0x10,
0x02, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x45,
0x45, 0x4b, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x05, 0x12,
0x08, 0x0a, 0x04, 0x59, 0x45, 0x41, 0x52, 0x10, 0x06, 0x32, 0xdc, 0x02, 0x0a, 0x0f, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x0a,
0x0b, 0x50, 0x75, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x13, 0x2e, 0x50,
0x75, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x10, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x10, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x57,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75,
0x6c, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x10, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0f, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x17, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x18, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x13, 0x42, 0x75, 0x6c,
0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
0x12, 0x1b, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e,
0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a,
0x13, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x12, 0x61, 0x64,
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69,
0x64, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65,
0x70, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x68, 0x69,
0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63, 0x68, 0x69,
0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x61, 0x64, 0x64, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5e,
0x0a, 0x11, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5f, 0x61,
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x74, 0x22, 0xad,
0x02, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a,
0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28,
0x03, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77,
0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x13, 0x73, 0x63, 0x68,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73,
0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x12, 0x73, 0x63, 0x68, 0x65,
0x64, 0x75, 0x6c, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0x53,
0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72,
0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f,
0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74,
0x4b, 0x65, 0x79, 0x22, 0x49, 0x0a, 0x16, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x54,
0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x43, 0x72, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a,
0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x72,
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x22, 0x53,
0x0a, 0x1a, 0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x09,
0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x17, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x73, 0x22, 0x47, 0x0a, 0x1b, 0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67,
0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72,
0x75, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x73, 0x22, 0xe4, 0x03, 0x0a,
0x16, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69,
0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64,
0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x12, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74,
0x65, 0x70, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48,
0x01, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x75, 0x6e,
0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x0b, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x68,
0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x63,
0x68, 0x69, 0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03,
0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a,
0x13, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x12, 0x61, 0x64,
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x77,
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x05,
0x52, 0x0f, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49,
0x64, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x48, 0x06, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69,
0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x64, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73,
0x74, 0x65, 0x70, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63,
0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x63,
0x68, 0x69, 0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x61, 0x64, 0x64,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0x42, 0x14, 0x0a, 0x12, 0x5f, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x77, 0x6f, 0x72,
0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72,
0x69, 0x74, 0x79, 0x22, 0x41, 0x0a, 0x17, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26,
0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x22, 0x6d, 0x0a, 0x13, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74,
0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2e, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x75, 0x72,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65,
0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x24, 0x0a,
0x0e, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12,
0x08, 0x0a, 0x04, 0x53, 0x4f, 0x46, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x41, 0x52,
0x44, 0x10, 0x01, 0x2a, 0x32, 0x0a, 0x0c, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4b,
0x69, 0x6e, 0x64, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x55, 0x4e, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10,
0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x55, 0x52, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x07,
0x0a, 0x03, 0x44, 0x41, 0x47, 0x10, 0x02, 0x2a, 0x6c, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74,
0x65, 0x67, 0x79, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x49, 0x4e,
0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44,
0x52, 0x4f, 0x50, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c,
0x51, 0x55, 0x45, 0x55, 0x45, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x15,
0x0a, 0x11, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x4f,
0x42, 0x49, 0x4e, 0x10, 0x03, 0x2a, 0x85, 0x01, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x4c, 0x61, 0x62, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12,
0x09, 0x0a, 0x05, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f,
0x54, 0x5f, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x52, 0x45,
0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x47,
0x52, 0x45, 0x41, 0x54, 0x45, 0x52, 0x5f, 0x54, 0x48, 0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f, 0x45,
0x51, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54,
0x48, 0x41, 0x4e, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x48,
0x41, 0x4e, 0x5f, 0x4f, 0x52, 0x5f, 0x45, 0x51, 0x55, 0x41, 0x4c, 0x10, 0x05, 0x2a, 0x5d, 0x0a,
0x11, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x10, 0x00, 0x12, 0x0a,
0x0a, 0x06, 0x4d, 0x49, 0x4e, 0x55, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f,
0x55, 0x52, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x41, 0x59, 0x10, 0x03, 0x12, 0x08, 0x0a,
0x04, 0x57, 0x45, 0x45, 0x4b, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48,
0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x59, 0x45, 0x41, 0x52, 0x10, 0x06, 0x32, 0xdc, 0x02, 0x0a,
0x0f, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x34, 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12,
0x13, 0x2e, 0x50, 0x75, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x10, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75,
0x6c, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x2e, 0x53, 0x63, 0x68,
0x65, 0x64, 0x75, 0x6c, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0f, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x17, 0x2e, 0x54, 0x72, 0x69, 0x67,
0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x18, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x13,
0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0c, 0x50,
0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x2e, 0x50, 0x75,
0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x15, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x2d, 0x64,
0x65, 0x76, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x61, 0x64, 0x6d,
0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x6c, 0x6f, 0x77, 0x12, 0x1b, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65,
0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1c, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b,
0x0a, 0x0c, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14,
0x2e, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, 0x40, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65,
0x74, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x2f, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1937,7 +2025,7 @@ func file_workflows_proto_rawDescGZIP() []byte {
}
var file_workflows_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
var file_workflows_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
var file_workflows_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_workflows_proto_goTypes = []interface{}{
(StickyStrategy)(0), // 0: StickyStrategy
(WorkflowKind)(0), // 1: WorkflowKind
@@ -1953,21 +2041,22 @@ var file_workflows_proto_goTypes = []interface{}{
(*CreateStepRateLimit)(nil), // 11: CreateStepRateLimit
(*ListWorkflowsRequest)(nil), // 12: ListWorkflowsRequest
(*ScheduleWorkflowRequest)(nil), // 13: ScheduleWorkflowRequest
(*WorkflowVersion)(nil), // 14: WorkflowVersion
(*WorkflowTriggerEventRef)(nil), // 15: WorkflowTriggerEventRef
(*WorkflowTriggerCronRef)(nil), // 16: WorkflowTriggerCronRef
(*BulkTriggerWorkflowRequest)(nil), // 17: BulkTriggerWorkflowRequest
(*BulkTriggerWorkflowResponse)(nil), // 18: BulkTriggerWorkflowResponse
(*TriggerWorkflowRequest)(nil), // 19: TriggerWorkflowRequest
(*TriggerWorkflowResponse)(nil), // 20: TriggerWorkflowResponse
(*PutRateLimitRequest)(nil), // 21: PutRateLimitRequest
(*PutRateLimitResponse)(nil), // 22: PutRateLimitResponse
nil, // 23: CreateWorkflowStepOpts.WorkerLabelsEntry
(*timestamppb.Timestamp)(nil), // 24: google.protobuf.Timestamp
(*ScheduledWorkflow)(nil), // 14: ScheduledWorkflow
(*WorkflowVersion)(nil), // 15: WorkflowVersion
(*WorkflowTriggerEventRef)(nil), // 16: WorkflowTriggerEventRef
(*WorkflowTriggerCronRef)(nil), // 17: WorkflowTriggerCronRef
(*BulkTriggerWorkflowRequest)(nil), // 18: BulkTriggerWorkflowRequest
(*BulkTriggerWorkflowResponse)(nil), // 19: BulkTriggerWorkflowResponse
(*TriggerWorkflowRequest)(nil), // 20: TriggerWorkflowRequest
(*TriggerWorkflowResponse)(nil), // 21: TriggerWorkflowResponse
(*PutRateLimitRequest)(nil), // 22: PutRateLimitRequest
(*PutRateLimitResponse)(nil), // 23: PutRateLimitResponse
nil, // 24: CreateWorkflowStepOpts.WorkerLabelsEntry
(*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp
}
var file_workflows_proto_depIdxs = []int32{
6, // 0: PutWorkflowRequest.opts:type_name -> CreateWorkflowVersionOpts
24, // 1: CreateWorkflowVersionOpts.scheduled_triggers:type_name -> google.protobuf.Timestamp
25, // 1: CreateWorkflowVersionOpts.scheduled_triggers:type_name -> google.protobuf.Timestamp
8, // 2: CreateWorkflowVersionOpts.jobs:type_name -> CreateWorkflowJobOpts
7, // 3: CreateWorkflowVersionOpts.concurrency:type_name -> WorkflowConcurrencyOpts
8, // 4: CreateWorkflowVersionOpts.on_failure_job:type_name -> CreateWorkflowJobOpts
@@ -1977,29 +2066,31 @@ var file_workflows_proto_depIdxs = []int32{
10, // 8: CreateWorkflowJobOpts.steps:type_name -> CreateWorkflowStepOpts
3, // 9: DesiredWorkerLabels.comparator:type_name -> WorkerLabelComparator
11, // 10: CreateWorkflowStepOpts.rate_limits:type_name -> CreateStepRateLimit
23, // 11: CreateWorkflowStepOpts.worker_labels:type_name -> CreateWorkflowStepOpts.WorkerLabelsEntry
24, // 11: CreateWorkflowStepOpts.worker_labels:type_name -> CreateWorkflowStepOpts.WorkerLabelsEntry
4, // 12: CreateStepRateLimit.duration:type_name -> RateLimitDuration
24, // 13: ScheduleWorkflowRequest.schedules:type_name -> google.protobuf.Timestamp
24, // 14: WorkflowVersion.created_at:type_name -> google.protobuf.Timestamp
24, // 15: WorkflowVersion.updated_at:type_name -> google.protobuf.Timestamp
19, // 16: BulkTriggerWorkflowRequest.workflows:type_name -> TriggerWorkflowRequest
4, // 17: PutRateLimitRequest.duration:type_name -> RateLimitDuration
9, // 18: CreateWorkflowStepOpts.WorkerLabelsEntry.value:type_name -> DesiredWorkerLabels
5, // 19: WorkflowService.PutWorkflow:input_type -> PutWorkflowRequest
13, // 20: WorkflowService.ScheduleWorkflow:input_type -> ScheduleWorkflowRequest
19, // 21: WorkflowService.TriggerWorkflow:input_type -> TriggerWorkflowRequest
17, // 22: WorkflowService.BulkTriggerWorkflow:input_type -> BulkTriggerWorkflowRequest
21, // 23: WorkflowService.PutRateLimit:input_type -> PutRateLimitRequest
14, // 24: WorkflowService.PutWorkflow:output_type -> WorkflowVersion
14, // 25: WorkflowService.ScheduleWorkflow:output_type -> WorkflowVersion
20, // 26: WorkflowService.TriggerWorkflow:output_type -> TriggerWorkflowResponse
18, // 27: WorkflowService.BulkTriggerWorkflow:output_type -> BulkTriggerWorkflowResponse
22, // 28: WorkflowService.PutRateLimit:output_type -> PutRateLimitResponse
24, // [24:29] is the sub-list for method output_type
19, // [19:24] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
25, // 13: ScheduleWorkflowRequest.schedules:type_name -> google.protobuf.Timestamp
25, // 14: ScheduledWorkflow.trigger_at:type_name -> google.protobuf.Timestamp
25, // 15: WorkflowVersion.created_at:type_name -> google.protobuf.Timestamp
25, // 16: WorkflowVersion.updated_at:type_name -> google.protobuf.Timestamp
14, // 17: WorkflowVersion.scheduled_workflows:type_name -> ScheduledWorkflow
20, // 18: BulkTriggerWorkflowRequest.workflows:type_name -> TriggerWorkflowRequest
4, // 19: PutRateLimitRequest.duration:type_name -> RateLimitDuration
9, // 20: CreateWorkflowStepOpts.WorkerLabelsEntry.value:type_name -> DesiredWorkerLabels
5, // 21: WorkflowService.PutWorkflow:input_type -> PutWorkflowRequest
13, // 22: WorkflowService.ScheduleWorkflow:input_type -> ScheduleWorkflowRequest
20, // 23: WorkflowService.TriggerWorkflow:input_type -> TriggerWorkflowRequest
18, // 24: WorkflowService.BulkTriggerWorkflow:input_type -> BulkTriggerWorkflowRequest
22, // 25: WorkflowService.PutRateLimit:input_type -> PutRateLimitRequest
15, // 26: WorkflowService.PutWorkflow:output_type -> WorkflowVersion
15, // 27: WorkflowService.ScheduleWorkflow:output_type -> WorkflowVersion
21, // 28: WorkflowService.TriggerWorkflow:output_type -> TriggerWorkflowResponse
19, // 29: WorkflowService.BulkTriggerWorkflow:output_type -> BulkTriggerWorkflowResponse
23, // 30: WorkflowService.PutRateLimit:output_type -> PutRateLimitResponse
26, // [26:31] is the sub-list for method output_type
21, // [21:26] is the sub-list for method input_type
21, // [21:21] is the sub-list for extension type_name
21, // [21:21] is the sub-list for extension extendee
0, // [0:21] is the sub-list for field type_name
}
func init() { file_workflows_proto_init() }
@@ -2117,7 +2208,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WorkflowVersion); i {
switch v := v.(*ScheduledWorkflow); i {
case 0:
return &v.state
case 1:
@@ -2129,7 +2220,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WorkflowTriggerEventRef); i {
switch v := v.(*WorkflowVersion); i {
case 0:
return &v.state
case 1:
@@ -2141,7 +2232,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WorkflowTriggerCronRef); i {
switch v := v.(*WorkflowTriggerEventRef); i {
case 0:
return &v.state
case 1:
@@ -2153,7 +2244,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BulkTriggerWorkflowRequest); i {
switch v := v.(*WorkflowTriggerCronRef); i {
case 0:
return &v.state
case 1:
@@ -2165,7 +2256,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BulkTriggerWorkflowResponse); i {
switch v := v.(*BulkTriggerWorkflowRequest); i {
case 0:
return &v.state
case 1:
@@ -2177,7 +2268,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TriggerWorkflowRequest); i {
switch v := v.(*BulkTriggerWorkflowResponse); i {
case 0:
return &v.state
case 1:
@@ -2189,7 +2280,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TriggerWorkflowResponse); i {
switch v := v.(*TriggerWorkflowRequest); i {
case 0:
return &v.state
case 1:
@@ -2201,7 +2292,7 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PutRateLimitRequest); i {
switch v := v.(*TriggerWorkflowResponse); i {
case 0:
return &v.state
case 1:
@@ -2213,6 +2304,18 @@ func file_workflows_proto_init() {
}
}
file_workflows_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PutRateLimitRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_workflows_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PutRateLimitResponse); i {
case 0:
return &v.state
@@ -2230,14 +2333,14 @@ func file_workflows_proto_init() {
file_workflows_proto_msgTypes[4].OneofWrappers = []interface{}{}
file_workflows_proto_msgTypes[6].OneofWrappers = []interface{}{}
file_workflows_proto_msgTypes[8].OneofWrappers = []interface{}{}
file_workflows_proto_msgTypes[14].OneofWrappers = []interface{}{}
file_workflows_proto_msgTypes[15].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_workflows_proto_rawDesc,
NumEnums: 5,
NumMessages: 19,
NumMessages: 20,
NumExtensions: 0,
NumServices: 1,
},
+28 -13
View File
@@ -248,7 +248,7 @@ func (a *AdminServiceImpl) PutWorkflow(ctx context.Context, req *contracts.PutWo
}
}
resp := toWorkflowVersion(workflowVersion)
resp := toWorkflowVersion(workflowVersion, nil)
return resp, nil
}
@@ -322,7 +322,7 @@ func (a *AdminServiceImpl) ScheduleWorkflow(ctx context.Context, req *contracts.
}
if err == nil && existing != nil {
return toWorkflowVersion(currWorkflow), nil
return toWorkflowVersion(currWorkflow, nil), nil
}
}
@@ -334,15 +334,20 @@ func (a *AdminServiceImpl) ScheduleWorkflow(ctx context.Context, req *contracts.
workflowVersionId := sqlchelpers.UUIDToStr(currWorkflow.WorkflowVersion.ID)
// FIXME add additional metadata?
var additionalMetadata []byte
_, err = a.repo.Workflow().CreateSchedules(
if req.AdditionalMetadata != nil {
additionalMetadata = []byte(*req.AdditionalMetadata)
}
scheduledRef, err := a.repo.Workflow().CreateSchedules(
ctx,
tenantId,
workflowVersionId,
&repository.CreateWorkflowSchedulesOpts{
ScheduledTriggers: dbSchedules,
Input: []byte(req.Input),
ScheduledTriggers: dbSchedules,
Input: []byte(req.Input),
AdditionalMetadata: additionalMetadata,
},
)
@@ -350,7 +355,7 @@ func (a *AdminServiceImpl) ScheduleWorkflow(ctx context.Context, req *contracts.
return nil, err
}
resp := toWorkflowVersion(currWorkflow)
resp := toWorkflowVersion(currWorkflow, scheduledRef)
return resp, nil
}
@@ -581,13 +586,23 @@ func getCreateJobOpts(req *contracts.CreateWorkflowJobOpts, kind string) (*repos
}, nil
}
func toWorkflowVersion(workflowVersion *dbsqlc.GetWorkflowVersionForEngineRow) *contracts.WorkflowVersion {
func toWorkflowVersion(workflowVersion *dbsqlc.GetWorkflowVersionForEngineRow, scheduledRefs []*dbsqlc.WorkflowTriggerScheduledRef) *contracts.WorkflowVersion {
scheduledWorkflows := make([]*contracts.ScheduledWorkflow, len(scheduledRefs))
for i, ref := range scheduledRefs {
scheduledWorkflows[i] = &contracts.ScheduledWorkflow{
Id: sqlchelpers.UUIDToStr(ref.ID),
TriggerAt: timestamppb.New(ref.TriggerAt.Time),
}
}
version := &contracts.WorkflowVersion{
Id: sqlchelpers.UUIDToStr(workflowVersion.WorkflowVersion.ID),
CreatedAt: timestamppb.New(workflowVersion.WorkflowVersion.CreatedAt.Time),
UpdatedAt: timestamppb.New(workflowVersion.WorkflowVersion.UpdatedAt.Time),
Order: int32(workflowVersion.WorkflowVersion.Order),
WorkflowId: sqlchelpers.UUIDToStr(workflowVersion.WorkflowVersion.WorkflowId),
Id: sqlchelpers.UUIDToStr(workflowVersion.WorkflowVersion.ID),
CreatedAt: timestamppb.New(workflowVersion.WorkflowVersion.CreatedAt.Time),
UpdatedAt: timestamppb.New(workflowVersion.WorkflowVersion.UpdatedAt.Time),
Order: workflowVersion.WorkflowVersion.Order,
WorkflowId: sqlchelpers.UUIDToStr(workflowVersion.WorkflowVersion.WorkflowId),
ScheduledWorkflows: scheduledWorkflows,
}
if workflowVersion.WorkflowVersion.Version.String != "" {
+12 -3
View File
@@ -129,6 +129,16 @@ func (t *TickerImpl) runScheduledWorkflow(tenantId, workflowVersionId, scheduled
fs := make([]repository.CreateWorkflowRunOpt, 0)
var additionalMetadata map[string]interface{}
if scheduled.AdditionalMetadata != nil {
err := json.Unmarshal(scheduled.AdditionalMetadata, &additionalMetadata)
if err != nil {
t.l.Err(err).Msg("could not unmarshal additional metadata")
return
}
}
if scheduled.ParentWorkflowRunId.Valid {
var childKey *string
@@ -158,18 +168,17 @@ func (t *TickerImpl) runScheduledWorkflow(tenantId, workflowVersionId, scheduled
sqlchelpers.UUIDToStr(scheduled.ParentStepRunId),
int(scheduled.ChildIndex.Int32),
childKey,
nil,
additionalMetadata,
parentAdditionalMeta,
))
}
// create a new workflow run in the database
// FIXME additionalMetadata is not used for scheduled runs
createOpts, err := repository.GetCreateWorkflowRunOptsFromSchedule(
scheduledWorkflowId,
workflowVersion,
scheduled.Input,
nil,
additionalMetadata,
fs...,
)
+894 -6
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+13 -5
View File
@@ -1716,11 +1716,15 @@ type WorkflowToWorkflowTag struct {
}
type WorkflowTriggerCronRef struct {
ParentId pgtype.UUID `json:"parentId"`
Cron string `json:"cron"`
TickerId pgtype.UUID `json:"tickerId"`
Input []byte `json:"input"`
Enabled bool `json:"enabled"`
ParentId pgtype.UUID `json:"parentId"`
Cron string `json:"cron"`
TickerId pgtype.UUID `json:"tickerId"`
Input []byte `json:"input"`
Enabled bool `json:"enabled"`
AdditionalMetadata []byte `json:"additionalMetadata"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
DeletedAt pgtype.Timestamp `json:"deletedAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
}
type WorkflowTriggerEventRef struct {
@@ -1738,6 +1742,10 @@ type WorkflowTriggerScheduledRef struct {
ChildKey pgtype.Text `json:"childKey"`
ParentStepRunId pgtype.UUID `json:"parentStepRunId"`
ParentWorkflowRunId pgtype.UUID `json:"parentWorkflowRunId"`
AdditionalMetadata []byte `json:"additionalMetadata"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
DeletedAt pgtype.Timestamp `json:"deletedAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
}
type WorkflowTriggers struct {
+9 -1
View File
@@ -901,7 +901,11 @@ CREATE TABLE "WorkflowTriggerCronRef" (
"cron" TEXT NOT NULL,
"tickerId" UUID,
"input" JSONB,
"enabled" BOOLEAN NOT NULL DEFAULT true
"enabled" BOOLEAN NOT NULL DEFAULT true,
"additionalMetadata" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deletedAt" TIMESTAMP(3),
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateTable
@@ -921,6 +925,10 @@ CREATE TABLE "WorkflowTriggerScheduledRef" (
"childKey" TEXT,
"parentStepRunId" UUID,
"parentWorkflowRunId" UUID,
"additionalMetadata" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deletedAt" TIMESTAMP(3),
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "WorkflowTriggerScheduledRef_pkey" PRIMARY KEY ("id")
);
+2 -1
View File
@@ -156,7 +156,8 @@ not_run_scheduled_workflows AS (
SELECT
scheduledWorkflow."id",
versions."id" AS "workflowVersionId",
workflow."tenantId" AS "tenantId"
workflow."tenantId" AS "tenantId",
scheduledWorkflow."additionalMetadata" AS "additionalMetadata"
FROM
"WorkflowTriggerScheduledRef" as scheduledWorkflow
JOIN
+28 -11
View File
@@ -227,17 +227,21 @@ FROM
active_cron_schedules
WHERE
cronSchedules."parentId" = active_cron_schedules."parentId"
RETURNING cronschedules."parentId", cronschedules.cron, cronschedules."tickerId", cronschedules.input, cronschedules.enabled, active_cron_schedules."workflowVersionId", active_cron_schedules."tenantId"
RETURNING cronschedules."parentId", cronschedules.cron, cronschedules."tickerId", cronschedules.input, cronschedules.enabled, cronschedules."additionalMetadata", cronschedules."createdAt", cronschedules."deletedAt", cronschedules."updatedAt", active_cron_schedules."workflowVersionId", active_cron_schedules."tenantId"
`
type PollCronSchedulesRow struct {
ParentId pgtype.UUID `json:"parentId"`
Cron string `json:"cron"`
TickerId pgtype.UUID `json:"tickerId"`
Input []byte `json:"input"`
Enabled bool `json:"enabled"`
WorkflowVersionId pgtype.UUID `json:"workflowVersionId"`
TenantId pgtype.UUID `json:"tenantId"`
ParentId pgtype.UUID `json:"parentId"`
Cron string `json:"cron"`
TickerId pgtype.UUID `json:"tickerId"`
Input []byte `json:"input"`
Enabled bool `json:"enabled"`
AdditionalMetadata []byte `json:"additionalMetadata"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
DeletedAt pgtype.Timestamp `json:"deletedAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
WorkflowVersionId pgtype.UUID `json:"workflowVersionId"`
TenantId pgtype.UUID `json:"tenantId"`
}
func (q *Queries) PollCronSchedules(ctx context.Context, db DBTX, tickerid pgtype.UUID) ([]*PollCronSchedulesRow, error) {
@@ -255,6 +259,10 @@ func (q *Queries) PollCronSchedules(ctx context.Context, db DBTX, tickerid pgtyp
&i.TickerId,
&i.Input,
&i.Enabled,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
&i.WorkflowVersionId,
&i.TenantId,
); err != nil {
@@ -415,7 +423,8 @@ not_run_scheduled_workflows AS (
SELECT
scheduledWorkflow."id",
versions."id" AS "workflowVersionId",
workflow."tenantId" AS "tenantId"
workflow."tenantId" AS "tenantId",
scheduledWorkflow."additionalMetadata" AS "additionalMetadata"
FROM
"WorkflowTriggerScheduledRef" as scheduledWorkflow
JOIN
@@ -441,7 +450,7 @@ not_run_scheduled_workflows AS (
),
active_scheduled_workflows AS (
SELECT
id, "workflowVersionId", "tenantId"
id, "workflowVersionId", "tenantId", "additionalMetadata"
FROM
not_run_scheduled_workflows
FOR UPDATE SKIP LOCKED
@@ -454,7 +463,7 @@ FROM
active_scheduled_workflows
WHERE
scheduledWorkflows."id" = active_scheduled_workflows."id"
RETURNING scheduledworkflows.id, scheduledworkflows."parentId", scheduledworkflows."triggerAt", scheduledworkflows."tickerId", scheduledworkflows.input, scheduledworkflows."childIndex", scheduledworkflows."childKey", scheduledworkflows."parentStepRunId", scheduledworkflows."parentWorkflowRunId", active_scheduled_workflows."workflowVersionId", active_scheduled_workflows."tenantId"
RETURNING scheduledworkflows.id, scheduledworkflows."parentId", scheduledworkflows."triggerAt", scheduledworkflows."tickerId", scheduledworkflows.input, scheduledworkflows."childIndex", scheduledworkflows."childKey", scheduledworkflows."parentStepRunId", scheduledworkflows."parentWorkflowRunId", scheduledworkflows."additionalMetadata", scheduledworkflows."createdAt", scheduledworkflows."deletedAt", scheduledworkflows."updatedAt", active_scheduled_workflows."workflowVersionId", active_scheduled_workflows."tenantId"
`
type PollScheduledWorkflowsRow struct {
@@ -467,6 +476,10 @@ type PollScheduledWorkflowsRow struct {
ChildKey pgtype.Text `json:"childKey"`
ParentStepRunId pgtype.UUID `json:"parentStepRunId"`
ParentWorkflowRunId pgtype.UUID `json:"parentWorkflowRunId"`
AdditionalMetadata []byte `json:"additionalMetadata"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
DeletedAt pgtype.Timestamp `json:"deletedAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
WorkflowVersionId pgtype.UUID `json:"workflowVersionId"`
TenantId pgtype.UUID `json:"tenantId"`
}
@@ -492,6 +505,10 @@ func (q *Queries) PollScheduledWorkflows(ctx context.Context, db DBTX, tickerid
&i.ChildKey,
&i.ParentStepRunId,
&i.ParentWorkflowRunId,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
&i.WorkflowVersionId,
&i.TenantId,
); err != nil {
@@ -1415,3 +1415,113 @@ WHERE
sre."workflowRunId" = @workflowRunId::uuid
ORDER BY
sre."id" DESC;
-- name: ListScheduledWorkflows :many
SELECT
w."name",
w."id" as "workflowId",
v."id" as "workflowVersionId",
w."tenantId",
t.*,
wr."createdAt" as "workflowRunCreatedAt",
wr."status" as "workflowRunStatus",
wr."id" as "workflowRunId",
wr."displayName" as "workflowRunName"
FROM "WorkflowTriggerScheduledRef" t
JOIN "WorkflowVersion" v ON t."parentId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
LEFT JOIN "WorkflowRunTriggeredBy" tb ON t."id" = tb."scheduledId"
LEFT JOIN "WorkflowRun" wr ON tb."parentId" = wr."id"
WHERE v."deletedAt" IS NULL
AND w."tenantId" = @tenantId::uuid
AND (@scheduleId::uuid IS NULL OR t."id" = @scheduleId::uuid)
AND (@workflowId::uuid IS NULL OR w."id" = @workflowId::uuid)
AND (@parentWorkflowRunId::uuid IS NULL OR t."id" = @parentWorkflowRunId::uuid)
AND (@parentStepRunId::uuid IS NULL OR t."parentStepRunId" = @parentStepRunId::uuid)
AND (sqlc.narg('additionalMetadata')::jsonb IS NULL OR
t."additionalMetadata" @> sqlc.narg('additionalMetadata')::jsonb)
AND (
sqlc.narg('statuses')::text[] IS NULL OR
wr."status" = ANY(cast(sqlc.narg('statuses')::text[] as "WorkflowRunStatus"[]))
or (
@includeScheduled::boolean IS TRUE AND
wr."status" IS NULL
)
)
ORDER BY
case when @orderBy = 'triggerAt ASC' THEN t."triggerAt" END ASC ,
case when @orderBy = 'triggerAt DESC' THEN t."triggerAt" END DESC,
case when @orderBy = 'createdAt ASC' THEN t."createdAt" END ASC ,
case when @orderBy = 'createdAt DESC' THEN t."createdAt" END DESC,
t."id" ASC
OFFSET
COALESCE(sqlc.narg('offset'), 0)
LIMIT
COALESCE(sqlc.narg('limit'), 50);
-- name: CountScheduledWorkflows :one
SELECT count(*)
FROM "WorkflowTriggerScheduledRef" t
JOIN "WorkflowVersion" v ON t."parentId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
LEFT JOIN "WorkflowRunTriggeredBy" tb ON t."id" = tb."scheduledId"
LEFT JOIN "WorkflowRun" wr ON tb."parentId" = wr."id"
WHERE v."deletedAt" IS NULL
AND w."tenantId" = @tenantId::uuid
AND (@scheduleId::uuid IS NULL OR t."id" = @scheduleId::uuid)
AND (@workflowId::uuid IS NULL OR w."id" = @workflowId::uuid)
AND (@parentWorkflowRunId::uuid IS NULL OR t."id" = @parentWorkflowRunId::uuid)
AND (@parentStepRunId::uuid IS NULL OR t."parentStepRunId" = @parentStepRunId::uuid)
AND (sqlc.narg('additionalMetadata')::jsonb IS NULL OR
t."additionalMetadata" @> sqlc.narg('additionalMetadata')::jsonb)
AND (
sqlc.narg('statuses')::text[] IS NULL OR
wr."status" = ANY(cast(sqlc.narg('statuses')::text[] as "WorkflowRunStatus"[]))
or (
@includeScheduled::boolean IS TRUE AND
wr."status" IS NULL
)
);
-- name: UpdateScheduledWorkflow :exec
UPDATE "WorkflowTriggerScheduledRef"
SET "triggerAt" = @triggerAt::timestamp
WHERE
"id" = @scheduleId::uuid;
-- name: DeleteScheduledWorkflow :exec
DELETE FROM "WorkflowTriggerScheduledRef"
WHERE
"id" = @scheduleId::uuid;
-- name: ListCronWorkflows :many
SELECT
w."name",
w."id" as "workflowId",
v."id" as "workflowVersionId",
w."tenantId",
t.*,
c.*
FROM "WorkflowTriggerCronRef" c
JOIN "WorkflowTriggers" t ON c."parentId" = t."id"
JOIN "WorkflowVersion" v ON t."workflowVersionId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
WHERE v."deletedAt" IS NULL
AND w."tenantId" = @tenantId::uuid
ORDER BY
case when @orderBy = 'createdAt ASC' THEN t."createdAt" END ASC ,
case when @orderBy = 'createdAt DESC' THEN t."createdAt" END DESC,
t."id" ASC
OFFSET
COALESCE(sqlc.narg('offset'), 0)
LIMIT
COALESCE(sqlc.narg('limit'), 50);
-- name: CountCronWorkflows :one
SELECT count(*)
FROM "WorkflowTriggerCronRef" c
JOIN "WorkflowTriggers" t ON c."parentId" = t."id"
JOIN "WorkflowVersion" v ON t."workflowVersionId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
WHERE v."deletedAt" IS NULL AND w."tenantId" = @tenantId::uuid;
@@ -90,6 +90,74 @@ func (q *Queries) BulkCreateWorkflowRunEvent(ctx context.Context, db DBTX, arg B
return err
}
const countCronWorkflows = `-- name: CountCronWorkflows :one
SELECT count(*)
FROM "WorkflowTriggerCronRef" c
JOIN "WorkflowTriggers" t ON c."parentId" = t."id"
JOIN "WorkflowVersion" v ON t."workflowVersionId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
WHERE v."deletedAt" IS NULL AND w."tenantId" = $1::uuid
`
func (q *Queries) CountCronWorkflows(ctx context.Context, db DBTX, tenantid pgtype.UUID) (int64, error) {
row := db.QueryRow(ctx, countCronWorkflows, tenantid)
var count int64
err := row.Scan(&count)
return count, err
}
const countScheduledWorkflows = `-- name: CountScheduledWorkflows :one
SELECT count(*)
FROM "WorkflowTriggerScheduledRef" t
JOIN "WorkflowVersion" v ON t."parentId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
LEFT JOIN "WorkflowRunTriggeredBy" tb ON t."id" = tb."scheduledId"
LEFT JOIN "WorkflowRun" wr ON tb."parentId" = wr."id"
WHERE v."deletedAt" IS NULL
AND w."tenantId" = $1::uuid
AND ($2::uuid IS NULL OR t."id" = $2::uuid)
AND ($3::uuid IS NULL OR w."id" = $3::uuid)
AND ($4::uuid IS NULL OR t."id" = $4::uuid)
AND ($5::uuid IS NULL OR t."parentStepRunId" = $5::uuid)
AND ($6::jsonb IS NULL OR
t."additionalMetadata" @> $6::jsonb)
AND (
$7::text[] IS NULL OR
wr."status" = ANY(cast($7::text[] as "WorkflowRunStatus"[]))
or (
$8::boolean IS TRUE AND
wr."status" IS NULL
)
)
`
type CountScheduledWorkflowsParams struct {
Tenantid pgtype.UUID `json:"tenantid"`
Scheduleid pgtype.UUID `json:"scheduleid"`
Workflowid pgtype.UUID `json:"workflowid"`
Parentworkflowrunid pgtype.UUID `json:"parentworkflowrunid"`
Parentsteprunid pgtype.UUID `json:"parentsteprunid"`
AdditionalMetadata []byte `json:"additionalMetadata"`
Statuses []string `json:"statuses"`
Includescheduled bool `json:"includescheduled"`
}
func (q *Queries) CountScheduledWorkflows(ctx context.Context, db DBTX, arg CountScheduledWorkflowsParams) (int64, error) {
row := db.QueryRow(ctx, countScheduledWorkflows,
arg.Tenantid,
arg.Scheduleid,
arg.Workflowid,
arg.Parentworkflowrunid,
arg.Parentsteprunid,
arg.AdditionalMetadata,
arg.Statuses,
arg.Includescheduled,
)
var count int64
err := row.Scan(&count)
return count, err
}
const countWorkflowRuns = `-- name: CountWorkflowRuns :one
WITH runs AS (
SELECT runs."id", runs."createdAt", runs."finishedAt", runs."startedAt", runs."duration"
@@ -1035,6 +1103,17 @@ type CreateWorkflowRunsParams struct {
InsertOrder pgtype.Int4 `json:"insertOrder"`
}
const deleteScheduledWorkflow = `-- name: DeleteScheduledWorkflow :exec
DELETE FROM "WorkflowTriggerScheduledRef"
WHERE
"id" = $1::uuid
`
func (q *Queries) DeleteScheduledWorkflow(ctx context.Context, db DBTX, scheduleid pgtype.UUID) error {
_, err := db.Exec(ctx, deleteScheduledWorkflow, scheduleid)
return err
}
const getChildWorkflowRun = `-- name: GetChildWorkflowRun :one
SELECT
"createdAt", "updatedAt", "deletedAt", "tenantId", "workflowVersionId", status, error, "startedAt", "finishedAt", "concurrencyGroupId", "displayName", id, "childIndex", "childKey", "parentId", "parentStepRunId", "additionalMetadata", duration, priority, "insertOrder"
@@ -1217,7 +1296,7 @@ func (q *Queries) GetChildWorkflowRunsByKey(ctx context.Context, db DBTX, arg Ge
const getScheduledChildWorkflowRun = `-- name: GetScheduledChildWorkflowRun :one
SELECT
id, "parentId", "triggerAt", "tickerId", input, "childIndex", "childKey", "parentStepRunId", "parentWorkflowRunId"
id, "parentId", "triggerAt", "tickerId", input, "childIndex", "childKey", "parentStepRunId", "parentWorkflowRunId", "additionalMetadata", "createdAt", "deletedAt", "updatedAt"
FROM
"WorkflowTriggerScheduledRef"
WHERE
@@ -1255,6 +1334,10 @@ func (q *Queries) GetScheduledChildWorkflowRun(ctx context.Context, db DBTX, arg
&i.ChildKey,
&i.ParentStepRunId,
&i.ParentWorkflowRunId,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
)
return &i, err
}
@@ -2090,6 +2173,240 @@ func (q *Queries) ListChildWorkflowRunCounts(ctx context.Context, db DBTX, stepr
return items, nil
}
const listCronWorkflows = `-- name: ListCronWorkflows :many
SELECT
w."name",
w."id" as "workflowId",
v."id" as "workflowVersionId",
w."tenantId",
t.id, t."createdAt", t."updatedAt", t."deletedAt", t."workflowVersionId", t."tenantId",
c."parentId", c.cron, c."tickerId", c.input, c.enabled, c."additionalMetadata", c."createdAt", c."deletedAt", c."updatedAt"
FROM "WorkflowTriggerCronRef" c
JOIN "WorkflowTriggers" t ON c."parentId" = t."id"
JOIN "WorkflowVersion" v ON t."workflowVersionId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
WHERE v."deletedAt" IS NULL
AND w."tenantId" = $1::uuid
ORDER BY
case when $2 = 'createdAt ASC' THEN t."createdAt" END ASC ,
case when $2 = 'createdAt DESC' THEN t."createdAt" END DESC,
t."id" ASC
OFFSET
COALESCE($3, 0)
LIMIT
COALESCE($4, 50)
`
type ListCronWorkflowsParams struct {
Tenantid pgtype.UUID `json:"tenantid"`
Orderby interface{} `json:"orderby"`
Offset interface{} `json:"offset"`
Limit interface{} `json:"limit"`
}
type ListCronWorkflowsRow struct {
Name string `json:"name"`
WorkflowId pgtype.UUID `json:"workflowId"`
WorkflowVersionId pgtype.UUID `json:"workflowVersionId"`
TenantId pgtype.UUID `json:"tenantId"`
ID pgtype.UUID `json:"id"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
DeletedAt pgtype.Timestamp `json:"deletedAt"`
WorkflowVersionId_2 pgtype.UUID `json:"workflowVersionId_2"`
TenantId_2 pgtype.UUID `json:"tenantId_2"`
ParentId pgtype.UUID `json:"parentId"`
Cron string `json:"cron"`
TickerId pgtype.UUID `json:"tickerId"`
Input []byte `json:"input"`
Enabled bool `json:"enabled"`
AdditionalMetadata []byte `json:"additionalMetadata"`
CreatedAt_2 pgtype.Timestamp `json:"createdAt_2"`
DeletedAt_2 pgtype.Timestamp `json:"deletedAt_2"`
UpdatedAt_2 pgtype.Timestamp `json:"updatedAt_2"`
}
func (q *Queries) ListCronWorkflows(ctx context.Context, db DBTX, arg ListCronWorkflowsParams) ([]*ListCronWorkflowsRow, error) {
rows, err := db.Query(ctx, listCronWorkflows,
arg.Tenantid,
arg.Orderby,
arg.Offset,
arg.Limit,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []*ListCronWorkflowsRow
for rows.Next() {
var i ListCronWorkflowsRow
if err := rows.Scan(
&i.Name,
&i.WorkflowId,
&i.WorkflowVersionId,
&i.TenantId,
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.DeletedAt,
&i.WorkflowVersionId_2,
&i.TenantId_2,
&i.ParentId,
&i.Cron,
&i.TickerId,
&i.Input,
&i.Enabled,
&i.AdditionalMetadata,
&i.CreatedAt_2,
&i.DeletedAt_2,
&i.UpdatedAt_2,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listScheduledWorkflows = `-- name: ListScheduledWorkflows :many
SELECT
w."name",
w."id" as "workflowId",
v."id" as "workflowVersionId",
w."tenantId",
t.id, t."parentId", t."triggerAt", t."tickerId", t.input, t."childIndex", t."childKey", t."parentStepRunId", t."parentWorkflowRunId", t."additionalMetadata", t."createdAt", t."deletedAt", t."updatedAt",
wr."createdAt" as "workflowRunCreatedAt",
wr."status" as "workflowRunStatus",
wr."id" as "workflowRunId",
wr."displayName" as "workflowRunName"
FROM "WorkflowTriggerScheduledRef" t
JOIN "WorkflowVersion" v ON t."parentId" = v."id"
JOIN "Workflow" w on v."workflowId" = w."id"
LEFT JOIN "WorkflowRunTriggeredBy" tb ON t."id" = tb."scheduledId"
LEFT JOIN "WorkflowRun" wr ON tb."parentId" = wr."id"
WHERE v."deletedAt" IS NULL
AND w."tenantId" = $1::uuid
AND ($2::uuid IS NULL OR t."id" = $2::uuid)
AND ($3::uuid IS NULL OR w."id" = $3::uuid)
AND ($4::uuid IS NULL OR t."id" = $4::uuid)
AND ($5::uuid IS NULL OR t."parentStepRunId" = $5::uuid)
AND ($6::jsonb IS NULL OR
t."additionalMetadata" @> $6::jsonb)
AND (
$7::text[] IS NULL OR
wr."status" = ANY(cast($7::text[] as "WorkflowRunStatus"[]))
or (
$8::boolean IS TRUE AND
wr."status" IS NULL
)
)
ORDER BY
case when $9 = 'triggerAt ASC' THEN t."triggerAt" END ASC ,
case when $9 = 'triggerAt DESC' THEN t."triggerAt" END DESC,
case when $9 = 'createdAt ASC' THEN t."createdAt" END ASC ,
case when $9 = 'createdAt DESC' THEN t."createdAt" END DESC,
t."id" ASC
OFFSET
COALESCE($10, 0)
LIMIT
COALESCE($11, 50)
`
type ListScheduledWorkflowsParams struct {
Tenantid pgtype.UUID `json:"tenantid"`
Scheduleid pgtype.UUID `json:"scheduleid"`
Workflowid pgtype.UUID `json:"workflowid"`
Parentworkflowrunid pgtype.UUID `json:"parentworkflowrunid"`
Parentsteprunid pgtype.UUID `json:"parentsteprunid"`
AdditionalMetadata []byte `json:"additionalMetadata"`
Statuses []string `json:"statuses"`
Includescheduled bool `json:"includescheduled"`
Orderby interface{} `json:"orderby"`
Offset interface{} `json:"offset"`
Limit interface{} `json:"limit"`
}
type ListScheduledWorkflowsRow struct {
Name string `json:"name"`
WorkflowId pgtype.UUID `json:"workflowId"`
WorkflowVersionId pgtype.UUID `json:"workflowVersionId"`
TenantId pgtype.UUID `json:"tenantId"`
ID pgtype.UUID `json:"id"`
ParentId pgtype.UUID `json:"parentId"`
TriggerAt pgtype.Timestamp `json:"triggerAt"`
TickerId pgtype.UUID `json:"tickerId"`
Input []byte `json:"input"`
ChildIndex pgtype.Int4 `json:"childIndex"`
ChildKey pgtype.Text `json:"childKey"`
ParentStepRunId pgtype.UUID `json:"parentStepRunId"`
ParentWorkflowRunId pgtype.UUID `json:"parentWorkflowRunId"`
AdditionalMetadata []byte `json:"additionalMetadata"`
CreatedAt pgtype.Timestamp `json:"createdAt"`
DeletedAt pgtype.Timestamp `json:"deletedAt"`
UpdatedAt pgtype.Timestamp `json:"updatedAt"`
WorkflowRunCreatedAt pgtype.Timestamp `json:"workflowRunCreatedAt"`
WorkflowRunStatus NullWorkflowRunStatus `json:"workflowRunStatus"`
WorkflowRunId pgtype.UUID `json:"workflowRunId"`
WorkflowRunName pgtype.Text `json:"workflowRunName"`
}
func (q *Queries) ListScheduledWorkflows(ctx context.Context, db DBTX, arg ListScheduledWorkflowsParams) ([]*ListScheduledWorkflowsRow, error) {
rows, err := db.Query(ctx, listScheduledWorkflows,
arg.Tenantid,
arg.Scheduleid,
arg.Workflowid,
arg.Parentworkflowrunid,
arg.Parentsteprunid,
arg.AdditionalMetadata,
arg.Statuses,
arg.Includescheduled,
arg.Orderby,
arg.Offset,
arg.Limit,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []*ListScheduledWorkflowsRow
for rows.Next() {
var i ListScheduledWorkflowsRow
if err := rows.Scan(
&i.Name,
&i.WorkflowId,
&i.WorkflowVersionId,
&i.TenantId,
&i.ID,
&i.ParentId,
&i.TriggerAt,
&i.TickerId,
&i.Input,
&i.ChildIndex,
&i.ChildKey,
&i.ParentStepRunId,
&i.ParentWorkflowRunId,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
&i.WorkflowRunCreatedAt,
&i.WorkflowRunStatus,
&i.WorkflowRunId,
&i.WorkflowRunName,
); err != nil {
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listStepsForJob = `-- name: ListStepsForJob :many
WITH job_id AS (
SELECT "jobId"
@@ -2823,6 +3140,23 @@ func (q *Queries) UpdateManyWorkflowRun(ctx context.Context, db DBTX, arg Update
return items, nil
}
const updateScheduledWorkflow = `-- name: UpdateScheduledWorkflow :exec
UPDATE "WorkflowTriggerScheduledRef"
SET "triggerAt" = $1::timestamp
WHERE
"id" = $2::uuid
`
type UpdateScheduledWorkflowParams struct {
Triggerat pgtype.Timestamp `json:"triggerat"`
Scheduleid pgtype.UUID `json:"scheduleid"`
}
func (q *Queries) UpdateScheduledWorkflow(ctx context.Context, db DBTX, arg UpdateScheduledWorkflowParams) error {
_, err := db.Exec(ctx, updateScheduledWorkflow, arg.Triggerat, arg.Scheduleid)
return err
}
const updateWorkflowRun = `-- name: UpdateWorkflowRun :one
UPDATE
"WorkflowRun"
+4 -2
View File
@@ -455,12 +455,14 @@ INSERT INTO "WorkflowTriggerScheduledRef" (
"id",
"parentId",
"triggerAt",
"input"
"input",
"additionalMetadata"
) VALUES (
gen_random_uuid(),
@workflowRunId::uuid,
unnest(@triggerTimes::timestamp[]),
@input::jsonb
@input::jsonb,
@additionalMetadata::json
) RETURNING *;
-- name: GetWorkflowLatestVersion :one
+39 -11
View File
@@ -242,23 +242,31 @@ INSERT INTO "WorkflowTriggerScheduledRef" (
"id",
"parentId",
"triggerAt",
"input"
"input",
"additionalMetadata"
) VALUES (
gen_random_uuid(),
$1::uuid,
unnest($2::timestamp[]),
$3::jsonb
) RETURNING id, "parentId", "triggerAt", "tickerId", input, "childIndex", "childKey", "parentStepRunId", "parentWorkflowRunId"
$3::jsonb,
$4::json
) RETURNING id, "parentId", "triggerAt", "tickerId", input, "childIndex", "childKey", "parentStepRunId", "parentWorkflowRunId", "additionalMetadata", "createdAt", "deletedAt", "updatedAt"
`
type CreateSchedulesParams struct {
Workflowrunid pgtype.UUID `json:"workflowrunid"`
Triggertimes []pgtype.Timestamp `json:"triggertimes"`
Input []byte `json:"input"`
Workflowrunid pgtype.UUID `json:"workflowrunid"`
Triggertimes []pgtype.Timestamp `json:"triggertimes"`
Input []byte `json:"input"`
Additionalmetadata []byte `json:"additionalmetadata"`
}
func (q *Queries) CreateSchedules(ctx context.Context, db DBTX, arg CreateSchedulesParams) ([]*WorkflowTriggerScheduledRef, error) {
rows, err := db.Query(ctx, createSchedules, arg.Workflowrunid, arg.Triggertimes, arg.Input)
rows, err := db.Query(ctx, createSchedules,
arg.Workflowrunid,
arg.Triggertimes,
arg.Input,
arg.Additionalmetadata,
)
if err != nil {
return nil, err
}
@@ -276,6 +284,10 @@ func (q *Queries) CreateSchedules(ctx context.Context, db DBTX, arg CreateSchedu
&i.ChildKey,
&i.ParentStepRunId,
&i.ParentWorkflowRunId,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
@@ -560,7 +572,7 @@ INSERT INTO "WorkflowTriggerCronRef" (
$1::uuid,
$2::text,
$3::jsonb
) RETURNING "parentId", cron, "tickerId", input, enabled
) RETURNING "parentId", cron, "tickerId", input, enabled, "additionalMetadata", "createdAt", "deletedAt", "updatedAt"
`
type CreateWorkflowTriggerCronRefParams struct {
@@ -578,6 +590,10 @@ func (q *Queries) CreateWorkflowTriggerCronRef(ctx context.Context, db DBTX, arg
&i.TickerId,
&i.Input,
&i.Enabled,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
)
return &i, err
}
@@ -617,7 +633,7 @@ INSERT INTO "WorkflowTriggerScheduledRef" (
$2::timestamp,
NULL, -- or provide a tickerId if applicable
NULL -- or provide input if applicable
) RETURNING id, "parentId", "triggerAt", "tickerId", input, "childIndex", "childKey", "parentStepRunId", "parentWorkflowRunId"
) RETURNING id, "parentId", "triggerAt", "tickerId", input, "childIndex", "childKey", "parentStepRunId", "parentWorkflowRunId", "additionalMetadata", "createdAt", "deletedAt", "updatedAt"
`
type CreateWorkflowTriggerScheduledRefParams struct {
@@ -638,6 +654,10 @@ func (q *Queries) CreateWorkflowTriggerScheduledRef(ctx context.Context, db DBTX
&i.ChildKey,
&i.ParentStepRunId,
&i.ParentWorkflowRunId,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
)
return &i, err
}
@@ -961,7 +981,7 @@ func (q *Queries) GetWorkflowVersionById(ctx context.Context, db DBTX, id pgtype
const getWorkflowVersionCronTriggerRefs = `-- name: GetWorkflowVersionCronTriggerRefs :many
SELECT
wtc."parentId", wtc.cron, wtc."tickerId", wtc.input, wtc.enabled
wtc."parentId", wtc.cron, wtc."tickerId", wtc.input, wtc.enabled, wtc."additionalMetadata", wtc."createdAt", wtc."deletedAt", wtc."updatedAt"
FROM
"WorkflowTriggerCronRef" as wtc
JOIN "WorkflowTriggers" as wt ON wt."id" = wtc."parentId"
@@ -984,6 +1004,10 @@ func (q *Queries) GetWorkflowVersionCronTriggerRefs(ctx context.Context, db DBTX
&i.TickerId,
&i.Input,
&i.Enabled,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
@@ -1101,7 +1125,7 @@ func (q *Queries) GetWorkflowVersionForEngine(ctx context.Context, db DBTX, arg
const getWorkflowVersionScheduleTriggerRefs = `-- name: GetWorkflowVersionScheduleTriggerRefs :many
SELECT
wtc.id, wtc."parentId", wtc."triggerAt", wtc."tickerId", wtc.input, wtc."childIndex", wtc."childKey", wtc."parentStepRunId", wtc."parentWorkflowRunId"
wtc.id, wtc."parentId", wtc."triggerAt", wtc."tickerId", wtc.input, wtc."childIndex", wtc."childKey", wtc."parentStepRunId", wtc."parentWorkflowRunId", wtc."additionalMetadata", wtc."createdAt", wtc."deletedAt", wtc."updatedAt"
FROM
"WorkflowTriggerScheduledRef" as wtc
JOIN "WorkflowTriggers" as wt ON wt."id" = wtc."parentId"
@@ -1128,6 +1152,10 @@ func (q *Queries) GetWorkflowVersionScheduleTriggerRefs(ctx context.Context, db
&i.ChildKey,
&i.ParentStepRunId,
&i.ParentWorkflowRunId,
&i.AdditionalMetadata,
&i.CreatedAt,
&i.DeletedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
+4 -3
View File
@@ -492,9 +492,10 @@ func (r *workflowEngineRepository) CreateSchedules(
}
createParams := dbsqlc.CreateSchedulesParams{
Workflowrunid: sqlchelpers.UUIDFromStr(workflowVersionId),
Input: opts.Input,
Triggertimes: make([]pgtype.Timestamp, len(opts.ScheduledTriggers)),
Workflowrunid: sqlchelpers.UUIDFromStr(workflowVersionId),
Input: opts.Input,
Triggertimes: make([]pgtype.Timestamp, len(opts.ScheduledTriggers)),
Additionalmetadata: opts.AdditionalMetadata,
}
for i, scheduledTrigger := range opts.ScheduledTriggers {
+191
View File
@@ -116,6 +116,197 @@ func (w *workflowRunAPIRepository) WorkflowRunMetricsCount(ctx context.Context,
return workflowRunMetricsCount(context.Background(), w.pool, w.queries, tenantId, opts)
}
func (w *workflowRunAPIRepository) ListScheduledWorkflows(ctx context.Context, tenantId string, opts *repository.ListScheduledWorkflowsOpts) ([]*dbsqlc.ListScheduledWorkflowsRow, int64, error) {
if err := w.v.Validate(opts); err != nil {
return nil, 0, err
}
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
defer cancel()
listOpts := dbsqlc.ListScheduledWorkflowsParams{
Tenantid: sqlchelpers.UUIDFromStr(tenantId),
}
countParams := dbsqlc.CountScheduledWorkflowsParams{
Tenantid: sqlchelpers.UUIDFromStr(tenantId),
}
if opts.WorkflowId != nil {
pgWorkflowId := sqlchelpers.UUIDFromStr(*opts.WorkflowId)
listOpts.Workflowid = pgWorkflowId
countParams.Workflowid = pgWorkflowId
}
if opts.AdditionalMetadata != nil {
additionalMetadataBytes, err := json.Marshal(opts.AdditionalMetadata)
if err != nil {
return nil, 0, err
}
listOpts.AdditionalMetadata = additionalMetadataBytes
countParams.AdditionalMetadata = additionalMetadataBytes
}
if opts.ParentWorkflowRunId != nil {
pgParentId := sqlchelpers.UUIDFromStr(*opts.ParentWorkflowRunId)
listOpts.Parentworkflowrunid = pgParentId
countParams.Parentworkflowrunid = pgParentId
}
if opts.ParentStepRunId != nil {
pgParentStepRunId := sqlchelpers.UUIDFromStr(*opts.ParentStepRunId)
listOpts.Parentsteprunid = pgParentStepRunId
countParams.Parentsteprunid = pgParentStepRunId
}
if opts.Statuses != nil {
statuses := make([]string, 0)
for _, status := range *opts.Statuses {
if status == "SCHEDULED" {
listOpts.Includescheduled = true
countParams.Includescheduled = true
continue
}
statuses = append(statuses, string(status))
}
listOpts.Statuses = statuses
countParams.Statuses = statuses
}
count, err := w.queries.CountScheduledWorkflows(ctx, w.pool, countParams)
if err != nil {
return nil, 0, err
}
if opts.Limit != nil {
listOpts.Limit = pgtype.Int4{
Int32: int32(*opts.Limit), // nolint: gosec
Valid: true,
}
}
if opts.Offset != nil {
listOpts.Offset = pgtype.Int4{
Int32: int32(*opts.Offset), // nolint: gosec
Valid: true,
}
}
orderByField := "triggerAt"
if opts.OrderBy != nil {
orderByField = *opts.OrderBy
}
orderByDirection := "DESC"
if opts.OrderDirection != nil {
orderByDirection = *opts.OrderDirection
}
listOpts.Orderby = orderByField + " " + orderByDirection
scheduledWorkflows, err := w.queries.ListScheduledWorkflows(ctx, w.pool, listOpts)
if err != nil {
return nil, 0, err
}
return scheduledWorkflows, count, nil
}
func (w *workflowRunAPIRepository) DeleteScheduledWorkflow(ctx context.Context, tenantId, scheduledWorkflowId string) error {
return w.queries.DeleteScheduledWorkflow(ctx, w.pool, sqlchelpers.UUIDFromStr(scheduledWorkflowId))
}
func (w *workflowRunAPIRepository) GetScheduledWorkflow(ctx context.Context, tenantId, scheduledWorkflowId string) (*dbsqlc.ListScheduledWorkflowsRow, error) {
listOpts := dbsqlc.ListScheduledWorkflowsParams{
Tenantid: sqlchelpers.UUIDFromStr(tenantId),
Scheduleid: sqlchelpers.UUIDFromStr(scheduledWorkflowId),
}
scheduledWorkflows, err := w.queries.ListScheduledWorkflows(ctx, w.pool, listOpts)
if err != nil {
return nil, err
}
if len(scheduledWorkflows) == 0 {
return nil, nil
}
return scheduledWorkflows[0], nil
}
func (w *workflowRunAPIRepository) UpdateScheduledWorkflow(ctx context.Context, tenantId, scheduledWorkflowId string, triggerAt time.Time) error {
return w.queries.UpdateScheduledWorkflow(ctx, w.pool, dbsqlc.UpdateScheduledWorkflowParams{
Scheduleid: sqlchelpers.UUIDFromStr(scheduledWorkflowId),
Triggerat: sqlchelpers.TimestampFromTime(triggerAt),
})
}
func (w *workflowRunAPIRepository) ListCronWorkflows(ctx context.Context, tenantId string, opts *repository.ListCronWorkflowsOpts) ([]*dbsqlc.ListCronWorkflowsRow, int64, error) {
if err := w.v.Validate(opts); err != nil {
return nil, 0, err
}
ctx, cancel := context.WithTimeout(ctx, time.Second*30)
defer cancel()
count, err := w.queries.CountCronWorkflows(ctx, w.pool, sqlchelpers.UUIDFromStr(tenantId))
if err != nil {
return nil, 0, err
}
listOpts := dbsqlc.ListCronWorkflowsParams{
Tenantid: sqlchelpers.UUIDFromStr(tenantId),
}
if opts.Limit != nil {
listOpts.Limit = pgtype.Int4{
Int32: int32(*opts.Limit), // nolint: gosec
Valid: true,
}
}
if opts.Offset != nil {
listOpts.Offset = pgtype.Int4{
Int32: int32(*opts.Offset), // nolint: gosec
Valid: true,
}
}
orderByField := "createdAt"
if opts.OrderBy != nil {
orderByField = *opts.OrderBy
}
orderByDirection := "DESC"
if opts.OrderDirection != nil {
orderByDirection = *opts.OrderDirection
}
listOpts.Orderby = orderByField + " " + orderByDirection
cronWorkflows, err := w.queries.ListCronWorkflows(ctx, w.pool, listOpts)
if err != nil {
return nil, 0, err
}
return cronWorkflows, count, nil
}
func (w *workflowRunEngineRepository) GetWorkflowRunInputData(tenantId, workflowRunId string) (map[string]interface{}, error) {
lookupData := datautils.JobRunLookupData{}
+2 -1
View File
@@ -92,7 +92,8 @@ func (o *CreateWorkflowVersionOpts) Checksum() (string, error) {
type CreateWorkflowSchedulesOpts struct {
ScheduledTriggers []time.Time
Input []byte
Input []byte
AdditionalMetadata []byte
}
type CreateWorkflowTagOpts struct {
+67
View File
@@ -388,6 +388,58 @@ type StepRunForJobRun struct {
ChildWorkflowsCount int
}
type ListScheduledWorkflowsOpts struct {
// (optional) number of events to skip
Offset *int
// (optional) number of events to return
Limit *int
// (optional) the order by field
OrderBy *string `validate:"omitempty,oneof=createdAt triggerAt"`
// (optional) the order direction
OrderDirection *string `validate:"omitempty,oneof=ASC DESC"`
// (optional) the workflow id
WorkflowId *string `validate:"omitempty,uuid"`
// (optional) the parent workflow run id
ParentWorkflowRunId *string `validate:"omitempty,uuid"`
// (optional) the parent step run id
ParentStepRunId *string `validate:"omitempty,uuid"`
// (optional) statuses to filter by
Statuses *[]db.WorkflowRunStatus
// (optional) include scheduled runs that are in the future
IncludeFuture *bool
// (optional) additional metadata for the workflow run
AdditionalMetadata map[string]interface{} `validate:"omitempty"`
}
type ListCronWorkflowsOpts struct {
// (optional) number of events to skip
Offset *int
// (optional) number of events to return
Limit *int
// (optional) the order by field
OrderBy *string `validate:"omitempty,oneof=createdAt finishedAt startedAt duration"`
// (optional) the order direction
OrderDirection *string `validate:"omitempty,oneof=ASC DESC"`
// (optional) the workflow id
WorkflowId *string `validate:"omitempty,uuid"`
// (optional) additional metadata for the workflow run
AdditionalMetadata map[string]interface{} `validate:"omitempty"`
}
type WorkflowRunAPIRepository interface {
RegisterCreateCallback(callback Callback[*dbsqlc.WorkflowRun])
@@ -397,6 +449,21 @@ type WorkflowRunAPIRepository interface {
// Counts by status
WorkflowRunMetricsCount(ctx context.Context, tenantId string, opts *WorkflowRunsMetricsOpts) (*dbsqlc.WorkflowRunsMetricsCountRow, error)
// List ScheduledWorkflows lists workflows by scheduled trigger
ListScheduledWorkflows(ctx context.Context, tenantId string, opts *ListScheduledWorkflowsOpts) ([]*dbsqlc.ListScheduledWorkflowsRow, int64, error)
// DeleteScheduledWorkflow deletes a scheduled workflow run
DeleteScheduledWorkflow(ctx context.Context, tenantId, scheduledWorkflowId string) error
// GetScheduledWorkflow gets a scheduled workflow run
GetScheduledWorkflow(ctx context.Context, tenantId, scheduledWorkflowId string) (*dbsqlc.ListScheduledWorkflowsRow, error)
// UpdateScheduledWorkflow updates a scheduled workflow run
UpdateScheduledWorkflow(ctx context.Context, tenantId, scheduledWorkflowId string, triggerAt time.Time) error
// List ScheduledWorkflows lists workflows by scheduled trigger
ListCronWorkflows(ctx context.Context, tenantId string, opts *ListCronWorkflowsOpts) ([]*dbsqlc.ListCronWorkflowsRow, int64, error)
// CreateNewWorkflowRun creates a new workflow run for a workflow version.
CreateNewWorkflowRun(ctx context.Context, tenantId string, opts *CreateWorkflowRunOpts) (*dbsqlc.WorkflowRun, error)
@@ -0,0 +1,11 @@
-- AlterTable
ALTER TABLE "WorkflowTriggerCronRef" ADD COLUMN "additionalMetadata" JSONB,
ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "deletedAt" TIMESTAMP(3),
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "WorkflowTriggerScheduledRef" ADD COLUMN "additionalMetadata" JSONB,
ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "deletedAt" TIMESTAMP(3),
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
+12 -1
View File
@@ -649,8 +649,11 @@ model WorkflowTriggerCronRef {
parent WorkflowTriggers @relation(fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the cron expression
cron String
cron String
// whether this cron is enabled or not
enabled Boolean @default(true)
@@ -664,6 +667,8 @@ model WorkflowTriggerCronRef {
// the input parameters to the scheduled workflow
input Json?
additionalMetadata Json?
// cron references must be unique per workflow
@@unique([parentId, cron])
}
@@ -671,6 +676,10 @@ model WorkflowTriggerCronRef {
model WorkflowTriggerScheduledRef {
id String @id @unique @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?
// the parent workflow
parent WorkflowVersion @relation(fields: [parentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
parentId String @db.Uuid
@@ -700,6 +709,8 @@ model WorkflowTriggerScheduledRef {
triggered WorkflowRunTriggeredBy?
additionalMetadata Json?
@@unique([parentId, parentStepRunId, childKey])
}
@@ -0,0 +1,4 @@
-- Modify "WorkflowTriggerCronRef" table
ALTER TABLE "WorkflowTriggerCronRef" ADD COLUMN "additionalMetadata" jsonb NULL, ADD COLUMN "createdAt" timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, ADD COLUMN "deletedAt" timestamp(3) NULL, ADD COLUMN "updatedAt" timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- Modify "WorkflowTriggerScheduledRef" table
ALTER TABLE "WorkflowTriggerScheduledRef" ADD COLUMN "additionalMetadata" jsonb NULL, ADD COLUMN "createdAt" timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, ADD COLUMN "deletedAt" timestamp(3) NULL, ADD COLUMN "updatedAt" timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
+2 -1
View File
@@ -1,4 +1,4 @@
h1:HGM1c6iDEBc8vMfSGR25SWgBr55zNkUyBGEQTIrdQGU=
h1:y8lBsbOHVrTOEIGR+vDKOBwtZe5Tbkv+9juCrSYtd14=
20240115180414_init.sql h1:Ef3ZyjAHkmJPdGF/dEWCahbwgcg6uGJKnDxW2JCRi2k=
20240122014727_v0_6_0.sql h1:o/LdlteAeFgoHJ3e/M4Xnghqt9826IE/Y/h0q95Acuo=
20240126235456_v0_7_0.sql h1:KiVzt/hXgQ6esbdC6OMJOOWuYEXmy1yeCpmsVAHTFKs=
@@ -72,3 +72,4 @@ h1:HGM1c6iDEBc8vMfSGR25SWgBr55zNkUyBGEQTIrdQGU=
20241023112235_v0.50.3.sql h1:aW7fMNTT9o3gg8TJhDM3juB/tWho3j9M6VYsbMqSNcw=
20241023223039_v0.50.4.sql h1:eXJLlkM6ZzqzZ4RbAZtoTiW7WjJPIJ5L6UkIKy6w9Uk=
20241025162439_v0.50.5.sql h1:CIv/oSeiVR1D3rOb4z8uv2t0XUI62TyK+0UI0s6tQ/k=
20241029122625_v0.51.0.sql h1:nOa4FqmZxSh1yBOJyduX+j15gQavjizTn660wyXjhNk=
+9 -1
View File
@@ -901,7 +901,11 @@ CREATE TABLE "WorkflowTriggerCronRef" (
"cron" TEXT NOT NULL,
"tickerId" UUID,
"input" JSONB,
"enabled" BOOLEAN NOT NULL DEFAULT true
"enabled" BOOLEAN NOT NULL DEFAULT true,
"additionalMetadata" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deletedAt" TIMESTAMP(3),
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CreateTable
@@ -921,6 +925,10 @@ CREATE TABLE "WorkflowTriggerScheduledRef" (
"childKey" TEXT,
"parentStepRunId" UUID,
"parentWorkflowRunId" UUID,
"additionalMetadata" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deletedAt" TIMESTAMP(3),
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "WorkflowTriggerScheduledRef_pkey" PRIMARY KEY ("id")
);