Files
hatchet/pkg/client/cron.go
Matt Kaye 80137736af Feat: Priority (#1513)
* feat: initial work wiring up priorities

* fix: add default to default prio in the db

* feat: wire priority through api on wf creation

* feat: extend python test

* feat: priority for scheduled workflows

* feat: wire priority through python api

* feat: more wiring priority through the api

* feat: I think it works?

* feat: e2e test for priority

* it works!

* feat: expand tests for default priorities

* feat: e2e scheduling test

* fix: skip broken test for now

* fix: lint

* feat: add priority columns to cron and schedule ref  tables

* feat: update inserts to include prio

* feat: wire up more apis

* feat: more wiring

* feat: wire up more rest api fields

* chore: cruft

* fix: more wiring

* fix: lint

* chore: gen + wire up priorities

* fix: retries

* fix: try changing fixture scope

* chore: bump version again

* feat: send priority with action payload

* fix: generate script

* Feat  priority ts (#1518)

* feat: initial work wiring up priorities

* fix: add default to default prio in the db

* feat: wire priority through api on wf creation

* feat: extend python test

* feat: priority for scheduled workflows

* feat: wire priority through python api

* feat: more wiring priority through the api

* feat: I think it works?

* feat: e2e test for priority

* it works!

* feat: expand tests for default priorities

* feat: e2e scheduling test

* chore: minor version for priority

* fix: skip broken test for now

* fix: lint

* feat: add priority columns to cron and schedule ref  tables

* feat: update inserts to include prio

* feat: wire up more apis

* feat: more wiring

* feat: wire up more rest api fields

* chore: cruft

* fix: more wiring

* fix: lint

* chore: gen + wire up priorities

* fix: increase timeout

* fix: retries

* fix: try changing fixture scope

* chore: generate

* fix: set schedule priority

* feat: priority

* fix: move priority to wf

* release: 1.2.0

* rm log

* fix: import

* fix: add priority to step

---------

Co-authored-by: mrkaye97 <mrkaye97@gmail.com>

* fix: add dummy runs to priority test to prevent race conditions

* fix: non-breaking field

* fix: gen

* feat: initial pass at docs

* feat: priority in go sdk

* feat: initial work on go example

* fix: doc examples

* fix: proofread

* chore: version

* feat: go sdk

* fix: lint

* fix: declarations and add back RunAsChild

* fix: child workflows

* fix: namespace

* fix: faster child workflows

* fix: sticky

* add back run as child

---------

Co-authored-by: Gabe Ruttner <gabriel.ruttner@gmail.com>
Co-authored-by: Alexander Belanger <alexander@hatchet.run>
2025-04-14 16:22:00 -04:00

160 lines
3.5 KiB
Go

package client
import (
"context"
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/rs/zerolog"
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
"github.com/hatchet-dev/hatchet/pkg/client/rest"
"github.com/hatchet-dev/hatchet/pkg/validator"
)
type CronOpts struct {
// Name is the user-friendly name for the cron trigger
Name string
// Expression is the cron expression for the trigger
Expression string
// Input is the input to the workflow
Input map[string]interface{}
// AdditionalMetadata is additional metadata to be stored with the cron trigger
AdditionalMetadata map[string]string
// Priority is the priority of the run triggered by the cron
Priority *int32
}
type CronClient interface {
// Create creates a new cron trigger
Create(ctx context.Context, workflow string, opts *CronOpts) (*gen.CronWorkflows, error)
// Delete deletes a cron trigger
Delete(ctx context.Context, id string) error
// List lists all cron triggers
List(ctx context.Context) (*gen.CronWorkflowsList, error)
}
type cronClientImpl struct {
restClient *rest.ClientWithResponses
l *zerolog.Logger
v validator.Validator
tenantId uuid.UUID
namespace string
}
func NewCronClient(restClient *rest.ClientWithResponses, l *zerolog.Logger, v validator.Validator, tenantId, namespace string) (CronClient, error) {
tenantIdUUID, err := uuid.Parse(tenantId)
if err != nil {
return nil, err
}
return &cronClientImpl{
restClient: restClient,
l: l,
v: v,
namespace: namespace,
tenantId: tenantIdUUID,
}, nil
}
func (c *cronClientImpl) Create(ctx context.Context, workflow string, opts *CronOpts) (*gen.CronWorkflows, error) {
additionalMeta := make(map[string]any)
for k, v := range opts.AdditionalMetadata {
additionalMeta[k] = v
}
resp, err := c.restClient.CronWorkflowTriggerCreate(
ctx,
c.tenantId,
workflow,
rest.CreateCronWorkflowTriggerRequest{
CronName: opts.Name,
CronExpression: opts.Expression,
Input: opts.Input,
AdditionalMetadata: additionalMeta,
Priority: opts.Priority,
},
)
if err != nil {
return nil, err
}
// if response code is not 200-level, return an error
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
// parse the response body into a cron trigger
cron := &gen.CronWorkflows{}
err = json.NewDecoder(resp.Body).Decode(cron)
if err != nil {
return nil, fmt.Errorf("could not unmarshal response body: %w", err)
}
return cron, nil
}
func (c *cronClientImpl) Delete(ctx context.Context, id string) error {
idUUID, err := uuid.Parse(id)
if err != nil {
return fmt.Errorf("could not parse id: %w", err)
}
resp, err := c.restClient.WorkflowCronDelete(
ctx,
c.tenantId,
idUUID,
)
if err != nil {
return err
}
// if response code is not 200-level, return an error
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
return nil
}
func (c *cronClientImpl) List(ctx context.Context) (*gen.CronWorkflowsList, error) {
resp, err := c.restClient.CronWorkflowList(
ctx,
c.tenantId,
&rest.CronWorkflowListParams{},
)
if err != nil {
return nil, err
}
// parse the response body into a list of cron triggers
cronList := &gen.CronWorkflowsList{}
err = json.NewDecoder(resp.Body).Decode(&cronList)
if err != nil {
return nil, fmt.Errorf("could not unmarshal response body: %w", err)
}
return cronList, nil
}