mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2026-04-20 08:42:45 -05:00
230 lines
6.7 KiB
Go
230 lines
6.7 KiB
Go
// Deprecated: This package is part of the legacy v0 workflow definition system.
|
|
// Use the new Go SDK at github.com/hatchet-dev/hatchet/sdks/go instead. Migration guide: https://docs.hatchet.run/home/migration-guide-go
|
|
package condition
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
contracts "github.com/hatchet-dev/hatchet/internal/services/shared/proto/v1"
|
|
)
|
|
|
|
// Condition represents a set of conditions to either trigger a task or satisfy a wait condition.
|
|
// Callers should not use Condition directly. Instead, you should use a condition wrapper, such
|
|
// as Conditions, SleepCondition, UserEventCondition, ParentCondition, Or.
|
|
type Condition interface {
|
|
ToPB(action contracts.Action) *ConditionMulti
|
|
}
|
|
|
|
type ConditionMulti struct {
|
|
SleepConditions []*contracts.SleepMatchCondition
|
|
UserEventConditions []*contracts.UserEventMatchCondition
|
|
ParentConditions []*contracts.ParentOverrideMatchCondition
|
|
}
|
|
|
|
type baseCondition struct {
|
|
readableDataKey string
|
|
orGroupID uuid.UUID
|
|
expression string
|
|
}
|
|
|
|
func (b *baseCondition) baseCondition(action contracts.Action) *contracts.BaseMatchCondition {
|
|
return &contracts.BaseMatchCondition{
|
|
ReadableDataKey: b.readableDataKey,
|
|
Action: action,
|
|
OrGroupId: b.orGroupID.String(),
|
|
Expression: b.expression,
|
|
}
|
|
}
|
|
|
|
func (b *baseCondition) ToPB(action contracts.Action) *ConditionMulti {
|
|
return &ConditionMulti{
|
|
SleepConditions: nil,
|
|
UserEventConditions: nil,
|
|
ParentConditions: nil,
|
|
}
|
|
}
|
|
|
|
type sleepCondition struct {
|
|
*baseCondition
|
|
|
|
duration time.Duration
|
|
}
|
|
|
|
// SleepCondition creates a new condition that waits for a specified duration.
|
|
func SleepCondition(duration time.Duration) *sleepCondition {
|
|
return &sleepCondition{
|
|
baseCondition: &baseCondition{
|
|
readableDataKey: "sleep:" + duration.String(),
|
|
orGroupID: uuid.New(),
|
|
},
|
|
duration: duration,
|
|
}
|
|
}
|
|
|
|
func (s *sleepCondition) Key() string {
|
|
return s.readableDataKey
|
|
}
|
|
|
|
func (s *sleepCondition) ToPB(action contracts.Action) *ConditionMulti {
|
|
sleep := &contracts.SleepMatchCondition{
|
|
Base: s.baseCondition.baseCondition(action),
|
|
SleepFor: s.duration.String(),
|
|
}
|
|
|
|
return &ConditionMulti{
|
|
SleepConditions: []*contracts.SleepMatchCondition{sleep},
|
|
UserEventConditions: nil,
|
|
ParentConditions: nil,
|
|
}
|
|
}
|
|
|
|
type userEventCondition struct {
|
|
baseCondition
|
|
|
|
eventKey string
|
|
}
|
|
|
|
// UserEventCondition creates a new condition that waits for a user event to occur.
|
|
// The eventKey is the key of the user event that the condition is waiting for.
|
|
// The expression is an optional CEL expression that can be used to filter the user event,
|
|
// such as `event.data.key == "value"`.
|
|
func UserEventCondition(eventKey string, expression string) *userEventCondition {
|
|
return &userEventCondition{
|
|
baseCondition: baseCondition{
|
|
readableDataKey: eventKey,
|
|
orGroupID: uuid.New(),
|
|
expression: expression,
|
|
},
|
|
eventKey: eventKey,
|
|
}
|
|
}
|
|
|
|
func (u *userEventCondition) ToPB(action contracts.Action) *ConditionMulti {
|
|
userEvent := &contracts.UserEventMatchCondition{
|
|
Base: u.baseCondition.baseCondition(action),
|
|
UserEventKey: u.eventKey,
|
|
}
|
|
|
|
return &ConditionMulti{
|
|
SleepConditions: nil,
|
|
UserEventConditions: []*contracts.UserEventMatchCondition{userEvent},
|
|
ParentConditions: nil,
|
|
}
|
|
}
|
|
|
|
type parentCondition struct {
|
|
baseCondition
|
|
|
|
parentReadableId string
|
|
}
|
|
|
|
// NamedTask defines an interface for task types that have a name
|
|
type NamedTask interface {
|
|
// GetName returns the name of the task
|
|
GetName() string
|
|
}
|
|
|
|
// ParentCondition creates a new condition that is satisfied based on the output of the parent task
|
|
// in a DAG.
|
|
func ParentCondition(parent NamedTask, expression string) *parentCondition {
|
|
return &parentCondition{
|
|
baseCondition: baseCondition{
|
|
readableDataKey: parent.GetName(),
|
|
orGroupID: uuid.New(),
|
|
expression: expression,
|
|
},
|
|
parentReadableId: parent.GetName(),
|
|
}
|
|
}
|
|
|
|
func (p *parentCondition) ToPB(action contracts.Action) *ConditionMulti {
|
|
parent := &contracts.ParentOverrideMatchCondition{
|
|
Base: p.baseCondition.baseCondition(action),
|
|
ParentReadableId: p.parentReadableId,
|
|
}
|
|
|
|
return &ConditionMulti{
|
|
SleepConditions: nil,
|
|
UserEventConditions: nil,
|
|
ParentConditions: []*contracts.ParentOverrideMatchCondition{parent},
|
|
}
|
|
}
|
|
|
|
type orGroup struct {
|
|
orGroupID uuid.UUID
|
|
conditions []Condition
|
|
}
|
|
|
|
// Or creates a new condition that is satisfied if any of the conditions in the group are satisfied.
|
|
// By default, conditions are evaluated as an intersection (AND). For more complex conditions, you can
|
|
// use Or to create a group of conditions that are evaluated as a union (OR).
|
|
func Or(conditions ...Condition) *orGroup {
|
|
return &orGroup{
|
|
orGroupID: uuid.New(),
|
|
conditions: conditions,
|
|
}
|
|
}
|
|
|
|
func (o *orGroup) ToPB(action contracts.Action) *ConditionMulti {
|
|
sleepConditions := make([]*contracts.SleepMatchCondition, 0)
|
|
userEventConditions := make([]*contracts.UserEventMatchCondition, 0)
|
|
parentConditions := make([]*contracts.ParentOverrideMatchCondition, 0)
|
|
|
|
for _, condition := range o.conditions {
|
|
c := condition.ToPB(action)
|
|
|
|
for _, sleepCondition := range c.SleepConditions {
|
|
sleepCondition.Base.OrGroupId = o.orGroupID.String()
|
|
sleepConditions = append(sleepConditions, sleepCondition)
|
|
}
|
|
|
|
for _, userEventCondition := range c.UserEventConditions {
|
|
userEventCondition.Base.OrGroupId = o.orGroupID.String()
|
|
userEventConditions = append(userEventConditions, userEventCondition)
|
|
}
|
|
|
|
for _, parentCondition := range c.ParentConditions {
|
|
parentCondition.Base.OrGroupId = o.orGroupID.String()
|
|
parentConditions = append(parentConditions, parentCondition)
|
|
}
|
|
}
|
|
|
|
return &ConditionMulti{
|
|
SleepConditions: sleepConditions,
|
|
UserEventConditions: userEventConditions,
|
|
ParentConditions: parentConditions,
|
|
}
|
|
}
|
|
|
|
type conditions struct {
|
|
conditions []Condition
|
|
}
|
|
|
|
// Conditions creates a new condition that is satisfied if all of the conditions are satisfied.
|
|
func Conditions(cs ...Condition) *conditions {
|
|
return &conditions{
|
|
conditions: cs,
|
|
}
|
|
}
|
|
|
|
func (c *conditions) ToPB(action contracts.Action) *ConditionMulti {
|
|
sleepConditions := make([]*contracts.SleepMatchCondition, 0)
|
|
userEventConditions := make([]*contracts.UserEventMatchCondition, 0)
|
|
parentConditions := make([]*contracts.ParentOverrideMatchCondition, 0)
|
|
|
|
for _, condition := range c.conditions {
|
|
c := condition.ToPB(action)
|
|
sleepConditions = append(sleepConditions, c.SleepConditions...)
|
|
userEventConditions = append(userEventConditions, c.UserEventConditions...)
|
|
parentConditions = append(parentConditions, c.ParentConditions...)
|
|
}
|
|
|
|
return &ConditionMulti{
|
|
SleepConditions: sleepConditions,
|
|
UserEventConditions: userEventConditions,
|
|
ParentConditions: parentConditions,
|
|
}
|
|
}
|