feat: multiple workflow concurrency keys (#1511)

* feat: multiple workflow concurrency keys

* [Python]: Allow multiple workflow-level concurrency keys (#1512)

* chore: generate

* feat: multi concurrency

* chore: version

* feat: example + test

* fix: expand tests

* Feat  ts multiple wf concurrency (#1522)

* feat: multiple concurrency

* release: 1.2.0

* fix: merge

* fix: concurrency defn

* fix: ts multiple concurrency backwards compat (#1531)

* fix

* gen

* chore: lint

---------

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

---------

Co-authored-by: Gabe Ruttner <gabriel.ruttner@gmail.com>

* chore: ver

* chore: gen

* chore: versions

* fix: manually rename migration

* fix: patch ver

---------

Co-authored-by: mrkaye97 <mrkaye97@gmail.com>
Co-authored-by: Gabe Ruttner <gabriel.ruttner@gmail.com>
This commit is contained in:
abelanger5
2025-04-14 17:29:17 -04:00
committed by GitHub
parent 9f3addca82
commit c6abd6b9d2
30 changed files with 1116 additions and 476 deletions
+3
View File
@@ -75,11 +75,14 @@ message CreateWorkflowVersionRequest {
repeated string event_triggers = 4; // (optional) event triggers for the workflow
repeated string cron_triggers = 5; // (optional) cron triggers for the workflow
repeated CreateTaskOpts tasks = 6; // (required) the workflow jobs
// Deprecated: use concurrency_arr instead
Concurrency concurrency = 7; // (optional) the workflow concurrency options
optional string cron_input = 8; // (optional) the input for the cron trigger
optional CreateTaskOpts on_failure_task = 9; // (optional) the job to run on failure
optional StickyStrategy sticky = 10; // (optional) the sticky strategy for assigning steps to workers
optional int32 default_priority = 11; // (optional) the default priority for the workflow
repeated Concurrency concurrency_arr = 12; // (optional) the workflow concurrency options
}
enum ConcurrencyLimitStrategy {
+24 -2
View File
@@ -486,7 +486,7 @@ func getCreateWorkflowOpts(req *contracts.CreateWorkflowVersionRequest) (*v1.Cre
sticky = &s
}
var concurrency *v1.CreateConcurrencyOpts
var concurrency []v1.CreateConcurrencyOpts
if req.Concurrency != nil {
if req.Concurrency.Expression == "" {
@@ -503,11 +503,33 @@ func getCreateWorkflowOpts(req *contracts.CreateWorkflowVersionRequest) (*v1.Cre
limitStrategy = &s
}
concurrency = &v1.CreateConcurrencyOpts{
concurrency = append(concurrency, v1.CreateConcurrencyOpts{
LimitStrategy: limitStrategy,
Expression: req.Concurrency.Expression,
MaxRuns: req.Concurrency.MaxRuns,
})
}
for _, c := range req.ConcurrencyArr {
if c.Expression == "" {
return nil, status.Error(
codes.InvalidArgument,
"CEL expression is required for concurrency",
)
}
var limitStrategy *string
if c.LimitStrategy != nil && c.LimitStrategy.String() != "" {
s := c.LimitStrategy.String()
limitStrategy = &s
}
concurrency = append(concurrency, v1.CreateConcurrencyOpts{
LimitStrategy: limitStrategy,
Expression: c.Expression,
MaxRuns: c.MaxRuns,
})
}
var cronInput []byte
+201 -188
View File
@@ -648,17 +648,19 @@ type CreateWorkflowVersionRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // (required) the workflow name
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // (optional) the workflow description
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // (optional) the workflow version
EventTriggers []string `protobuf:"bytes,4,rep,name=event_triggers,json=eventTriggers,proto3" json:"event_triggers,omitempty"` // (optional) event triggers for the workflow
CronTriggers []string `protobuf:"bytes,5,rep,name=cron_triggers,json=cronTriggers,proto3" json:"cron_triggers,omitempty"` // (optional) cron triggers for the workflow
Tasks []*CreateTaskOpts `protobuf:"bytes,6,rep,name=tasks,proto3" json:"tasks,omitempty"` // (required) the workflow jobs
Concurrency *Concurrency `protobuf:"bytes,7,opt,name=concurrency,proto3" json:"concurrency,omitempty"` // (optional) the workflow concurrency options
CronInput *string `protobuf:"bytes,8,opt,name=cron_input,json=cronInput,proto3,oneof" json:"cron_input,omitempty"` // (optional) the input for the cron trigger
OnFailureTask *CreateTaskOpts `protobuf:"bytes,9,opt,name=on_failure_task,json=onFailureTask,proto3,oneof" json:"on_failure_task,omitempty"` // (optional) the job to run on failure
Sticky *StickyStrategy `protobuf:"varint,10,opt,name=sticky,proto3,enum=v1.StickyStrategy,oneof" json:"sticky,omitempty"` // (optional) the sticky strategy for assigning steps to workers
DefaultPriority *int32 `protobuf:"varint,11,opt,name=default_priority,json=defaultPriority,proto3,oneof" json:"default_priority,omitempty"` // (optional) the default priority for the workflow
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // (required) the workflow name
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // (optional) the workflow description
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // (optional) the workflow version
EventTriggers []string `protobuf:"bytes,4,rep,name=event_triggers,json=eventTriggers,proto3" json:"event_triggers,omitempty"` // (optional) event triggers for the workflow
CronTriggers []string `protobuf:"bytes,5,rep,name=cron_triggers,json=cronTriggers,proto3" json:"cron_triggers,omitempty"` // (optional) cron triggers for the workflow
Tasks []*CreateTaskOpts `protobuf:"bytes,6,rep,name=tasks,proto3" json:"tasks,omitempty"` // (required) the workflow jobs
// Deprecated: use concurrency_arr instead
Concurrency *Concurrency `protobuf:"bytes,7,opt,name=concurrency,proto3" json:"concurrency,omitempty"` // (optional) the workflow concurrency options
CronInput *string `protobuf:"bytes,8,opt,name=cron_input,json=cronInput,proto3,oneof" json:"cron_input,omitempty"` // (optional) the input for the cron trigger
OnFailureTask *CreateTaskOpts `protobuf:"bytes,9,opt,name=on_failure_task,json=onFailureTask,proto3,oneof" json:"on_failure_task,omitempty"` // (optional) the job to run on failure
Sticky *StickyStrategy `protobuf:"varint,10,opt,name=sticky,proto3,enum=v1.StickyStrategy,oneof" json:"sticky,omitempty"` // (optional) the sticky strategy for assigning steps to workers
DefaultPriority *int32 `protobuf:"varint,11,opt,name=default_priority,json=defaultPriority,proto3,oneof" json:"default_priority,omitempty"` // (optional) the default priority for the workflow
ConcurrencyArr []*Concurrency `protobuf:"bytes,12,rep,name=concurrency_arr,json=concurrencyArr,proto3" json:"concurrency_arr,omitempty"` // (optional) the workflow concurrency options
}
func (x *CreateWorkflowVersionRequest) Reset() {
@@ -770,6 +772,13 @@ func (x *CreateWorkflowVersionRequest) GetDefaultPriority() int32 {
return 0
}
func (x *CreateWorkflowVersionRequest) GetConcurrencyArr() []*Concurrency {
if x != nil {
return x.ConcurrencyArr
}
return nil
}
type Concurrency struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1271,7 +1280,7 @@ var file_v1_workflows_proto_rawDesc = []byte{
0x3d, 0x0a, 0x1a, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a,
0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xa0,
0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0xda,
0x04, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,
0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
@@ -1301,161 +1310,164 @@ var file_v1_workflows_proto_rawDesc = []byte{
0x79, 0x48, 0x02, 0x52, 0x06, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x88, 0x01, 0x01, 0x12, 0x2e,
0x0a, 0x10, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69,
0x74, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x48, 0x03, 0x52, 0x0f, 0x64, 0x65, 0x66, 0x61,
0x75, 0x6c, 0x74, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0d,
0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x12, 0x0a,
0x10, 0x5f, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x61, 0x73,
0x6b, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x42, 0x13, 0x0a, 0x11,
0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74,
0x79, 0x22, 0xb7, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63,
0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f,
0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x02, 0x20,
0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x75, 0x6e, 0x73, 0x88, 0x01,
0x01, 0x12, 0x48, 0x0a, 0x0e, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74,
0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x76, 0x31, 0x2e, 0x43,
0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53,
0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x48, 0x01, 0x52, 0x0d, 0x6c, 0x69, 0x6d, 0x69, 0x74,
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f,
0x6d, 0x61, 0x78, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x96, 0x02, 0x0a, 0x13,
0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69,
0x72, 0x65, 0x64, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72,
0x61, 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e,
0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61,
0x72, 0x61, 0x74, 0x6f, 0x72, 0x48, 0x03, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61,
0x74, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x48, 0x04, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a,
0x09, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63,
0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x77, 0x65,
0x69, 0x67, 0x68, 0x74, 0x22, 0xda, 0x05, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54,
0x61, 0x73, 0x6b, 0x4f, 0x70, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x61,
0x62, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65,
0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e,
0x70, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20,
0x03, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07,
0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72,
0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c,
0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x4c,
0x69, 0x6d, 0x69, 0x74, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73,
0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x4f, 0x70, 0x74, 0x73, 0x2e, 0x57, 0x6f, 0x72, 0x6b,
0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x77,
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x62,
0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x09, 0x20,
0x01, 0x28, 0x02, 0x48, 0x00, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x46, 0x61,
0x63, 0x74, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x13, 0x62, 0x61, 0x63, 0x6b, 0x6f,
0x66, 0x66, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a,
0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x11, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x4d,
0x61, 0x78, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x0b,
0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12,
0x37, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e,
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65,
0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0d, 0x20, 0x01,
0x28, 0x09, 0x48, 0x03, 0x52, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x69,
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x88, 0x01, 0x01, 0x1a, 0x58, 0x0a, 0x11, 0x57, 0x6f, 0x72, 0x6b,
0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
0x38, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66,
0x61, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66,
0x66, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x0d, 0x0a,
0x0b, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x13, 0x0a, 0x11,
0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
0x74, 0x22, 0xb8, 0x02, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b,
0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x05, 0x75,
0x6e, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e,
0x69, 0x74, 0x73, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78,
0x70, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x45,
0x78, 0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f,
0x65, 0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x09, 0x75, 0x6e,
0x69, 0x74, 0x73, 0x45, 0x78, 0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x69,
0x6d, 0x69, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18,
0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x0f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x56, 0x61,
0x6c, 0x75, 0x65, 0x73, 0x45, 0x78, 0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x08, 0x64,
0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e,
0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x48, 0x04, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x42, 0x0b, 0x0a,
0x09, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75,
0x6e, 0x69, 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x69,
0x6d, 0x69, 0x74, 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, 0x50, 0x0a, 0x1d,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a,
0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 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, 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, 0x2a, 0x7f, 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, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x4e, 0x45, 0x57, 0x45,
0x53, 0x54, 0x10, 0x04, 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, 0x32, 0xb7, 0x02, 0x0a,
0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a,
0x0b, 0x50, 0x75, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x20, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73,
0x12, 0x16, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61,
0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73,
0x12, 0x16, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x53, 0x0a, 0x12, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b,
0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x12, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x69,
0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x67,
0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 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, 0x73, 0x68, 0x61, 0x72, 0x65,
0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x75, 0x6c, 0x74, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x38,
0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x61, 0x72,
0x72, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72,
0x72, 0x65, 0x6e, 0x63, 0x79, 0x41, 0x72, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x6f,
0x6e, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x6f, 0x6e, 0x5f, 0x66,
0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x42, 0x09, 0x0a, 0x07, 0x5f,
0x73, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0xb7, 0x01, 0x0a, 0x0b,
0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65,
0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x08, 0x6d,
0x61, 0x78, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52,
0x07, 0x6d, 0x61, 0x78, 0x52, 0x75, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x0e, 0x6c,
0x69, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72,
0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 0x48, 0x01, 0x52, 0x0d, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x75,
0x6e, 0x73, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x74, 0x72,
0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x96, 0x02, 0x0a, 0x13, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65,
0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a,
0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
0x00, 0x52, 0x08, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f,
0x0a, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x48, 0x01, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x88, 0x01, 0x01, 0x12,
0x1f, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
0x08, 0x48, 0x02, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x88, 0x01, 0x01,
0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x4c, 0x61, 0x62, 0x65, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x48,
0x03, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x88, 0x01, 0x01,
0x12, 0x1b, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
0x48, 0x04, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a,
0x09, 0x5f, 0x73, 0x74, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69,
0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x71, 0x75,
0x69, 0x72, 0x65, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x61,
0x74, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xda,
0x05, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x4f, 0x70, 0x74,
0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x61, 0x62, 0x6c, 0x65,
0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69,
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d,
0x65, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07,
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x70,
0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65,
0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73,
0x12, 0x38, 0x0a, 0x0b, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18,
0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x0a,
0x72, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x77, 0x6f,
0x72, 0x6b, 0x65, 0x72, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x24, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73,
0x6b, 0x4f, 0x70, 0x74, 0x73, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c,
0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66,
0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x02, 0x48, 0x00, 0x52,
0x0d, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x88, 0x01,
0x01, 0x12, 0x33, 0x0a, 0x13, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x6d, 0x61, 0x78,
0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01,
0x52, 0x11, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x4d, 0x61, 0x78, 0x53, 0x65, 0x63, 0x6f,
0x6e, 0x64, 0x73, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72,
0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0b, 0x63, 0x6f,
0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x37, 0x0a, 0x0a, 0x63, 0x6f, 0x6e,
0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x48, 0x02, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88,
0x01, 0x01, 0x12, 0x2e, 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x0f,
0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x88,
0x01, 0x01, 0x1a, 0x58, 0x0a, 0x11, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65,
0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65,
0x73, 0x69, 0x72, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x4c, 0x61, 0x62, 0x65, 0x6c,
0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x11, 0x0a, 0x0f,
0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x42,
0x16, 0x0a, 0x14, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x6d, 0x61, 0x78, 0x5f,
0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x6f, 0x6e, 0x64,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64,
0x75, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xb8, 0x02, 0x0a, 0x13,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69,
0x6d, 0x69, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x18, 0x02,
0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x88, 0x01, 0x01,
0x12, 0x1e, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x45, 0x78, 0x70, 0x72, 0x88, 0x01, 0x01,
0x12, 0x22, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x09, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x45, 0x78, 0x70,
0x72, 0x88, 0x01, 0x01, 0x12, 0x2f, 0x0a, 0x11, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48,
0x03, 0x52, 0x0f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x78,
0x70, 0x72, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74,
0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x04,
0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a,
0x06, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6b, 0x65, 0x79, 0x5f,
0x65, 0x78, 0x70, 0x72, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x73, 0x5f, 0x65,
0x78, 0x70, 0x72, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 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, 0x50, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66,
0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 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, 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, 0x2a, 0x7f, 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, 0x12, 0x11, 0x0a, 0x0d, 0x43,
0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x4e, 0x45, 0x57, 0x45, 0x53, 0x54, 0x10, 0x04, 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, 0x32, 0xb7, 0x02, 0x0a, 0x0c, 0x41, 0x64, 0x6d, 0x69, 0x6e,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x20, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x43,
0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x16, 0x2e, 0x76, 0x31, 0x2e,
0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x54, 0x61,
0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x52,
0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x16, 0x2e, 0x76, 0x31, 0x2e,
0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x61,
0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x54,
0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75,
0x6e, 0x12, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f,
0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1e, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x57, 0x6f, 0x72,
0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 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, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1503,27 +1515,28 @@ var file_v1_workflows_proto_depIdxs = []int32{
12, // 5: v1.CreateWorkflowVersionRequest.concurrency:type_name -> v1.Concurrency
14, // 6: v1.CreateWorkflowVersionRequest.on_failure_task:type_name -> v1.CreateTaskOpts
0, // 7: v1.CreateWorkflowVersionRequest.sticky:type_name -> v1.StickyStrategy
2, // 8: v1.Concurrency.limit_strategy:type_name -> v1.ConcurrencyLimitStrategy
3, // 9: v1.DesiredWorkerLabels.comparator:type_name -> v1.WorkerLabelComparator
15, // 10: v1.CreateTaskOpts.rate_limits:type_name -> v1.CreateTaskRateLimit
17, // 11: v1.CreateTaskOpts.worker_labels:type_name -> v1.CreateTaskOpts.WorkerLabelsEntry
12, // 12: v1.CreateTaskOpts.concurrency:type_name -> v1.Concurrency
19, // 13: v1.CreateTaskOpts.conditions:type_name -> v1.TaskConditions
1, // 14: v1.CreateTaskRateLimit.duration:type_name -> v1.RateLimitDuration
13, // 15: v1.CreateTaskOpts.WorkerLabelsEntry.value:type_name -> v1.DesiredWorkerLabels
11, // 16: v1.AdminService.PutWorkflow:input_type -> v1.CreateWorkflowVersionRequest
4, // 17: v1.AdminService.CancelTasks:input_type -> v1.CancelTasksRequest
5, // 18: v1.AdminService.ReplayTasks:input_type -> v1.ReplayTasksRequest
9, // 19: v1.AdminService.TriggerWorkflowRun:input_type -> v1.TriggerWorkflowRunRequest
16, // 20: v1.AdminService.PutWorkflow:output_type -> v1.CreateWorkflowVersionResponse
7, // 21: v1.AdminService.CancelTasks:output_type -> v1.CancelTasksResponse
8, // 22: v1.AdminService.ReplayTasks:output_type -> v1.ReplayTasksResponse
10, // 23: v1.AdminService.TriggerWorkflowRun:output_type -> v1.TriggerWorkflowRunResponse
20, // [20:24] is the sub-list for method output_type
16, // [16:20] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
16, // [16:16] is the sub-list for extension extendee
0, // [0:16] is the sub-list for field type_name
12, // 8: v1.CreateWorkflowVersionRequest.concurrency_arr:type_name -> v1.Concurrency
2, // 9: v1.Concurrency.limit_strategy:type_name -> v1.ConcurrencyLimitStrategy
3, // 10: v1.DesiredWorkerLabels.comparator:type_name -> v1.WorkerLabelComparator
15, // 11: v1.CreateTaskOpts.rate_limits:type_name -> v1.CreateTaskRateLimit
17, // 12: v1.CreateTaskOpts.worker_labels:type_name -> v1.CreateTaskOpts.WorkerLabelsEntry
12, // 13: v1.CreateTaskOpts.concurrency:type_name -> v1.Concurrency
19, // 14: v1.CreateTaskOpts.conditions:type_name -> v1.TaskConditions
1, // 15: v1.CreateTaskRateLimit.duration:type_name -> v1.RateLimitDuration
13, // 16: v1.CreateTaskOpts.WorkerLabelsEntry.value:type_name -> v1.DesiredWorkerLabels
11, // 17: v1.AdminService.PutWorkflow:input_type -> v1.CreateWorkflowVersionRequest
4, // 18: v1.AdminService.CancelTasks:input_type -> v1.CancelTasksRequest
5, // 19: v1.AdminService.ReplayTasks:input_type -> v1.ReplayTasksRequest
9, // 20: v1.AdminService.TriggerWorkflowRun:input_type -> v1.TriggerWorkflowRunRequest
16, // 21: v1.AdminService.PutWorkflow:output_type -> v1.CreateWorkflowVersionResponse
7, // 22: v1.AdminService.CancelTasks:output_type -> v1.CancelTasksResponse
8, // 23: v1.AdminService.ReplayTasks:output_type -> v1.ReplayTasksResponse
10, // 24: v1.AdminService.TriggerWorkflowRun:output_type -> v1.TriggerWorkflowRunResponse
21, // [21:25] is the sub-list for method output_type
17, // [17:21] is the sub-list for method input_type
17, // [17:17] is the sub-list for extension type_name
17, // [17:17] is the sub-list for extension extendee
0, // [0:17] is the sub-list for field type_name
}
func init() { file_v1_workflows_proto_init() }
+1 -1
View File
@@ -42,7 +42,7 @@ type WorkflowCreateOpts[I any] struct {
OnCron []string
// (optional) Concurrency settings to control parallel execution
Concurrency *types.Concurrency
Concurrency []types.Concurrency
// (optional) Strategy for sticky execution of workflow runs
StickyStrategy *types.StickyStrategy
@@ -2,8 +2,6 @@ package sqlcv1
import (
"context"
"encoding/json"
"fmt"
"github.com/jackc/pgx/v5/pgtype"
)
@@ -215,9 +213,6 @@ func (q *Queries) CreateTasks(ctx context.Context, db DBTX, arg CreateTasksParam
arg.WorkflowRunIds,
)
if err != nil {
argBytes, _ := json.Marshal(arg)
fmt.Println("FAILED ARG BYTES ARE", string(argBytes))
return nil, err
}
defer rows.Close()
@@ -263,17 +258,11 @@ func (q *Queries) CreateTasks(ctx context.Context, db DBTX, arg CreateTasksParam
&i.WorkflowVersionID,
&i.WorkflowRunID,
); err != nil {
argBytes, _ := json.Marshal(arg)
fmt.Println("FAILED ARG BYTES ARE", string(argBytes))
return nil, err
}
items = append(items, &i)
}
if err := rows.Err(); err != nil {
argBytes, _ := json.Marshal(arg)
fmt.Println("FAILED ARG BYTES ARE", string(argBytes))
return nil, err
}
return items, nil
+73
View File
@@ -438,6 +438,79 @@ WHERE
w."deletedAt" IS NULL AND
workflowVersions."deletedAt" IS NULL;
-- name: CreateWorkflowConcurrencyV1 :one
WITH inserted_wcs AS (
INSERT INTO v1_workflow_concurrency (
workflow_id,
workflow_version_id,
strategy,
expression,
tenant_id,
max_concurrency
)
VALUES (
@workflowId::uuid,
@workflowVersionId::uuid,
@limitStrategy::v1_concurrency_strategy,
@expression,
@tenantId::uuid,
COALESCE(sqlc.narg('maxRuns')::integer, 1)
)
RETURNING *
), inserted_scs AS (
INSERT INTO v1_step_concurrency (
parent_strategy_id,
workflow_id,
workflow_version_id,
step_id,
strategy,
expression,
tenant_id,
max_concurrency
)
SELECT
wcs.id,
s."workflowId",
s."workflowVersionId",
s."id",
@limitStrategy::v1_concurrency_strategy,
@expression,
s."tenantId",
COALESCE(sqlc.narg('maxRuns')::integer, 1)
FROM (
SELECT
s."id",
wf."id" AS "workflowId",
wv."id" AS "workflowVersionId",
wf."tenantId"
FROM "Step" s
JOIN "Job" j ON s."jobId" = j."id"
JOIN "WorkflowVersion" wv ON j."workflowVersionId" = wv."id"
JOIN "Workflow" wf ON wv."workflowId" = wf."id"
WHERE
wv."id" = @workflowVersionId::uuid
AND j."kind" = 'DEFAULT'
) s, inserted_wcs wcs
RETURNING *
)
SELECT
wcs.id,
ARRAY_AGG(scs.id)::bigint[] AS child_strategy_ids
FROM
inserted_wcs wcs
JOIN
inserted_scs scs ON scs.parent_strategy_id = wcs.id
GROUP BY
wcs.id;
-- name: UpdateWorkflowConcurrencyWithChildStrategyIds :exec
-- Update the workflow concurrency row using its primary key.
UPDATE v1_workflow_concurrency
SET child_strategy_ids = @childStrategyIds::bigint[]
WHERE workflow_id = @workflowId::uuid
AND workflow_version_id = @workflowVersionId::uuid
AND id = @workflowConcurrencyId::bigint;
-- name: CreateStepConcurrency :one
INSERT INTO v1_step_concurrency (
workflow_id,
+120
View File
@@ -501,6 +501,100 @@ func (q *Queries) CreateWorkflowConcurrency(ctx context.Context, db DBTX, arg Cr
return &i, err
}
const createWorkflowConcurrencyV1 = `-- name: CreateWorkflowConcurrencyV1 :one
WITH inserted_wcs AS (
INSERT INTO v1_workflow_concurrency (
workflow_id,
workflow_version_id,
strategy,
expression,
tenant_id,
max_concurrency
)
VALUES (
$1::uuid,
$2::uuid,
$3::v1_concurrency_strategy,
$4,
$5::uuid,
COALESCE($6::integer, 1)
)
RETURNING id, workflow_id, workflow_version_id, is_active, strategy, child_strategy_ids, expression, tenant_id, max_concurrency
), inserted_scs AS (
INSERT INTO v1_step_concurrency (
parent_strategy_id,
workflow_id,
workflow_version_id,
step_id,
strategy,
expression,
tenant_id,
max_concurrency
)
SELECT
wcs.id,
s."workflowId",
s."workflowVersionId",
s."id",
$3::v1_concurrency_strategy,
$4,
s."tenantId",
COALESCE($6::integer, 1)
FROM (
SELECT
s."id",
wf."id" AS "workflowId",
wv."id" AS "workflowVersionId",
wf."tenantId"
FROM "Step" s
JOIN "Job" j ON s."jobId" = j."id"
JOIN "WorkflowVersion" wv ON j."workflowVersionId" = wv."id"
JOIN "Workflow" wf ON wv."workflowId" = wf."id"
WHERE
wv."id" = $2::uuid
AND j."kind" = 'DEFAULT'
) s, inserted_wcs wcs
RETURNING id, parent_strategy_id, workflow_id, workflow_version_id, step_id, is_active, strategy, expression, tenant_id, max_concurrency
)
SELECT
wcs.id,
ARRAY_AGG(scs.id)::bigint[] AS child_strategy_ids
FROM
inserted_wcs wcs
JOIN
inserted_scs scs ON scs.parent_strategy_id = wcs.id
GROUP BY
wcs.id
`
type CreateWorkflowConcurrencyV1Params struct {
Workflowid pgtype.UUID `json:"workflowid"`
Workflowversionid pgtype.UUID `json:"workflowversionid"`
Limitstrategy V1ConcurrencyStrategy `json:"limitstrategy"`
Expression string `json:"expression"`
Tenantid pgtype.UUID `json:"tenantid"`
MaxRuns pgtype.Int4 `json:"maxRuns"`
}
type CreateWorkflowConcurrencyV1Row struct {
ID int64 `json:"id"`
ChildStrategyIds []int64 `json:"child_strategy_ids"`
}
func (q *Queries) CreateWorkflowConcurrencyV1(ctx context.Context, db DBTX, arg CreateWorkflowConcurrencyV1Params) (*CreateWorkflowConcurrencyV1Row, error) {
row := db.QueryRow(ctx, createWorkflowConcurrencyV1,
arg.Workflowid,
arg.Workflowversionid,
arg.Limitstrategy,
arg.Expression,
arg.Tenantid,
arg.MaxRuns,
)
var i CreateWorkflowConcurrencyV1Row
err := row.Scan(&i.ID, &i.ChildStrategyIds)
return &i, err
}
const createWorkflowTriggerCronRef = `-- name: CreateWorkflowTriggerCronRef :one
INSERT INTO "WorkflowTriggerCronRef" (
"parentId",
@@ -1263,6 +1357,32 @@ func (q *Queries) MoveScheduledTriggerToNewWorkflowTriggers(ctx context.Context,
return err
}
const updateWorkflowConcurrencyWithChildStrategyIds = `-- name: UpdateWorkflowConcurrencyWithChildStrategyIds :exec
UPDATE v1_workflow_concurrency
SET child_strategy_ids = $1::bigint[]
WHERE workflow_id = $2::uuid
AND workflow_version_id = $3::uuid
AND id = $4::bigint
`
type UpdateWorkflowConcurrencyWithChildStrategyIdsParams struct {
Childstrategyids []int64 `json:"childstrategyids"`
Workflowid pgtype.UUID `json:"workflowid"`
Workflowversionid pgtype.UUID `json:"workflowversionid"`
Workflowconcurrencyid int64 `json:"workflowconcurrencyid"`
}
// Update the workflow concurrency row using its primary key.
func (q *Queries) UpdateWorkflowConcurrencyWithChildStrategyIds(ctx context.Context, db DBTX, arg UpdateWorkflowConcurrencyWithChildStrategyIdsParams) error {
_, err := db.Exec(ctx, updateWorkflowConcurrencyWithChildStrategyIds,
arg.Childstrategyids,
arg.Workflowid,
arg.Workflowversionid,
arg.Workflowconcurrencyid,
)
return err
}
const upsertAction = `-- name: UpsertAction :one
INSERT INTO "Action" (
"id",
+33 -16
View File
@@ -40,7 +40,7 @@ type CreateWorkflowVersionOpts struct {
OnFailure *CreateStepOpts `json:"onFailureJob,omitempty" validate:"omitempty"`
// (optional) the workflow concurrency groups
Concurrency *CreateConcurrencyOpts `json:"concurrency,omitempty" validator:"omitnil"`
Concurrency []CreateConcurrencyOpts `json:"concurrency,omitempty" validator:"omitempty,dive"`
// (optional) sticky strategy
Sticky *string `validate:"omitempty,oneof=SOFT HARD"`
@@ -406,30 +406,32 @@ func (r *workflowRepository) createWorkflowVersionTxs(ctx context.Context, tx sq
// create concurrency group
// NOTE: we do this AFTER the creation of steps/jobs because we have a trigger which depends on the existence
// of the jobs/steps to create the v1 concurrency groups
if opts.Concurrency != nil {
params := sqlcv1.CreateWorkflowConcurrencyParams{
Workflowversionid: sqlcWorkflowVersion.ID,
ConcurrencyGroupExpression: sqlchelpers.TextFromStr(opts.Concurrency.Expression),
for _, wfConcurrency := range opts.Concurrency {
params := sqlcv1.CreateWorkflowConcurrencyV1Params{
Workflowid: workflowId,
Workflowversionid: sqlcWorkflowVersion.ID,
Expression: wfConcurrency.Expression,
Tenantid: tenantId,
}
if opts.Concurrency.MaxRuns != nil {
params.MaxRuns = sqlchelpers.ToInt(*opts.Concurrency.MaxRuns)
if wfConcurrency.MaxRuns != nil {
params.MaxRuns = pgtype.Int4{
Int32: *wfConcurrency.MaxRuns,
Valid: true,
}
}
var ls sqlcv1.ConcurrencyLimitStrategy
var ls sqlcv1.V1ConcurrencyStrategy
if opts.Concurrency.LimitStrategy != nil && *opts.Concurrency.LimitStrategy != "" {
ls = sqlcv1.ConcurrencyLimitStrategy(*opts.Concurrency.LimitStrategy)
if wfConcurrency.LimitStrategy != nil && *wfConcurrency.LimitStrategy != "" {
ls = sqlcv1.V1ConcurrencyStrategy(*wfConcurrency.LimitStrategy)
} else {
ls = sqlcv1.ConcurrencyLimitStrategyCANCELINPROGRESS
ls = sqlcv1.V1ConcurrencyStrategyCANCELINPROGRESS
}
params.LimitStrategy = sqlcv1.NullConcurrencyLimitStrategy{
Valid: true,
ConcurrencyLimitStrategy: ls,
}
params.Limitstrategy = ls
_, err = r.queries.CreateWorkflowConcurrency(
wcs, err := r.queries.CreateWorkflowConcurrencyV1(
ctx,
tx,
params,
@@ -438,6 +440,21 @@ func (r *workflowRepository) createWorkflowVersionTxs(ctx context.Context, tx sq
if err != nil {
return "", fmt.Errorf("could not create concurrency group: %w", err)
}
err = r.queries.UpdateWorkflowConcurrencyWithChildStrategyIds(
ctx,
tx,
sqlcv1.UpdateWorkflowConcurrencyWithChildStrategyIdsParams{
Workflowid: workflowId,
Workflowversionid: sqlcWorkflowVersion.ID,
Workflowconcurrencyid: wcs.ID,
Childstrategyids: wcs.ChildStrategyIds,
},
)
if err != nil {
return "", fmt.Errorf("could not create concurrency group: %w", err)
}
}
// create the workflow triggers
+10 -8
View File
@@ -132,7 +132,7 @@ type workflowDeclarationImpl[I any, O any] struct {
Description *string
OnEvents []string
OnCron []string
Concurrency *types.Concurrency
Concurrency []types.Concurrency
OnFailureTask *task.OnFailureTaskDeclaration[I]
StickyStrategy *types.StickyStrategy
@@ -746,18 +746,20 @@ func (w *workflowDeclarationImpl[I, O]) Dump() (*contracts.CreateWorkflowVersion
req.Description = *w.Description
}
if w.Concurrency != nil {
req.Concurrency = &contracts.Concurrency{
Expression: w.Concurrency.Expression,
MaxRuns: w.Concurrency.MaxRuns,
for _, concurrency := range w.Concurrency {
c := contracts.Concurrency{
Expression: concurrency.Expression,
MaxRuns: concurrency.MaxRuns,
}
if w.Concurrency.LimitStrategy != nil {
strategy := *w.Concurrency.LimitStrategy
if concurrency.LimitStrategy != nil {
strategy := *concurrency.LimitStrategy
strategyInt := contracts.ConcurrencyLimitStrategy_value[string(strategy)]
strategyEnum := contracts.ConcurrencyLimitStrategy(strategyInt)
req.Concurrency.LimitStrategy = &strategyEnum
c.LimitStrategy = &strategyEnum
}
req.ConcurrencyArr = append(req.ConcurrencyArr, &c)
}
if w.OnFailureTask != nil {
@@ -60,7 +60,7 @@ async def test_multi_concurrency_key(hatchet: Hatchet) -> None:
concurrency_multiple_keys_workflow.create_bulk_run_item(
WorkflowInput(
name=(name := choice(characters)),
digit=(digit := choice([str(i) for i in range(3)])),
digit=(digit := choice([str(i) for i in range(6)])),
),
options=TriggerWorkflowOptions(
additional_metadata={
@@ -71,7 +71,7 @@ async def test_multi_concurrency_key(hatchet: Hatchet) -> None:
},
),
)
for _ in range(100)
for _ in range(200)
]
)
@@ -79,7 +79,8 @@ async def test_multi_concurrency_key(hatchet: Hatchet) -> None:
workflows = (
await hatchet.workflows.aio_list(
workflow_name=concurrency_multiple_keys_workflow.name
workflow_name=concurrency_multiple_keys_workflow.name,
limit=1_000,
)
).rows
@@ -99,6 +100,7 @@ async def test_multi_concurrency_key(hatchet: Hatchet) -> None:
additional_metadata={
"test_run_id": test_run_id,
},
limit=1_000,
)
sorted_runs = sorted(
@@ -0,0 +1,155 @@
import asyncio
from collections import Counter
from datetime import datetime
from random import choice
from typing import Literal
from uuid import uuid4
import pytest
from pydantic import BaseModel
from examples.concurrency_workflow_level.worker import (
DIGIT_MAX_RUNS,
NAME_MAX_RUNS,
WorkflowInput,
concurrency_workflow_level_workflow,
)
from hatchet_sdk import Hatchet, TriggerWorkflowOptions
from hatchet_sdk.clients.rest.models.v1_task_summary import V1TaskSummary
Character = Literal["Anna", "Vronsky", "Stiva", "Dolly", "Levin", "Karenin"]
characters: list[Character] = [
"Anna",
"Vronsky",
"Stiva",
"Dolly",
"Levin",
"Karenin",
]
class RunMetadata(BaseModel):
test_run_id: str
key: str
name: Character
digit: str
started_at: datetime
finished_at: datetime
@staticmethod
def parse(task: V1TaskSummary) -> "RunMetadata":
return RunMetadata(
test_run_id=task.additional_metadata["test_run_id"], # type: ignore
key=task.additional_metadata["key"], # type: ignore
name=task.additional_metadata["name"], # type: ignore
digit=task.additional_metadata["digit"], # type: ignore
started_at=task.started_at or datetime.max,
finished_at=task.finished_at or datetime.min,
)
def __str__(self) -> str:
return self.key
@pytest.mark.asyncio()
async def test_workflow_level_concurrency(hatchet: Hatchet) -> None:
test_run_id = str(uuid4())
run_refs = await concurrency_workflow_level_workflow.aio_run_many_no_wait(
[
concurrency_workflow_level_workflow.create_bulk_run_item(
WorkflowInput(
name=(name := choice(characters)),
digit=(digit := choice([str(i) for i in range(6)])),
),
options=TriggerWorkflowOptions(
additional_metadata={
"test_run_id": test_run_id,
"key": f"{name}-{digit}",
"name": name,
"digit": digit,
},
),
)
for _ in range(200)
]
)
await asyncio.gather(*[r.aio_result() for r in run_refs])
workflows = (
await hatchet.workflows.aio_list(
workflow_name=concurrency_workflow_level_workflow.name,
limit=1_000,
)
).rows
assert workflows
workflow = next(
(w for w in workflows if w.name == concurrency_workflow_level_workflow.name),
None,
)
assert workflow
assert workflow.name == concurrency_workflow_level_workflow.name
runs = await hatchet.runs.aio_list(
workflow_ids=[workflow.metadata.id],
additional_metadata={
"test_run_id": test_run_id,
},
limit=1_000,
)
sorted_runs = sorted(
[RunMetadata.parse(r) for r in runs.rows], key=lambda r: r.started_at
)
overlapping_groups: dict[int, list[RunMetadata]] = {}
for run in sorted_runs:
has_group_membership = False
if not overlapping_groups:
overlapping_groups[1] = [run]
continue
if has_group_membership:
continue
for id, group in overlapping_groups.items():
if all(are_overlapping(run, task) for task in group):
overlapping_groups[id].append(run)
has_group_membership = True
break
if not has_group_membership:
overlapping_groups[len(overlapping_groups) + 1] = [run]
for id, group in overlapping_groups.items():
assert is_valid_group(group), f"Group {id} is not valid"
def are_overlapping(x: RunMetadata, y: RunMetadata) -> bool:
return (x.started_at < y.finished_at and x.finished_at > y.started_at) or (
x.finished_at > y.started_at and x.started_at < y.finished_at
)
def is_valid_group(group: list[RunMetadata]) -> bool:
digits = Counter[str]()
names = Counter[str]()
for task in group:
digits[task.digit] += 1
names[task.name] += 1
if any(v > DIGIT_MAX_RUNS for v in digits.values()):
return False
if any(v > NAME_MAX_RUNS for v in names.values()):
return False
return True
@@ -0,0 +1,65 @@
import asyncio
from pydantic import BaseModel
from hatchet_sdk import (
ConcurrencyExpression,
ConcurrencyLimitStrategy,
Context,
Hatchet,
)
hatchet = Hatchet(debug=True)
SLEEP_TIME = 2
DIGIT_MAX_RUNS = 8
NAME_MAX_RUNS = 3
# ❓ Concurrency Strategy With Key
class WorkflowInput(BaseModel):
name: str
digit: str
concurrency_workflow_level_workflow = hatchet.workflow(
name="ConcurrencyWorkflowManyKeys",
input_validator=WorkflowInput,
concurrency=[
ConcurrencyExpression(
expression="input.digit",
max_runs=DIGIT_MAX_RUNS,
limit_strategy=ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
),
ConcurrencyExpression(
expression="input.name",
max_runs=NAME_MAX_RUNS,
limit_strategy=ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
),
],
)
# ‼️
@concurrency_workflow_level_workflow.task()
async def task_1(input: WorkflowInput, ctx: Context) -> None:
await asyncio.sleep(SLEEP_TIME)
@concurrency_workflow_level_workflow.task()
async def task_2(input: WorkflowInput, ctx: Context) -> None:
await asyncio.sleep(SLEEP_TIME)
def main() -> None:
worker = hatchet.worker(
"concurrency-worker-workflow-level",
slots=10,
workflows=[concurrency_workflow_level_workflow],
)
worker.start()
if __name__ == "__main__":
main()
+4
View File
@@ -4,6 +4,9 @@ from examples.cancellation.worker import cancellation_workflow
from examples.concurrency_limit.worker import concurrency_limit_workflow
from examples.concurrency_limit_rr.worker import concurrency_limit_rr_workflow
from examples.concurrency_multiple_keys.worker import concurrency_multiple_keys_workflow
from examples.concurrency_workflow_level.worker import (
concurrency_workflow_level_workflow,
)
from examples.dag.worker import dag_workflow
from examples.dedupe.worker import dedupe_child_wf, dedupe_parent_wf
from examples.durable.worker import durable_workflow
@@ -48,6 +51,7 @@ def main() -> None:
sync_fanout_parent,
sync_fanout_child,
non_retryable_workflow,
concurrency_workflow_level_workflow,
priority_workflow,
lifespan_task,
],
File diff suppressed because one or more lines are too long
@@ -121,7 +121,7 @@ class TriggerWorkflowRunResponse(_message.Message):
def __init__(self, external_id: _Optional[str] = ...) -> None: ...
class CreateWorkflowVersionRequest(_message.Message):
__slots__ = ("name", "description", "version", "event_triggers", "cron_triggers", "tasks", "concurrency", "cron_input", "on_failure_task", "sticky", "default_priority")
__slots__ = ("name", "description", "version", "event_triggers", "cron_triggers", "tasks", "concurrency", "cron_input", "on_failure_task", "sticky", "default_priority", "concurrency_arr")
NAME_FIELD_NUMBER: _ClassVar[int]
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
VERSION_FIELD_NUMBER: _ClassVar[int]
@@ -133,6 +133,7 @@ class CreateWorkflowVersionRequest(_message.Message):
ON_FAILURE_TASK_FIELD_NUMBER: _ClassVar[int]
STICKY_FIELD_NUMBER: _ClassVar[int]
DEFAULT_PRIORITY_FIELD_NUMBER: _ClassVar[int]
CONCURRENCY_ARR_FIELD_NUMBER: _ClassVar[int]
name: str
description: str
version: str
@@ -144,7 +145,8 @@ class CreateWorkflowVersionRequest(_message.Message):
on_failure_task: CreateTaskOpts
sticky: StickyStrategy
default_priority: int
def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., version: _Optional[str] = ..., event_triggers: _Optional[_Iterable[str]] = ..., cron_triggers: _Optional[_Iterable[str]] = ..., tasks: _Optional[_Iterable[_Union[CreateTaskOpts, _Mapping]]] = ..., concurrency: _Optional[_Union[Concurrency, _Mapping]] = ..., cron_input: _Optional[str] = ..., on_failure_task: _Optional[_Union[CreateTaskOpts, _Mapping]] = ..., sticky: _Optional[_Union[StickyStrategy, str]] = ..., default_priority: _Optional[int] = ...) -> None: ...
concurrency_arr: _containers.RepeatedCompositeFieldContainer[Concurrency]
def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., version: _Optional[str] = ..., event_triggers: _Optional[_Iterable[str]] = ..., cron_triggers: _Optional[_Iterable[str]] = ..., tasks: _Optional[_Iterable[_Union[CreateTaskOpts, _Mapping]]] = ..., concurrency: _Optional[_Union[Concurrency, _Mapping]] = ..., cron_input: _Optional[str] = ..., on_failure_task: _Optional[_Union[CreateTaskOpts, _Mapping]] = ..., sticky: _Optional[_Union[StickyStrategy, str]] = ..., default_priority: _Optional[int] = ..., concurrency_arr: _Optional[_Iterable[_Union[Concurrency, _Mapping]]] = ...) -> None: ...
class Concurrency(_message.Message):
__slots__ = ("expression", "max_runs", "limit_strategy")
+14 -7
View File
@@ -188,7 +188,7 @@ class Hatchet:
version: str | None = None,
sticky: StickyStrategy | None = None,
default_priority: int = 1,
concurrency: ConcurrencyExpression | None = None,
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None,
task_defaults: TaskDefaults = TaskDefaults(),
) -> Workflow[EmptyModel]: ...
@@ -204,7 +204,7 @@ class Hatchet:
version: str | None = None,
sticky: StickyStrategy | None = None,
default_priority: int = 1,
concurrency: ConcurrencyExpression | None = None,
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None,
task_defaults: TaskDefaults = TaskDefaults(),
) -> Workflow[TWorkflowInput]: ...
@@ -219,7 +219,7 @@ class Hatchet:
version: str | None = None,
sticky: StickyStrategy | None = None,
default_priority: int = 1,
concurrency: ConcurrencyExpression | None = None,
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None,
task_defaults: TaskDefaults = TaskDefaults(),
) -> Workflow[EmptyModel] | Workflow[TWorkflowInput]:
"""
@@ -288,7 +288,7 @@ class Hatchet:
version: str | None = None,
sticky: StickyStrategy | None = None,
default_priority: int = 1,
concurrency: ConcurrencyExpression | None = None,
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None,
schedule_timeout: Duration = DEFAULT_SCHEDULE_TIMEOUT,
execution_timeout: Duration = DEFAULT_EXECUTION_TIMEOUT,
retries: int = 0,
@@ -310,7 +310,7 @@ class Hatchet:
version: str | None = None,
sticky: StickyStrategy | None = None,
default_priority: int = 1,
concurrency: ConcurrencyExpression | None = None,
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None,
schedule_timeout: Duration = DEFAULT_SCHEDULE_TIMEOUT,
execution_timeout: Duration = DEFAULT_EXECUTION_TIMEOUT,
retries: int = 0,
@@ -333,7 +333,7 @@ class Hatchet:
version: str | None = None,
sticky: StickyStrategy | None = None,
default_priority: int = 1,
concurrency: ConcurrencyExpression | None = None,
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None,
schedule_timeout: Duration = DEFAULT_SCHEDULE_TIMEOUT,
execution_timeout: Duration = DEFAULT_EXECUTION_TIMEOUT,
retries: int = 0,
@@ -417,6 +417,13 @@ class Hatchet:
self,
)
if isinstance(concurrency, list):
_concurrency = concurrency
elif isinstance(concurrency, ConcurrencyExpression):
_concurrency = [concurrency]
else:
_concurrency = []
task_wrapper = workflow.task(
name=name,
schedule_timeout=schedule_timeout,
@@ -427,7 +434,7 @@ class Hatchet:
desired_worker_labels=desired_worker_labels,
backoff_factor=backoff_factor,
backoff_max_seconds=backoff_max_seconds,
concurrency=[concurrency] if concurrency else [],
concurrency=_concurrency,
)
def inner(
+15 -9
View File
@@ -79,21 +79,15 @@ class WorkflowConfig(BaseModel):
on_events: list[str] = Field(default_factory=list)
on_crons: list[str] = Field(default_factory=list)
sticky: StickyStrategy | None = None
concurrency: ConcurrencyExpression | None = None
concurrency: ConcurrencyExpression | list[ConcurrencyExpression] | None = None
input_validator: Type[BaseModel] = EmptyModel
default_priority: int | None = None
task_defaults: TaskDefaults = TaskDefaults()
@model_validator(mode="after")
def validate_concurrency_expression(self) -> "WorkflowConfig":
if not self.concurrency:
return self
expr = self.concurrency.expression
def _raise_for_invalid_expression(self, expr: str) -> None:
if not expr.startswith("input."):
return self
return None
_, field = expr.split(".", maxsplit=2)
@@ -102,6 +96,18 @@ class WorkflowConfig(BaseModel):
f"The concurrency expression provided relies on the `{field}` field, which was not present in `{self.input_validator.__name__}`."
)
@model_validator(mode="after")
def validate_concurrency_expression(self) -> "WorkflowConfig":
if not self.concurrency:
return self
if isinstance(self.concurrency, list):
for item in self.concurrency:
self._raise_for_invalid_expression(item.expression)
if isinstance(self.concurrency, ConcurrencyExpression):
self._raise_for_invalid_expression(self.concurrency.expression)
return self
+12 -1
View File
@@ -137,6 +137,16 @@ class BaseWorkflow(Generic[TWorkflowInput]):
t.to_proto(service_name) if (t := self._on_failure_task) else None
)
if isinstance(self.config.concurrency, list):
_concurrency_arr = [c.to_proto() for c in self.config.concurrency]
_concurrency = None
elif isinstance(self.config.concurrency, ConcurrencyExpression):
_concurrency_arr = []
_concurrency = self.config.concurrency.to_proto()
else:
_concurrency = None
_concurrency_arr = []
return CreateWorkflowVersionRequest(
name=name,
description=self.config.description,
@@ -144,11 +154,12 @@ class BaseWorkflow(Generic[TWorkflowInput]):
event_triggers=event_triggers,
cron_triggers=self.config.on_crons,
tasks=tasks,
concurrency=(c.to_proto() if (c := self.config.concurrency) else None),
## TODO: Fix this
cron_input=None,
on_failure_task=on_failure_task,
sticky=convert_python_enum_to_proto(self.config.sticky, StickyStrategyProto), # type: ignore[arg-type]
concurrency=_concurrency,
concurrency_arr=_concurrency_arr,
default_priority=self.config.default_priority,
)
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "hatchet-sdk"
version = "1.5.0"
version = "1.6.0"
description = ""
authors = ["Alexander Belanger <alexander@hatchet.run>"]
readme = "README.md"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@hatchet-dev/typescript-sdk",
"version": "1.2.0",
"version": "1.3.0",
"description": "Background task orchestration & visibility for developers",
"types": "dist/index.d.ts",
"files": [
@@ -10,6 +10,193 @@
* ---------------------------------------------------------------
*/
export enum V1LogLineLevel {
DEBUG = 'DEBUG',
INFO = 'INFO',
WARN = 'WARN',
ERROR = 'ERROR',
}
export enum V1TaskRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
}
export enum V1TaskStatus {
QUEUED = 'QUEUED',
RUNNING = 'RUNNING',
COMPLETED = 'COMPLETED',
CANCELLED = 'CANCELLED',
FAILED = 'FAILED',
}
export enum WebhookWorkerRequestMethod {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
}
export enum LogLineOrderByDirection {
Asc = 'asc',
Desc = 'desc',
}
export enum LogLineOrderByField {
CreatedAt = 'createdAt',
}
export enum LogLineLevel {
DEBUG = 'DEBUG',
INFO = 'INFO',
WARN = 'WARN',
ERROR = 'ERROR',
}
export enum PullRequestState {
Open = 'open',
Closed = 'closed',
}
export enum WorkerRuntimeSDKs {
GOLANG = 'GOLANG',
PYTHON = 'PYTHON',
TYPESCRIPT = 'TYPESCRIPT',
}
export enum StepRunEventSeverity {
INFO = 'INFO',
WARNING = 'WARNING',
CRITICAL = 'CRITICAL',
}
export enum StepRunEventReason {
REQUEUED_NO_WORKER = 'REQUEUED_NO_WORKER',
REQUEUED_RATE_LIMIT = 'REQUEUED_RATE_LIMIT',
SCHEDULING_TIMED_OUT = 'SCHEDULING_TIMED_OUT',
ASSIGNED = 'ASSIGNED',
STARTED = 'STARTED',
ACKNOWLEDGED = 'ACKNOWLEDGED',
FINISHED = 'FINISHED',
FAILED = 'FAILED',
RETRYING = 'RETRYING',
CANCELLED = 'CANCELLED',
TIMEOUT_REFRESHED = 'TIMEOUT_REFRESHED',
REASSIGNED = 'REASSIGNED',
TIMED_OUT = 'TIMED_OUT',
SLOT_RELEASED = 'SLOT_RELEASED',
RETRIED_BY_USER = 'RETRIED_BY_USER',
WORKFLOW_RUN_GROUP_KEY_SUCCEEDED = 'WORKFLOW_RUN_GROUP_KEY_SUCCEEDED',
WORKFLOW_RUN_GROUP_KEY_FAILED = 'WORKFLOW_RUN_GROUP_KEY_FAILED',
}
export enum StepRunStatus {
PENDING = 'PENDING',
PENDING_ASSIGNMENT = 'PENDING_ASSIGNMENT',
ASSIGNED = 'ASSIGNED',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
CANCELLING = 'CANCELLING',
BACKOFF = 'BACKOFF',
}
export enum JobRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
BACKOFF = 'BACKOFF',
}
export enum WorkflowKind {
FUNCTION = 'FUNCTION',
DURABLE = 'DURABLE',
DAG = 'DAG',
}
export enum WorkflowRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
QUEUED = 'QUEUED',
BACKOFF = 'BACKOFF',
}
export enum WorkflowRunOrderByDirection {
ASC = 'ASC',
DESC = 'DESC',
}
export enum WorkflowRunOrderByField {
CreatedAt = 'createdAt',
StartedAt = 'startedAt',
FinishedAt = 'finishedAt',
Duration = 'duration',
}
export enum CronWorkflowsOrderByField {
Name = 'name',
CreatedAt = 'createdAt',
}
export enum ScheduledRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
QUEUED = 'QUEUED',
SCHEDULED = 'SCHEDULED',
}
export enum ScheduledWorkflowsOrderByField {
TriggerAt = 'triggerAt',
CreatedAt = 'createdAt',
}
export enum RateLimitOrderByDirection {
Asc = 'asc',
Desc = 'desc',
}
export enum RateLimitOrderByField {
Key = 'key',
Value = 'value',
LimitValue = 'limitValue',
}
export enum EventOrderByDirection {
Asc = 'asc',
Desc = 'desc',
}
export enum EventOrderByField {
CreatedAt = 'createdAt',
}
export enum TenantResource {
WORKER = 'WORKER',
WORKER_SLOT = 'WORKER_SLOT',
EVENT = 'EVENT',
WORKFLOW_RUN = 'WORKFLOW_RUN',
TASK_RUN = 'TASK_RUN',
CRON = 'CRON',
SCHEDULE = 'SCHEDULE',
}
export enum TenantMemberRole {
OWNER = 'OWNER',
ADMIN = 'ADMIN',
MEMBER = 'MEMBER',
}
export interface APIMeta {
auth?: APIMetaAuth;
/**
@@ -134,13 +321,13 @@ export interface APIResourceMeta {
/**
* the time that this resource was created
* @format date-time
* @example "2022-12-13T20:06:48.888Z"
* @example "2022-12-13T15:06:48.888358-05:00"
*/
createdAt: string;
/**
* the time that this resource was last updated
* @format date-time
* @example "2022-12-13T20:06:48.888Z"
* @example "2022-12-13T15:06:48.888358-05:00"
*/
updatedAt: string;
}
@@ -235,22 +422,6 @@ export interface TenantMemberList {
rows?: TenantMember[];
}
export enum TenantMemberRole {
OWNER = 'OWNER',
ADMIN = 'ADMIN',
MEMBER = 'MEMBER',
}
export enum TenantResource {
WORKER = 'WORKER',
WORKER_SLOT = 'WORKER_SLOT',
EVENT = 'EVENT',
WORKFLOW_RUN = 'WORKFLOW_RUN',
TASK_RUN = 'TASK_RUN',
CRON = 'CRON',
SCHEDULE = 'SCHEDULE',
}
export interface TenantResourceLimit {
metadata: APIResourceMeta;
/** The resource associated with this limit. */
@@ -489,15 +660,6 @@ export interface EventWorkflowRunSummary {
cancelled?: number;
}
export enum EventOrderByField {
CreatedAt = 'createdAt',
}
export enum EventOrderByDirection {
Asc = 'asc',
Desc = 'desc',
}
export type EventSearch = string;
export interface EventKeyList {
@@ -530,7 +692,7 @@ export interface RateLimit {
/**
* The last time the rate limit was refilled.
* @format date-time
* @example "2022-12-13T20:06:48.888Z"
* @example "2022-12-13T15:06:48.888358-05:00"
*/
lastRefill: string;
}
@@ -540,17 +702,6 @@ export interface RateLimitList {
rows?: RateLimit[];
}
export enum RateLimitOrderByField {
Key = 'key',
Value = 'value',
LimitValue = 'limitValue',
}
export enum RateLimitOrderByDirection {
Asc = 'asc',
Desc = 'desc',
}
export interface ReplayEventRequest {
eventIds: string[];
}
@@ -807,21 +958,6 @@ export interface ScheduledWorkflowsList {
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;
@@ -847,23 +983,6 @@ export interface CronWorkflowsList {
pagination?: PaginationResponse;
}
export enum CronWorkflowsOrderByField {
Name = 'name',
CreatedAt = 'createdAt',
}
export enum WorkflowRunOrderByField {
CreatedAt = 'createdAt',
StartedAt = 'startedAt',
FinishedAt = 'finishedAt',
Duration = 'duration',
}
export enum WorkflowRunOrderByDirection {
ASC = 'ASC',
DESC = 'DESC',
}
export interface WorkflowRunsMetrics {
counts?: WorkflowRunsMetricsCounts;
}
@@ -877,51 +996,14 @@ export interface WorkflowRunsMetricsCounts {
CANCELLED?: number;
}
export enum WorkflowRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
QUEUED = 'QUEUED',
BACKOFF = 'BACKOFF',
}
export type WorkflowRunStatusList = WorkflowRunStatus[];
export enum WorkflowKind {
FUNCTION = 'FUNCTION',
DURABLE = 'DURABLE',
DAG = 'DAG',
}
export type WorkflowKindList = WorkflowKind[];
export interface WorkflowRunsCancelRequest {
workflowRunIds: string[];
}
export enum JobRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
BACKOFF = 'BACKOFF',
}
export enum StepRunStatus {
PENDING = 'PENDING',
PENDING_ASSIGNMENT = 'PENDING_ASSIGNMENT',
ASSIGNED = 'ASSIGNED',
RUNNING = 'RUNNING',
SUCCEEDED = 'SUCCEEDED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
CANCELLING = 'CANCELLING',
BACKOFF = 'BACKOFF',
}
export interface JobRun {
metadata: APIResourceMeta;
tenantId: string;
@@ -987,32 +1069,6 @@ export interface StepRun {
cancelledError?: string;
}
export enum StepRunEventReason {
REQUEUED_NO_WORKER = 'REQUEUED_NO_WORKER',
REQUEUED_RATE_LIMIT = 'REQUEUED_RATE_LIMIT',
SCHEDULING_TIMED_OUT = 'SCHEDULING_TIMED_OUT',
ASSIGNED = 'ASSIGNED',
STARTED = 'STARTED',
ACKNOWLEDGED = 'ACKNOWLEDGED',
FINISHED = 'FINISHED',
FAILED = 'FAILED',
RETRYING = 'RETRYING',
CANCELLED = 'CANCELLED',
TIMEOUT_REFRESHED = 'TIMEOUT_REFRESHED',
REASSIGNED = 'REASSIGNED',
TIMED_OUT = 'TIMED_OUT',
SLOT_RELEASED = 'SLOT_RELEASED',
RETRIED_BY_USER = 'RETRIED_BY_USER',
WORKFLOW_RUN_GROUP_KEY_SUCCEEDED = 'WORKFLOW_RUN_GROUP_KEY_SUCCEEDED',
WORKFLOW_RUN_GROUP_KEY_FAILED = 'WORKFLOW_RUN_GROUP_KEY_FAILED',
}
export enum StepRunEventSeverity {
INFO = 'INFO',
WARNING = 'WARNING',
CRITICAL = 'CRITICAL',
}
export interface StepRunEvent {
id: number;
/** @format date-time */
@@ -1071,12 +1127,6 @@ export interface WorkerRuntimeInfo {
runtimeExtra?: string;
}
export enum WorkerRuntimeSDKs {
GOLANG = 'GOLANG',
PYTHON = 'PYTHON',
TYPESCRIPT = 'TYPESCRIPT',
}
export interface WorkerList {
pagination?: PaginationResponse;
rows?: Worker[];
@@ -1131,13 +1181,13 @@ export interface Worker {
/**
* The time this worker last sent a heartbeat.
* @format date-time
* @example "2022-12-13T20:06:48.888Z"
* @example "2022-12-13T15:06:48.888358-05:00"
*/
lastHeartbeatAt?: string;
/**
* The time this worker last sent a heartbeat.
* @format date-time
* @example "2022-12-13T20:06:48.888Z"
* @example "2022-12-13T15:06:48.888358-05:00"
*/
lastListenerEstablished?: string;
/** The actions this worker can perform. */
@@ -1283,11 +1333,6 @@ export interface PullRequest {
pullRequestState: PullRequestState;
}
export enum PullRequestState {
Open = 'open',
Closed = 'closed',
}
export interface LogLine {
/**
* The creation date of the log line.
@@ -1300,27 +1345,11 @@ export interface LogLine {
metadata: object;
}
export enum LogLineLevel {
DEBUG = 'DEBUG',
INFO = 'INFO',
WARN = 'WARN',
ERROR = 'ERROR',
}
export interface LogLineList {
pagination?: PaginationResponse;
rows?: LogLine[];
}
export enum LogLineOrderByField {
CreatedAt = 'createdAt',
}
export enum LogLineOrderByDirection {
Asc = 'asc',
Desc = 'desc',
}
export type LogLineSearch = string;
export type LogLineLevelField = LogLineLevel[];
@@ -1385,12 +1414,6 @@ export interface WebhookWorker {
url: string;
}
export enum WebhookWorkerRequestMethod {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
}
export interface WebhookWorkerRequest {
/**
* The date and time the request was created.
@@ -1457,7 +1480,7 @@ export interface V1WorkflowRunDisplayNameList {
export interface V1TaskSummary {
metadata: APIResourceMeta;
/** The action ID of the task. */
actionId: string;
actionId?: string;
/** Additional metadata for the task run. */
additionalMetadata?: object;
/** The list of children tasks */
@@ -1580,14 +1603,6 @@ export interface V1TaskEventList {
}[];
}
export enum V1TaskStatus {
QUEUED = 'QUEUED',
RUNNING = 'RUNNING',
COMPLETED = 'COMPLETED',
CANCELLED = 'CANCELLED',
FAILED = 'FAILED',
}
export type V1TaskRunMetrics = {
status: V1TaskStatus;
count: number;
@@ -1702,19 +1717,13 @@ export interface V1WorkflowRunDetails {
tasks: V1TaskSummary[];
}
export enum V1TaskRunStatus {
PENDING = 'PENDING',
RUNNING = 'RUNNING',
COMPLETED = 'COMPLETED',
FAILED = 'FAILED',
CANCELLED = 'CANCELLED',
}
export interface V1TriggerWorkflowRunRequest {
/** The name of the workflow. */
workflowName: string;
input: object;
additionalMetadata?: object;
/** The priority of the workflow run. */
priority?: number;
}
export interface V1LogLine {
@@ -1729,13 +1738,6 @@ export interface V1LogLine {
metadata: object;
}
export enum V1LogLineLevel {
DEBUG = 'DEBUG',
INFO = 'INFO',
WARN = 'WARN',
ERROR = 'ERROR',
}
export interface V1LogLineList {
pagination?: PaginationResponse;
rows?: V1LogLine[];
@@ -68,7 +68,10 @@ export class HttpClient<SecurityDataType = unknown> {
format,
...axiosConfig
}: ApiConfig<SecurityDataType> = {}) {
this.instance = axios.create({ ...axiosConfig, baseURL: axiosConfig.baseURL || '' });
this.instance = axios.create({
...axiosConfig,
baseURL: axiosConfig.baseURL || '',
});
this.secure = secure;
this.format = format;
this.securityWorker = securityWorker;
+5 -1
View File
@@ -288,6 +288,9 @@ export class V0Worker {
...(workflow.on?.cron ? [workflow.on.cron] : []),
];
const concurrencyArr = Array.isArray(concurrency) ? concurrency : [];
const concurrencySolo = !Array.isArray(concurrency) ? concurrency : undefined;
const registeredWorkflow = this.client.admin.putWorkflowV1({
name: workflow.name,
description: workflow.description || '',
@@ -295,7 +298,7 @@ export class V0Worker {
eventTriggers,
cronTriggers,
sticky: workflow.sticky,
concurrency,
concurrencyArr,
onFailureTask,
defaultPriority: workflow.defaultPriority,
tasks: [...workflow._tasks, ...workflow._durableTasks].map<CreateTaskOpts>((task) => ({
@@ -328,6 +331,7 @@ export class V0Worker {
: [workflow.taskDefaults.concurrency]
: [],
})),
concurrency: concurrencySolo,
});
this.registeredWorkflowPromises.push(registeredWorkflow);
await registeredWorkflow;
+45 -2
View File
@@ -250,6 +250,7 @@ export interface TriggerWorkflowRunRequest {
workflowName: string;
input: Uint8Array;
additionalMetadata: Uint8Array;
priority?: number | undefined;
}
export interface TriggerWorkflowRunResponse {
@@ -270,7 +271,7 @@ export interface CreateWorkflowVersionRequest {
cronTriggers: string[];
/** (required) the workflow jobs */
tasks: CreateTaskOpts[];
/** (optional) the workflow concurrency options */
/** Deprecated: use concurrency_arr instead */
concurrency: Concurrency | undefined;
/** (optional) the input for the cron trigger */
cronInput?: string | undefined;
@@ -280,6 +281,8 @@ export interface CreateWorkflowVersionRequest {
sticky?: StickyStrategy | undefined;
/** (optional) the default priority for the workflow */
defaultPriority?: number | undefined;
/** (optional) the workflow concurrency options */
concurrencyArr: Concurrency[];
}
export interface Concurrency {
@@ -793,7 +796,12 @@ export const ReplayTasksResponse: MessageFns<ReplayTasksResponse> = {
};
function createBaseTriggerWorkflowRunRequest(): TriggerWorkflowRunRequest {
return { workflowName: '', input: new Uint8Array(0), additionalMetadata: new Uint8Array(0) };
return {
workflowName: '',
input: new Uint8Array(0),
additionalMetadata: new Uint8Array(0),
priority: undefined,
};
}
export const TriggerWorkflowRunRequest: MessageFns<TriggerWorkflowRunRequest> = {
@@ -810,6 +818,9 @@ export const TriggerWorkflowRunRequest: MessageFns<TriggerWorkflowRunRequest> =
if (message.additionalMetadata.length !== 0) {
writer.uint32(26).bytes(message.additionalMetadata);
}
if (message.priority !== undefined) {
writer.uint32(32).int32(message.priority);
}
return writer;
},
@@ -844,6 +855,14 @@ export const TriggerWorkflowRunRequest: MessageFns<TriggerWorkflowRunRequest> =
message.additionalMetadata = reader.bytes();
continue;
}
case 4: {
if (tag !== 32) {
break;
}
message.priority = reader.int32();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
@@ -860,6 +879,7 @@ export const TriggerWorkflowRunRequest: MessageFns<TriggerWorkflowRunRequest> =
additionalMetadata: isSet(object.additionalMetadata)
? bytesFromBase64(object.additionalMetadata)
: new Uint8Array(0),
priority: isSet(object.priority) ? globalThis.Number(object.priority) : undefined,
};
},
@@ -874,6 +894,9 @@ export const TriggerWorkflowRunRequest: MessageFns<TriggerWorkflowRunRequest> =
if (message.additionalMetadata.length !== 0) {
obj.additionalMetadata = base64FromBytes(message.additionalMetadata);
}
if (message.priority !== undefined) {
obj.priority = Math.round(message.priority);
}
return obj;
},
@@ -885,6 +908,7 @@ export const TriggerWorkflowRunRequest: MessageFns<TriggerWorkflowRunRequest> =
message.workflowName = object.workflowName ?? '';
message.input = object.input ?? new Uint8Array(0);
message.additionalMetadata = object.additionalMetadata ?? new Uint8Array(0);
message.priority = object.priority ?? undefined;
return message;
},
};
@@ -963,6 +987,7 @@ function createBaseCreateWorkflowVersionRequest(): CreateWorkflowVersionRequest
onFailureTask: undefined,
sticky: undefined,
defaultPriority: undefined,
concurrencyArr: [],
};
}
@@ -1004,6 +1029,9 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
if (message.defaultPriority !== undefined) {
writer.uint32(88).int32(message.defaultPriority);
}
for (const v of message.concurrencyArr) {
Concurrency.encode(v!, writer.uint32(98).fork()).join();
}
return writer;
},
@@ -1102,6 +1130,14 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
message.defaultPriority = reader.int32();
continue;
}
case 12: {
if (tag !== 98) {
break;
}
message.concurrencyArr.push(Concurrency.decode(reader, reader.uint32()));
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
@@ -1134,6 +1170,9 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
defaultPriority: isSet(object.defaultPriority)
? globalThis.Number(object.defaultPriority)
: undefined,
concurrencyArr: globalThis.Array.isArray(object?.concurrencyArr)
? object.concurrencyArr.map((e: any) => Concurrency.fromJSON(e))
: [],
};
},
@@ -1172,6 +1211,9 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
if (message.defaultPriority !== undefined) {
obj.defaultPriority = Math.round(message.defaultPriority);
}
if (message.concurrencyArr?.length) {
obj.concurrencyArr = message.concurrencyArr.map((e) => Concurrency.toJSON(e));
}
return obj;
},
@@ -1197,6 +1239,7 @@ export const CreateWorkflowVersionRequest: MessageFns<CreateWorkflowVersionReque
: undefined;
message.sticky = object.sticky ?? undefined;
message.defaultPriority = object.defaultPriority ?? undefined;
message.concurrencyArr = object.concurrencyArr?.map((e) => Concurrency.fromPartial(e)) || [];
return message;
},
};
+6 -3
View File
@@ -9,11 +9,11 @@ import { IHatchetClient } from './client/client.interface';
import {
CreateWorkflowTaskOpts,
CreateOnFailureTaskOpts,
TaskConcurrency,
TaskFn,
CreateWorkflowDurableTaskOpts,
CreateBaseTaskOpts,
CreateOnSuccessTaskOpts,
Concurrency,
DurableTaskFn,
} from './task';
import { Duration } from './client/duration';
@@ -104,7 +104,10 @@ export type CreateBaseWorkflowOpts = {
*/
onEvents?: string[];
concurrency?: TaskConcurrency;
/**
* (optional) concurrency config for the workflow.
*/
concurrency?: Concurrency | Concurrency[];
/**
* (optional) the priority for the workflow.
@@ -186,7 +189,7 @@ export type TaskDefaults = {
/**
* (optional) the concurrency options for the task.
*/
concurrency?: TaskConcurrency | TaskConcurrency[];
concurrency?: Concurrency | Concurrency[];
};
/**
@@ -0,0 +1,29 @@
import { multiConcurrency } from './workflow';
async function main() {
const res = await multiConcurrency.run([
{
Message: 'Hello World',
GroupKey: 'A',
},
{
Message: 'Goodbye Moon',
GroupKey: 'A',
},
{
Message: 'Hello World B',
GroupKey: 'B',
},
]);
// eslint-disable-next-line no-console
console.log(res[0]['to-lower'].TransformedMessage);
// eslint-disable-next-line no-console
console.log(res[1]['to-lower'].TransformedMessage);
// eslint-disable-next-line no-console
console.log(res[2]['to-lower'].TransformedMessage);
}
if (require.main === module) {
main().then(() => process.exit(0));
}
@@ -0,0 +1,14 @@
import { hatchet } from '../hatchet-client';
import { multiConcurrency } from './workflow';
async function main() {
const worker = await hatchet.worker('simple-concurrency-worker', {
workflows: [multiConcurrency],
});
await worker.start();
}
if (require.main === module) {
main();
}
@@ -0,0 +1,46 @@
import { ConcurrencyLimitStrategy } from '@hatchet/workflow';
import { hatchet } from '../hatchet-client';
type SimpleInput = {
Message: string;
GroupKey: string;
};
type SimpleOutput = {
'to-lower': {
TransformedMessage: string;
};
};
const sleep = (ms: number) =>
new Promise((resolve) => {
setTimeout(resolve, ms);
});
// ❓ Concurrency Strategy With Key
export const multiConcurrency = hatchet.workflow<SimpleInput, SimpleOutput>({
name: 'simple-concurrency',
concurrency: [
{
maxRuns: 1,
limitStrategy: ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
expression: 'input.GroupKey',
},
{
maxRuns: 1,
limitStrategy: ConcurrencyLimitStrategy.GROUP_ROUND_ROBIN,
expression: 'input.UserId',
},
],
});
// !!
multiConcurrency.task({
name: 'to-lower',
fn: async (input) => {
await sleep(Math.floor(Math.random() * (1000 - 200 + 1)) + 200);
return {
TransformedMessage: input.Message.toLowerCase(),
};
},
});
+7 -2
View File
@@ -7,7 +7,7 @@ import { InputType, OutputType, UnknownInputType } from './types';
/**
* Options for configuring the concurrency for a task.
*/
export type TaskConcurrency = {
export type Concurrency = {
/**
* required the CEL expression to use for concurrency
*
@@ -33,6 +33,11 @@ export type TaskConcurrency = {
limitStrategy?: ConcurrencyLimitStrategy;
};
/**
* @deprecated use Concurrency instead
*/
export type TaskConcurrency = Concurrency;
export class NonRetryableError extends Error {
constructor(message?: string) {
super(message);
@@ -130,7 +135,7 @@ export type CreateBaseTaskOpts<
/**
* (optional) the concurrency options for the task
*/
concurrency?: TaskConcurrency | TaskConcurrency[];
concurrency?: Concurrency | Concurrency[];
};
export type CreateWorkflowTaskOpts<