From e237199cdee2b1bb1f603defc4184d23105d0765 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Sat, 4 Feb 2023 11:42:30 -0800 Subject: [PATCH 1/4] rebase! --- api/persistence/v1/executions.pb.go | 534 ++++++++++-------- common/dynamicconfig/constants.go | 6 + .../api/persistence/v1/executions.proto | 2 + service/history/configs/config.go | 52 +- service/history/workflow/history_builder.go | 10 +- .../history/workflow/history_builder_test.go | 10 +- service/history/workflow/mutable_state.go | 9 +- .../history/workflow/mutable_state_impl.go | 10 +- .../workflow/mutable_state_impl_test.go | 4 + .../history/workflow/mutable_state_mock.go | 8 +- .../workflow/mutable_state_rebuilder.go | 2 + .../workflow/mutable_state_rebuilder_test.go | 1 + .../workflow/workflow_task_state_machine.go | 64 ++- tests/transient_task_test.go | 162 ++++++ 14 files changed, 610 insertions(+), 264 deletions(-) diff --git a/api/persistence/v1/executions.pb.go b/api/persistence/v1/executions.pb.go index 344fec9ceac..fc11426e1c2 100644 --- a/api/persistence/v1/executions.pb.go +++ b/api/persistence/v1/executions.pb.go @@ -205,6 +205,8 @@ type WorkflowExecutionInfo struct { WorkflowTaskOriginalScheduledTime *time.Time `protobuf:"bytes,30,opt,name=workflow_task_original_scheduled_time,json=workflowTaskOriginalScheduledTime,proto3,stdtime" json:"workflow_task_original_scheduled_time,omitempty"` WorkflowTaskRequestId string `protobuf:"bytes,31,opt,name=workflow_task_request_id,json=workflowTaskRequestId,proto3" json:"workflow_task_request_id,omitempty"` WorkflowTaskType v1.WorkflowTaskType `protobuf:"varint,68,opt,name=workflow_task_type,json=workflowTaskType,proto3,enum=temporal.server.api.enums.v1.WorkflowTaskType" json:"workflow_task_type,omitempty"` + WorkflowTaskSuggestContinueAsNew bool `protobuf:"varint,69,opt,name=workflow_task_suggest_continue_as_new,json=workflowTaskSuggestContinueAsNew,proto3" json:"workflow_task_suggest_continue_as_new,omitempty"` + WorkflowTaskHistorySizeBytes int64 `protobuf:"varint,70,opt,name=workflow_task_history_size_bytes,json=workflowTaskHistorySizeBytes,proto3" json:"workflow_task_history_size_bytes,omitempty"` CancelRequested bool `protobuf:"varint,29,opt,name=cancel_requested,json=cancelRequested,proto3" json:"cancel_requested,omitempty"` CancelRequestId string `protobuf:"bytes,32,opt,name=cancel_request_id,json=cancelRequestId,proto3" json:"cancel_request_id,omitempty"` StickyTaskQueue string `protobuf:"bytes,33,opt,name=sticky_task_queue,json=stickyTaskQueue,proto3" json:"sticky_task_queue,omitempty"` @@ -466,6 +468,20 @@ func (m *WorkflowExecutionInfo) GetWorkflowTaskType() v1.WorkflowTaskType { return v1.WORKFLOW_TASK_TYPE_UNSPECIFIED } +func (m *WorkflowExecutionInfo) GetWorkflowTaskSuggestContinueAsNew() bool { + if m != nil { + return m.WorkflowTaskSuggestContinueAsNew + } + return false +} + +func (m *WorkflowExecutionInfo) GetWorkflowTaskHistorySizeBytes() int64 { + if m != nil { + return m.WorkflowTaskHistorySizeBytes + } + return 0 +} + func (m *WorkflowExecutionInfo) GetCancelRequested() bool { if m != nil { return m.CancelRequested @@ -2224,225 +2240,229 @@ func init() { } var fileDescriptor_67a714d0e7ba9f37 = []byte{ - // 3479 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0x4d, 0x73, 0x1b, 0xc7, - 0x95, 0x82, 0x38, 0x24, 0x06, 0x0f, 0x20, 0x38, 0x1c, 0x7e, 0x0d, 0x69, 0x0a, 0xa4, 0x60, 0xc9, - 0xa6, 0x6c, 0x19, 0x34, 0x29, 0x79, 0xe5, 0x8f, 0x5d, 0x6b, 0x49, 0x4a, 0xb2, 0x81, 0x95, 0x65, - 0x79, 0x48, 0x5b, 0x2e, 0xaf, 0x5d, 0xa8, 0xe1, 0x4c, 0x93, 0x9c, 0x25, 0x30, 0x03, 0xcd, 0x0c, - 0x48, 0xc1, 0xb5, 0x07, 0x1f, 0xb6, 0xf6, 0xec, 0xdc, 0x72, 0xce, 0x29, 0xc7, 0x5c, 0x72, 0xcf, - 0x21, 0x95, 0xca, 0x29, 0xe5, 0x5b, 0x7c, 0x4b, 0x2c, 0x5f, 0x72, 0x49, 0xd9, 0x95, 0x5f, 0x90, - 0xea, 0xd7, 0xdd, 0xf3, 0x85, 0x21, 0x39, 0x54, 0xac, 0x83, 0x6f, 0x98, 0x7e, 0x9f, 0xfd, 0xfa, - 0xf5, 0xfb, 0x6a, 0xc0, 0x8d, 0x80, 0x74, 0x7b, 0xae, 0x67, 0x74, 0x56, 0x7d, 0xe2, 0x1d, 0x11, - 0x6f, 0xd5, 0xe8, 0xd9, 0xab, 0x3d, 0xe2, 0xf9, 0xb6, 0x1f, 0x10, 0xc7, 0x24, 0xab, 0x47, 0x6b, - 0xab, 0xe4, 0x09, 0x31, 0xfb, 0x81, 0xed, 0x3a, 0x7e, 0xa3, 0xe7, 0xb9, 0x81, 0xab, 0xd6, 0x05, - 0x51, 0x83, 0x11, 0x35, 0x8c, 0x9e, 0xdd, 0x88, 0x11, 0x35, 0x8e, 0xd6, 0x16, 0x6a, 0xfb, 0xae, - 0xbb, 0xdf, 0x21, 0xab, 0x48, 0xb1, 0xdb, 0xdf, 0x5b, 0xb5, 0xfa, 0x9e, 0x41, 0x99, 0x30, 0x1e, - 0x0b, 0x4b, 0x69, 0x78, 0x60, 0x77, 0x89, 0x1f, 0x18, 0xdd, 0x1e, 0x47, 0xb8, 0x6c, 0x91, 0x1e, - 0x71, 0x2c, 0xe2, 0x98, 0x36, 0xf1, 0x57, 0xf7, 0xdd, 0x7d, 0x17, 0xd7, 0xf1, 0x17, 0x47, 0xb9, - 0x12, 0x2a, 0x4f, 0xb5, 0x36, 0xdd, 0x6e, 0xd7, 0x75, 0xa8, 0xc2, 0x5d, 0xe2, 0xfb, 0xc6, 0x3e, - 0xc9, 0xc4, 0x22, 0x4e, 0xbf, 0xeb, 0x53, 0xa4, 0x63, 0xd7, 0x3b, 0xdc, 0xeb, 0xb8, 0xc7, 0x1c, - 0xeb, 0x6a, 0x02, 0x6b, 0xcf, 0xb0, 0x3b, 0x7d, 0x8f, 0x0c, 0x33, 0x7b, 0x29, 0x81, 0x26, 0x78, - 0x0c, 0xe3, 0xbd, 0x92, 0x65, 0x57, 0xb3, 0xe3, 0x9a, 0x87, 0xc3, 0xb8, 0xd7, 0xb2, 0x70, 0x43, - 0x3d, 0xd9, 0xb6, 0x38, 0xea, 0xab, 0xa7, 0xa2, 0xa6, 0xb6, 0xf4, 0xf2, 0xa9, 0xc8, 0x81, 0xe1, - 0x1f, 0x72, 0xc4, 0x37, 0x72, 0x71, 0x6d, 0x53, 0x8a, 0x76, 0x30, 0xe8, 0x09, 0xbd, 0xaf, 0x67, - 0x91, 0x1d, 0xd8, 0x7e, 0xe0, 0x7a, 0x83, 0xe1, 0x5d, 0xae, 0xe6, 0xf0, 0xb4, 0xc7, 0x7d, 0xd2, - 0x27, 0xdc, 0xcb, 0xea, 0x7f, 0x28, 0x42, 0x69, 0xfb, 0xc0, 0xf0, 0xac, 0xa6, 0xb3, 0xe7, 0xaa, - 0xf3, 0x20, 0xfb, 0xf4, 0xa3, 0x6d, 0x5b, 0x5a, 0x61, 0xb9, 0xb0, 0x32, 0xaa, 0x17, 0xf1, 0xbb, - 0x69, 0x51, 0x90, 0x67, 0x38, 0xfb, 0x84, 0x82, 0x2e, 0x2e, 0x17, 0x56, 0x46, 0xf4, 0x22, 0x7e, - 0x37, 0x2d, 0x75, 0x1a, 0x46, 0xdd, 0x63, 0x87, 0x78, 0xda, 0xc8, 0x72, 0x61, 0xa5, 0xa4, 0xb3, - 0x0f, 0xf5, 0x3a, 0xa8, 0x7e, 0xe0, 0x76, 0x88, 0xd3, 0xf6, 0x6d, 0xc7, 0x24, 0x6d, 0x8f, 0x38, - 0xe4, 0x58, 0x1b, 0x43, 0xae, 0x0a, 0x83, 0x6c, 0x53, 0x80, 0x4e, 0xd7, 0xd5, 0x0d, 0x28, 0xf7, - 0x7b, 0x96, 0x11, 0x90, 0x36, 0x75, 0x51, 0xad, 0xb8, 0x5c, 0x58, 0x29, 0xaf, 0x2f, 0x34, 0x98, - 0xff, 0x36, 0x84, 0xff, 0x36, 0x76, 0x84, 0xff, 0x6e, 0x4a, 0x5f, 0xff, 0x65, 0xa9, 0xa0, 0x03, - 0x23, 0xa2, 0xcb, 0xea, 0x1d, 0xa8, 0x39, 0x46, 0x97, 0xf8, 0x3d, 0xc3, 0x24, 0x6d, 0xc7, 0x0d, - 0xec, 0x3d, 0xdb, 0xc4, 0xcb, 0xd0, 0x3e, 0xa2, 0x06, 0x70, 0x1d, 0xad, 0x84, 0x7a, 0x2f, 0x86, - 0x58, 0x0f, 0x62, 0x48, 0x9f, 0x30, 0x1c, 0xf5, 0xff, 0x0a, 0x30, 0xef, 0x91, 0x5e, 0x47, 0xd0, - 0x5a, 0x9d, 0xc7, 0x6d, 0xc3, 0x3c, 0x6c, 0x77, 0xc8, 0x11, 0xe9, 0x68, 0xe3, 0xcb, 0x23, 0x2b, - 0xe5, 0xf5, 0x66, 0xe3, 0xec, 0xbb, 0xd9, 0x08, 0xad, 0xda, 0xd0, 0x23, 0x76, 0x77, 0x3a, 0x8f, - 0x37, 0xcc, 0xc3, 0xfb, 0x94, 0xd7, 0x5d, 0x27, 0xf0, 0x06, 0xfa, 0xac, 0x97, 0x09, 0x54, 0x0f, - 0x41, 0xc1, 0x73, 0x8a, 0x64, 0xfb, 0x9a, 0x82, 0xc2, 0x37, 0xce, 0x27, 0xfc, 0x23, 0xca, 0x45, - 0xb0, 0xf5, 0x99, 0xd0, 0xea, 0xe3, 0xc4, 0xa2, 0x6a, 0x40, 0x85, 0x09, 0xf3, 0x03, 0x23, 0x20, - 0xbe, 0x36, 0x89, 0x82, 0xde, 0x7d, 0x06, 0x41, 0xdb, 0xc8, 0x80, 0x49, 0x29, 0x3f, 0x8e, 0x56, - 0x16, 0x9a, 0xf0, 0xc2, 0x29, 0x66, 0x50, 0x15, 0x18, 0x39, 0x24, 0x03, 0xf4, 0xb9, 0x92, 0x4e, - 0x7f, 0x52, 0xa7, 0x3a, 0x32, 0x3a, 0x7d, 0xc2, 0x9d, 0x8d, 0x7d, 0xbc, 0x7d, 0xf1, 0xcd, 0xc2, - 0x42, 0x00, 0x53, 0x19, 0x9b, 0x8a, 0xb3, 0x18, 0x65, 0x2c, 0xde, 0x8b, 0xb3, 0x28, 0xaf, 0xaf, - 0xe5, 0xd9, 0x4f, 0x82, 0x73, 0x5c, 0xaa, 0x03, 0x4a, 0x7a, 0x87, 0x19, 0x22, 0xef, 0x24, 0x45, - 0x36, 0x72, 0x8b, 0x44, 0xb6, 0x31, 0x79, 0x2d, 0x49, 0x96, 0x94, 0xd1, 0x96, 0x24, 0x8f, 0x2a, - 0x63, 0x2d, 0x49, 0x96, 0x95, 0x52, 0x4b, 0x92, 0x41, 0x29, 0xb7, 0x24, 0xb9, 0xac, 0x54, 0x5a, - 0x92, 0x5c, 0x51, 0xc6, 0x5b, 0x92, 0x5c, 0x55, 0x26, 0x5a, 0x92, 0x3c, 0xa1, 0x28, 0xf5, 0x5f, - 0x2d, 0xc3, 0xcc, 0x23, 0x1e, 0x44, 0xee, 0x8a, 0x5c, 0x82, 0x97, 0xfa, 0x32, 0x54, 0xa2, 0x7b, - 0xc1, 0x2f, 0x76, 0x49, 0x2f, 0x87, 0x6b, 0x4d, 0x4b, 0x5d, 0x82, 0x72, 0x18, 0x80, 0xf8, 0xfd, - 0x2e, 0xe9, 0x20, 0x96, 0x9a, 0x96, 0xda, 0x80, 0xa9, 0x9e, 0xe1, 0x11, 0x27, 0x68, 0x27, 0x58, - 0xb1, 0x0b, 0x3f, 0xc9, 0x40, 0x0f, 0x62, 0x0c, 0xaf, 0x83, 0xca, 0xf1, 0xe3, 0x7c, 0x25, 0x44, - 0x57, 0x18, 0xe4, 0x51, 0xc4, 0xbd, 0x0e, 0xe3, 0x1c, 0xdb, 0xeb, 0x3b, 0x14, 0x71, 0x94, 0xa9, - 0xc8, 0x16, 0xf5, 0xbe, 0x93, 0xd0, 0xc0, 0x76, 0xec, 0xc0, 0x36, 0x02, 0x82, 0x51, 0x6a, 0x0c, - 0xbd, 0x83, 0x6b, 0xd0, 0x14, 0x90, 0xa6, 0xa5, 0xbe, 0x05, 0xf3, 0xa6, 0xdb, 0xed, 0x75, 0x08, - 0xde, 0x62, 0x72, 0x44, 0x29, 0x77, 0x8d, 0xc0, 0x3c, 0xa0, 0x54, 0x45, 0xa4, 0x9a, 0x8d, 0x10, - 0xee, 0x52, 0xf8, 0x26, 0x05, 0x37, 0x2d, 0xf5, 0x12, 0x00, 0x46, 0x61, 0xf4, 0x5f, 0x0c, 0x1a, - 0x25, 0xbd, 0x44, 0x57, 0xf0, 0xa4, 0xe8, 0xde, 0xa2, 0x68, 0x3d, 0xe8, 0x11, 0x34, 0x89, 0x06, - 0x6c, 0x6f, 0x02, 0xb2, 0x33, 0xe8, 0x11, 0x6a, 0x10, 0xf5, 0x0b, 0x58, 0x08, 0xb1, 0xc3, 0x1c, - 0x8f, 0x41, 0xce, 0xed, 0x07, 0x5a, 0x19, 0xdd, 0x64, 0x7e, 0x28, 0xce, 0xdd, 0xe1, 0x79, 0x7c, - 0x53, 0xfa, 0x25, 0x0d, 0x73, 0xda, 0x71, 0xfa, 0x64, 0x77, 0x18, 0x03, 0xf5, 0x23, 0x98, 0x0e, - 0xd9, 0x53, 0xe3, 0x09, 0xc6, 0x95, 0x7c, 0x8c, 0xc3, 0x9d, 0xe8, 0xfd, 0x90, 0xe5, 0x2e, 0x5c, - 0xb2, 0xc8, 0x9e, 0xd1, 0xef, 0xc4, 0x0e, 0x8f, 0x65, 0x25, 0xce, 0x7b, 0x3c, 0x1f, 0xef, 0x05, - 0xce, 0x45, 0x1c, 0xf4, 0x8e, 0xe1, 0x1f, 0x0a, 0x19, 0xaf, 0x82, 0xda, 0x31, 0xfc, 0x80, 0x9f, - 0x0b, 0x72, 0xb7, 0x2d, 0x6d, 0x12, 0x8f, 0x65, 0x82, 0x42, 0xf0, 0x40, 0x28, 0x45, 0xd3, 0x52, - 0x5f, 0x83, 0x29, 0x44, 0xde, 0xb3, 0xbd, 0x90, 0xc4, 0xb6, 0x34, 0x15, 0xb1, 0x15, 0x0a, 0xba, - 0x47, 0x21, 0x48, 0xd2, 0xb4, 0xd4, 0xff, 0x82, 0x17, 0x11, 0x3d, 0xa9, 0xbc, 0x1f, 0x18, 0x1e, - 0xf5, 0x99, 0x90, 0x7c, 0x0a, 0xc9, 0x6b, 0x14, 0x35, 0xae, 0xe1, 0x36, 0xc3, 0x13, 0xcc, 0x6e, - 0x03, 0x20, 0x25, 0x4b, 0x4b, 0xd3, 0x39, 0xd3, 0x52, 0x09, 0x69, 0x30, 0x2b, 0xb5, 0x00, 0x35, - 0x6c, 0xc7, 0xb3, 0xdb, 0x4c, 0x4e, 0x36, 0x55, 0x4a, 0xf9, 0x71, 0x94, 0xe1, 0xd6, 0x61, 0x26, - 0xb9, 0x29, 0x91, 0xd8, 0x66, 0x71, 0x2f, 0x53, 0xc7, 0xb1, 0x7d, 0x88, 0x7c, 0x76, 0x0f, 0x96, - 0x53, 0x86, 0x30, 0x0f, 0x88, 0xd5, 0xef, 0xc4, 0x4d, 0x31, 0xc7, 0xf2, 0x62, 0x9c, 0x7c, 0x5b, - 0x60, 0x09, 0x43, 0x6c, 0x42, 0xed, 0x0c, 0x83, 0x6a, 0xc8, 0x65, 0xe1, 0xf8, 0x64, 0x63, 0x6e, - 0xa7, 0xf5, 0x17, 0x1e, 0x35, 0x9f, 0xcf, 0xa3, 0x12, 0x1b, 0x14, 0xae, 0x34, 0x64, 0x14, 0x23, - 0xa0, 0x41, 0x37, 0xd0, 0x16, 0x30, 0x2c, 0x27, 0x68, 0x36, 0x18, 0x28, 0x71, 0x29, 0x13, 0x9b, - 0xc1, 0xe3, 0x79, 0x21, 0xe7, 0xf1, 0xcc, 0x65, 0x6c, 0x15, 0xcf, 0xc9, 0x80, 0xc5, 0x93, 0x6c, - 0x8e, 0x02, 0x16, 0x73, 0x0a, 0x98, 0xcf, 0x3c, 0x11, 0x14, 0xe1, 0xc1, 0xd5, 0xa4, 0x08, 0xd7, - 0xb3, 0xf7, 0x6d, 0xc7, 0xe8, 0xa4, 0x65, 0xd5, 0x72, 0xca, 0xba, 0x1c, 0x97, 0xf5, 0x21, 0x67, - 0x96, 0x94, 0x79, 0x0b, 0xb4, 0xa4, 0x4c, 0x8f, 0x3c, 0xee, 0x13, 0x1f, 0x0f, 0x7f, 0x09, 0xc3, - 0xdf, 0x4c, 0x9c, 0x89, 0xce, 0xa0, 0x4d, 0x4b, 0xfd, 0x3c, 0x1e, 0x31, 0x45, 0x7d, 0xab, 0xdd, - 0x59, 0x2e, 0xac, 0x54, 0x4f, 0x48, 0x91, 0x58, 0x17, 0xd3, 0xe4, 0x98, 0x08, 0x1e, 0x83, 0x1e, - 0x89, 0x45, 0x58, 0xbe, 0xa2, 0x5e, 0x03, 0xc5, 0x34, 0x1c, 0x93, 0x74, 0x84, 0x3e, 0xc4, 0xd2, - 0x2e, 0x2d, 0x17, 0x56, 0x64, 0x7d, 0x82, 0xad, 0xeb, 0x62, 0x59, 0x7d, 0x05, 0x26, 0x93, 0xa8, - 0x54, 0xf5, 0x65, 0x54, 0x3d, 0x89, 0xdb, 0x44, 0x5c, 0x3f, 0xb0, 0xcd, 0xc3, 0x41, 0x3b, 0x96, - 0x0c, 0x2e, 0x33, 0x5c, 0x06, 0xd8, 0x09, 0x53, 0xc2, 0x3e, 0x2c, 0x73, 0x5c, 0x61, 0xfd, 0x76, - 0xe0, 0xb6, 0xa3, 0xc0, 0x41, 0x7d, 0xbc, 0x9e, 0xcf, 0xc7, 0x17, 0x19, 0x23, 0x61, 0xf9, 0x1d, - 0x77, 0x5b, 0x84, 0x12, 0xea, 0xec, 0x1a, 0x14, 0x85, 0x7b, 0xbf, 0xc8, 0xea, 0x73, 0xfe, 0xa9, - 0x7e, 0x0c, 0xb3, 0x1e, 0x09, 0xbc, 0x01, 0x4f, 0x8f, 0x9d, 0xb6, 0xed, 0x04, 0xc4, 0x3b, 0x32, - 0x3a, 0xda, 0x95, 0x7c, 0x82, 0xa7, 0x91, 0x9c, 0xa5, 0xd0, 0x4e, 0x93, 0x13, 0x47, 0x6c, 0xbb, - 0xc6, 0x13, 0xbb, 0xdb, 0xef, 0x46, 0x6c, 0xaf, 0x9e, 0x87, 0xed, 0x07, 0x8c, 0x3a, 0x64, 0x7b, - 0x33, 0xcd, 0x96, 0x6f, 0xc3, 0xd7, 0x5e, 0xc2, 0x6d, 0x25, 0xa8, 0xf8, 0xad, 0xf5, 0xd5, 0xb7, - 0x69, 0x69, 0x4e, 0xa9, 0x76, 0x0d, 0xf3, 0xd0, 0xdd, 0xdb, 0x6b, 0x9b, 0x2e, 0xd9, 0xdb, 0xb3, - 0x4d, 0x9b, 0x38, 0x81, 0xf6, 0xf2, 0x72, 0x61, 0xa5, 0xa0, 0xcf, 0x21, 0xc2, 0x26, 0x83, 0x6f, - 0x45, 0x60, 0xb5, 0x0b, 0xf5, 0x8c, 0x3c, 0x4c, 0x9e, 0xf4, 0x6c, 0xa6, 0x2e, 0xbb, 0x2d, 0x2b, - 0x39, 0x6f, 0xcb, 0xd2, 0x50, 0x42, 0xbe, 0x1b, 0x72, 0xe2, 0xcd, 0xc8, 0x12, 0x53, 0xd5, 0x71, - 0x9d, 0x36, 0xfe, 0x32, 0x76, 0x3b, 0xa4, 0x4d, 0x3c, 0xcf, 0xf5, 0xd0, 0xfd, 0x7d, 0xed, 0xda, - 0xf2, 0xc8, 0x4a, 0x49, 0x7f, 0x01, 0x81, 0x0f, 0x5c, 0x47, 0x17, 0x48, 0x77, 0x29, 0x0e, 0xf5, - 0x6c, 0x5f, 0x5d, 0x01, 0xe5, 0xc0, 0xf0, 0x19, 0x7d, 0xbb, 0xe7, 0x76, 0x6c, 0x73, 0xa0, 0xbd, - 0x82, 0xae, 0x5d, 0x3d, 0x30, 0x7c, 0xa4, 0x78, 0x88, 0xab, 0xea, 0x8b, 0x30, 0x6e, 0x7a, 0xae, - 0x13, 0xfa, 0x9f, 0xf6, 0x2a, 0x7a, 0x6a, 0x85, 0x2e, 0x0a, 0x5f, 0xa2, 0x95, 0xa0, 0x6f, 0xef, - 0xd3, 0x20, 0x61, 0xba, 0x7d, 0x27, 0xd0, 0x1a, 0x18, 0xb1, 0xcb, 0x6c, 0x6d, 0x8b, 0x2e, 0xa9, - 0x1f, 0xc1, 0xa4, 0xd1, 0x0f, 0xdc, 0xb6, 0x47, 0x7c, 0x12, 0xb4, 0x7b, 0xae, 0xed, 0x04, 0xbe, - 0x76, 0x03, 0xad, 0x72, 0x35, 0xba, 0xa9, 0xf4, 0x8a, 0x86, 0x7d, 0xf0, 0xd1, 0x5a, 0x43, 0xa7, - 0xd8, 0x0f, 0x11, 0x59, 0x9f, 0xa0, 0xf4, 0xb1, 0x05, 0xf5, 0x7f, 0x61, 0xd2, 0x27, 0x86, 0x67, - 0x1e, 0xd0, 0x43, 0xf6, 0xec, 0xdd, 0x3e, 0x6d, 0x31, 0x6e, 0x62, 0x8b, 0xf1, 0x61, 0x9e, 0xfa, - 0x38, 0xb3, 0xaa, 0x6d, 0x6c, 0x23, 0xcb, 0x8d, 0x90, 0x23, 0xeb, 0x39, 0x14, 0x3f, 0xb5, 0xac, - 0x3e, 0x02, 0xa9, 0x4b, 0xba, 0xae, 0xf6, 0x06, 0x0a, 0xdc, 0x7a, 0x76, 0x81, 0x1f, 0x90, 0xae, - 0xcb, 0x84, 0x20, 0x43, 0xf5, 0x0b, 0x98, 0xe4, 0xe9, 0xb7, 0xcd, 0xda, 0x71, 0x9b, 0xf8, 0xda, - 0xbf, 0xa1, 0xa5, 0x5e, 0xcf, 0x94, 0xc2, 0x9b, 0x76, 0x2a, 0x81, 0x27, 0xe7, 0xf7, 0x05, 0x9d, - 0xae, 0x1c, 0xa5, 0x56, 0xd4, 0x1b, 0x30, 0xcb, 0xeb, 0x9d, 0xd0, 0x59, 0x79, 0x71, 0x7c, 0x0b, - 0x4f, 0x76, 0x0a, 0xa1, 0xa1, 0x8a, 0xac, 0x48, 0xfe, 0x6f, 0x98, 0x88, 0xd0, 0x69, 0x33, 0xe7, - 0x6b, 0x6f, 0xa2, 0x46, 0xeb, 0x79, 0xf6, 0x1d, 0x32, 0xa3, 0xcd, 0x88, 0xaf, 0x57, 0x49, 0xe2, - 0x3b, 0x91, 0xd5, 0xa8, 0x2a, 0xe9, 0xbb, 0xf3, 0xd6, 0x79, 0xb3, 0x9a, 0xde, 0x4f, 0xdf, 0x9a, - 0x9b, 0x30, 0x37, 0x54, 0xe9, 0x05, 0x4f, 0x70, 0xd7, 0x6f, 0xb3, 0x12, 0x27, 0x59, 0xed, 0xed, - 0x3c, 0xa1, 0xbb, 0xbe, 0x09, 0xb3, 0xd8, 0xb8, 0xb6, 0x03, 0xcf, 0x70, 0x7c, 0x1b, 0x35, 0x62, - 0x0e, 0xfe, 0x0e, 0x12, 0x4d, 0x23, 0x74, 0x27, 0x04, 0x32, 0x4f, 0x7f, 0x0f, 0xaa, 0xc9, 0x7a, - 0x5c, 0xfb, 0xf7, 0x9c, 0x1b, 0x18, 0x27, 0xf1, 0x2a, 0x5c, 0x5d, 0x85, 0x69, 0x87, 0x1c, 0x0f, - 0x9f, 0xd3, 0x7f, 0xb0, 0xe6, 0xc8, 0x21, 0xc7, 0xa9, 0x53, 0xba, 0x0f, 0x15, 0xde, 0xca, 0xe0, - 0xac, 0x4a, 0x7b, 0x17, 0xe5, 0x5e, 0xcb, 0x3c, 0x22, 0xc4, 0x60, 0x2e, 0x63, 0x06, 0xae, 0xb7, - 0x45, 0x3f, 0x45, 0x63, 0x84, 0x1f, 0xea, 0x9b, 0xa0, 0x0d, 0x35, 0x46, 0xa2, 0x2e, 0xbc, 0xcd, - 0xfa, 0x9c, 0x54, 0x77, 0x24, 0x4a, 0xc3, 0x1b, 0x30, 0x6b, 0x76, 0x5c, 0x9f, 0xdb, 0x6d, 0x8f, - 0x78, 0x61, 0x21, 0xfe, 0x9f, 0xcc, 0xd8, 0x08, 0xdd, 0xe1, 0x40, 0x5e, 0x8c, 0xdf, 0x02, 0x8d, - 0x11, 0x1d, 0xd9, 0xbe, 0xbd, 0x6b, 0x77, 0xec, 0x60, 0x10, 0x92, 0x6d, 0x20, 0xd9, 0x0c, 0xc2, - 0x3f, 0x09, 0xc1, 0x9c, 0xf0, 0x36, 0x00, 0x97, 0x46, 0x6d, 0xbd, 0x99, 0xb7, 0x92, 0x66, 0x3a, - 0x50, 0x3b, 0xdf, 0x85, 0xa5, 0x6c, 0xc9, 0xbc, 0x8d, 0x23, 0x96, 0xb6, 0x85, 0xb1, 0x71, 0x31, - 0x43, 0x81, 0x2d, 0x81, 0xb3, 0x60, 0xc1, 0x4c, 0x66, 0xec, 0xc8, 0x98, 0x41, 0xbc, 0x91, 0xec, - 0xe6, 0x97, 0x92, 0x01, 0x90, 0xcf, 0x0c, 0x8f, 0xd6, 0x1a, 0x0f, 0x8d, 0x41, 0xc7, 0x35, 0xac, - 0xf8, 0xb8, 0xe0, 0x53, 0x28, 0x85, 0x01, 0xe3, 0x27, 0xe5, 0x1c, 0x0e, 0x03, 0xc2, 0xd6, 0xbf, - 0x25, 0xc9, 0x8a, 0x32, 0xd9, 0x92, 0xe4, 0xeb, 0xca, 0x6b, 0x2d, 0x49, 0x7e, 0x4d, 0x69, 0xb4, - 0x24, 0x79, 0x55, 0x79, 0xbd, 0x25, 0xc9, 0xaf, 0x2b, 0x6b, 0x2d, 0x49, 0x5e, 0x53, 0xd6, 0x5b, - 0x92, 0xbc, 0xae, 0xdc, 0xa8, 0xdf, 0x80, 0x6a, 0xf2, 0x92, 0xd3, 0x94, 0xc0, 0xe3, 0x52, 0xdb, - 0xb7, 0xbf, 0x24, 0xa8, 0xe3, 0x88, 0x5e, 0xe6, 0x6b, 0xdb, 0xf6, 0x97, 0xa4, 0xfe, 0x43, 0x01, - 0x66, 0x87, 0x42, 0x22, 0xce, 0x2b, 0xb0, 0x9e, 0xf2, 0x08, 0xbd, 0x7a, 0xb1, 0x7a, 0xaa, 0xc0, - 0xeb, 0x29, 0x04, 0x44, 0xf5, 0xd4, 0x0c, 0x8c, 0xf1, 0x8b, 0xc1, 0xc6, 0x0b, 0xa3, 0x1e, 0x5e, - 0x86, 0x16, 0x8c, 0xe2, 0xf5, 0xc4, 0x59, 0x42, 0x75, 0xfd, 0x66, 0xbe, 0x72, 0x30, 0xa9, 0x87, - 0xce, 0x58, 0xa8, 0xf7, 0x60, 0x8c, 0xfe, 0xe8, 0xfb, 0x38, 0x69, 0x48, 0xd4, 0x96, 0x67, 0x73, - 0xe9, 0xfb, 0x3a, 0xa7, 0xae, 0xff, 0x63, 0x0c, 0x94, 0x84, 0xdb, 0xff, 0x54, 0x63, 0x94, 0xc8, - 0x06, 0x23, 0x71, 0x1b, 0x6c, 0x41, 0x29, 0x2a, 0x8b, 0x99, 0xea, 0x2f, 0x9d, 0x6e, 0x87, 0xb0, - 0x1c, 0x96, 0x03, 0x51, 0x06, 0x37, 0x60, 0x2a, 0x30, 0xbc, 0x7d, 0x92, 0x1a, 0xd1, 0xb0, 0x51, - 0xca, 0x24, 0x03, 0xa5, 0x46, 0x34, 0x1c, 0x3f, 0xae, 0xf3, 0x18, 0x1b, 0x63, 0x30, 0x48, 0x72, - 0x44, 0xc3, 0xb1, 0xf9, 0x06, 0x8a, 0x6c, 0xfb, 0x6c, 0x91, 0xc5, 0xb5, 0xe4, 0xdc, 0x44, 0x4e, - 0xcf, 0x4d, 0xde, 0x81, 0x05, 0xce, 0xc2, 0x3c, 0xb0, 0x3b, 0x56, 0x24, 0xd6, 0x75, 0x3a, 0x03, - 0x1c, 0xb3, 0xc8, 0xfa, 0x1c, 0xc3, 0xd8, 0xa2, 0x08, 0x42, 0xfa, 0x87, 0x4e, 0x67, 0x80, 0xd3, - 0xe4, 0xe1, 0xc6, 0x15, 0xd8, 0x08, 0xc0, 0x4f, 0x37, 0xab, 0x1a, 0x14, 0x45, 0x08, 0x2c, 0xb3, - 0x59, 0x35, 0xff, 0x54, 0xe7, 0xa0, 0x28, 0xa2, 0x55, 0x05, 0x21, 0x63, 0x01, 0x0b, 0x4f, 0x4d, - 0x98, 0x88, 0xc7, 0x15, 0x1a, 0xa3, 0xc6, 0xf3, 0xb6, 0xe9, 0x11, 0x21, 0x06, 0xaa, 0xeb, 0xa0, - 0x5a, 0x84, 0x06, 0x9b, 0xb6, 0xb1, 0x17, 0x10, 0xaf, 0x8d, 0xe1, 0x48, 0x9b, 0xc0, 0x0d, 0x2a, - 0x0c, 0xb2, 0x41, 0x01, 0x5b, 0x74, 0x5d, 0xfd, 0x45, 0x01, 0x58, 0xc0, 0x8a, 0x8f, 0x87, 0xa8, - 0x8a, 0x16, 0x09, 0x0c, 0x1b, 0xc7, 0xbe, 0x54, 0x8d, 0x07, 0x79, 0x32, 0x78, 0xda, 0x69, 0x1b, - 0x28, 0x22, 0x1a, 0x1a, 0x19, 0xfe, 0xe1, 0x1d, 0xc6, 0xf5, 0xfd, 0x0b, 0xfa, 0xbc, 0x79, 0x12, - 0x70, 0xe1, 0x73, 0x98, 0x3f, 0x91, 0x52, 0xbd, 0x0d, 0x8b, 0xa6, 0xe1, 0xb4, 0xfd, 0x43, 0xbb, - 0x17, 0x0f, 0xc5, 0x34, 0xa4, 0xda, 0xb4, 0x31, 0x28, 0xe0, 0x46, 0xe7, 0x4d, 0xc3, 0xd9, 0x3e, - 0xb4, 0x7b, 0x51, 0x18, 0xde, 0xe0, 0x08, 0x9b, 0x55, 0xa8, 0xc4, 0x37, 0xc8, 0x62, 0x59, 0xfd, - 0xb7, 0x12, 0x4c, 0xc5, 0x46, 0xc4, 0x3f, 0x9b, 0x7b, 0x17, 0xf3, 0xb5, 0xd1, 0xa4, 0xaf, 0x5d, - 0x81, 0x6a, 0x6a, 0x64, 0xc5, 0xa6, 0x95, 0x95, 0xbd, 0xf8, 0xb8, 0xaa, 0x0e, 0xe3, 0x0e, 0x79, - 0x12, 0x43, 0x62, 0xc3, 0xc9, 0x32, 0x5d, 0x14, 0x38, 0xd9, 0xde, 0x2f, 0x9f, 0xe0, 0xfd, 0x97, - 0xa1, 0xb2, 0xeb, 0x19, 0x8e, 0x79, 0xd0, 0x0e, 0xdc, 0x43, 0xc2, 0xae, 0x40, 0x45, 0x2f, 0xb3, - 0xb5, 0x1d, 0xba, 0x24, 0x6a, 0x16, 0x6a, 0x94, 0x04, 0xea, 0x38, 0xa2, 0xd2, 0x9a, 0x45, 0xef, - 0x3b, 0x9b, 0x31, 0x82, 0xd8, 0xbd, 0x99, 0x38, 0xeb, 0xde, 0x28, 0xcf, 0x78, 0x6f, 0x16, 0x01, - 0x84, 0x52, 0x7c, 0x18, 0x58, 0xd2, 0x65, 0xa6, 0x4a, 0xd3, 0x6a, 0x49, 0x72, 0x49, 0x81, 0x70, - 0x08, 0x1e, 0x8e, 0xbf, 0xeb, 0x7f, 0x1f, 0x01, 0x35, 0x55, 0x6c, 0xfc, 0xbc, 0xdd, 0x26, 0x66, - 0xea, 0xb1, 0xb3, 0x4c, 0x5d, 0x7c, 0x46, 0x53, 0x27, 0x8b, 0x31, 0xf9, 0xfc, 0xc5, 0x58, 0x72, - 0x2e, 0x5a, 0x3a, 0xff, 0x5c, 0xf4, 0xb4, 0x3a, 0x12, 0x4e, 0xa9, 0x23, 0xeb, 0x3f, 0x48, 0x30, - 0x4e, 0x39, 0xfc, 0x7c, 0x32, 0xf3, 0x5d, 0xa8, 0xf0, 0x21, 0x10, 0xe3, 0x33, 0x8a, 0x7c, 0xea, - 0x27, 0x14, 0x27, 0x7c, 0xd4, 0x83, 0x3c, 0xca, 0x41, 0xf4, 0xa1, 0x92, 0xd8, 0xa0, 0x53, 0x0c, - 0x40, 0x90, 0xdf, 0x18, 0xf2, 0x5b, 0xcb, 0x57, 0x39, 0xf1, 0xd1, 0x08, 0xb2, 0x0f, 0x67, 0xa3, - 0xb1, 0xc5, 0xb8, 0x63, 0x16, 0x93, 0x8e, 0x79, 0x0d, 0xc2, 0x58, 0x13, 0x0e, 0x59, 0x65, 0x1c, - 0xd7, 0x4c, 0x88, 0x75, 0x31, 0x60, 0x9d, 0x07, 0x39, 0x0c, 0x53, 0xec, 0xd5, 0xb5, 0x48, 0x78, - 0x74, 0x8a, 0xb9, 0x37, 0x9c, 0xe5, 0xde, 0xe5, 0x67, 0x74, 0xef, 0x74, 0x04, 0xac, 0x0c, 0x47, - 0xc0, 0x6b, 0xa0, 0x18, 0x1d, 0x8f, 0x18, 0x96, 0xc8, 0x5c, 0xc4, 0xc2, 0xe8, 0x27, 0xeb, 0x13, - 0x7c, 0x7d, 0x83, 0x2f, 0xd7, 0x7f, 0x73, 0x11, 0x14, 0x91, 0xbc, 0x42, 0xa7, 0x8b, 0x6d, 0xa3, - 0x90, 0xd8, 0x46, 0xda, 0x1b, 0x2f, 0x9e, 0xe9, 0x8d, 0x23, 0xa7, 0x78, 0xa3, 0x74, 0xa2, 0x37, - 0x8e, 0xfe, 0xeb, 0x81, 0x67, 0x2c, 0x79, 0xbe, 0x3f, 0x5d, 0x7c, 0xa9, 0xff, 0x7f, 0x15, 0x2a, - 0x1b, 0x66, 0x60, 0x1f, 0xd9, 0xc1, 0x00, 0xcd, 0x15, 0x93, 0x5a, 0x48, 0x4a, 0xbd, 0x05, 0x5a, - 0x3a, 0xb7, 0x85, 0xef, 0x74, 0xec, 0xed, 0x77, 0x26, 0x99, 0xe1, 0xc4, 0x33, 0xdd, 0x7b, 0x50, - 0x4d, 0xcd, 0xba, 0xa5, 0xbc, 0x0d, 0xbc, 0x9f, 0x98, 0x6b, 0xaf, 0x80, 0x32, 0xf4, 0x98, 0xc1, - 0x62, 0x72, 0xd5, 0x4f, 0x3e, 0x60, 0x6c, 0x41, 0x25, 0xf1, 0x52, 0x90, 0xd7, 0x3c, 0x65, 0x3f, - 0xf6, 0x3a, 0xb0, 0x04, 0x65, 0x83, 0x9b, 0x46, 0x64, 0xf1, 0x92, 0x0e, 0x62, 0x89, 0xd5, 0xd1, - 0xb1, 0x76, 0x8a, 0xbf, 0x3f, 0x7a, 0x61, 0x23, 0xf5, 0x19, 0xcc, 0x9f, 0x3c, 0x65, 0x86, 0x7c, - 0x53, 0xd9, 0x59, 0x3f, 0x7b, 0xbe, 0x9c, 0xe2, 0x1d, 0xe5, 0x88, 0x73, 0x3c, 0x56, 0xc6, 0x78, - 0x6f, 0x89, 0x7c, 0x41, 0x79, 0xef, 0xe0, 0x98, 0x86, 0xea, 0x9a, 0x66, 0x9c, 0xf3, 0xb1, 0x72, - 0x8a, 0x65, 0x8f, 0x24, 0xd7, 0xfb, 0x30, 0x79, 0x40, 0x0c, 0x2f, 0xd8, 0x25, 0x46, 0x70, 0xde, - 0x17, 0x4a, 0x25, 0xa4, 0x14, 0xdc, 0xb2, 0xde, 0x12, 0xaa, 0xe7, 0x78, 0x4b, 0x60, 0xb5, 0x51, - 0xd6, 0x5b, 0x02, 0x55, 0xcd, 0x0b, 0x1f, 0x9b, 0x68, 0x8f, 0xaa, 0xb0, 0xd0, 0x19, 0x88, 0x5c, - 0xc6, 0x9a, 0xd0, 0xf8, 0x88, 0x7f, 0x32, 0x39, 0xe2, 0x4f, 0xf6, 0x57, 0x6a, 0xba, 0xbf, 0xba, - 0x16, 0xb9, 0xb1, 0x6d, 0x11, 0x27, 0xb0, 0x83, 0x01, 0x3e, 0x72, 0xe2, 0x7b, 0x05, 0xae, 0x37, - 0xf9, 0x72, 0xe6, 0x5c, 0x79, 0x3a, 0x73, 0xae, 0x7c, 0xf2, 0xb3, 0xc2, 0xcc, 0xf3, 0x79, 0x56, - 0x98, 0x7d, 0x3e, 0xcf, 0x0a, 0x73, 0xa7, 0x3c, 0x2b, 0xec, 0xc0, 0x0c, 0xa3, 0x4a, 0x4f, 0x34, - 0xb5, 0x9c, 0xd7, 0x7b, 0x0a, 0xc9, 0x53, 0xb3, 0xcc, 0x53, 0x1f, 0x2b, 0xe6, 0x4f, 0x7f, 0xac, - 0xc8, 0xf1, 0x7a, 0xb0, 0x70, 0xf6, 0xeb, 0xc1, 0x03, 0x50, 0x19, 0x17, 0x36, 0x53, 0x65, 0xff, - 0xb6, 0xe3, 0xaf, 0x9b, 0xcb, 0xc9, 0xea, 0x83, 0x03, 0x69, 0xca, 0xb8, 0xc7, 0x7e, 0xea, 0x0a, - 0xd2, 0xde, 0x37, 0xfc, 0x80, 0xaf, 0xd0, 0x06, 0x3e, 0xc6, 0x8f, 0xa6, 0x2b, 0xe2, 0x45, 0xae, - 0xb6, 0x88, 0xae, 0x36, 0x17, 0x52, 0x3d, 0x42, 0x78, 0xe8, 0x72, 0xd9, 0x2d, 0x4c, 0xed, 0x84, - 0x16, 0xe6, 0x13, 0x98, 0x45, 0x21, 0xd1, 0xd5, 0x16, 0xdd, 0xf0, 0x52, 0x96, 0xfa, 0x43, 0x03, - 0x33, 0x5f, 0x9f, 0xa6, 0xf4, 0xef, 0x0b, 0x72, 0xd1, 0xbb, 0x7e, 0x01, 0x0b, 0x29, 0xbe, 0xf1, - 0x77, 0xf9, 0xe5, 0xbc, 0x0f, 0xbf, 0x09, 0xde, 0xd1, 0x03, 0x7d, 0x4b, 0x92, 0x47, 0x14, 0xa9, - 0x25, 0xc9, 0x63, 0x4a, 0xb1, 0x25, 0xc9, 0x97, 0x94, 0x5a, 0xfd, 0x4f, 0x05, 0x28, 0x61, 0xb5, - 0x7a, 0x46, 0x16, 0xcc, 0xca, 0x41, 0x17, 0x33, 0x73, 0xd0, 0x06, 0x94, 0xd1, 0x4f, 0x79, 0x86, - 0x1e, 0xc9, 0xfb, 0x4f, 0x39, 0x46, 0x24, 0x32, 0x50, 0x3c, 0x10, 0x49, 0x28, 0x07, 0x63, 0x0b, - 0x8f, 0x41, 0xf3, 0x20, 0xb3, 0x78, 0x15, 0x0e, 0x90, 0x8a, 0xf8, 0xdd, 0xb4, 0xea, 0x7f, 0x96, - 0x40, 0xc5, 0xf1, 0x4c, 0xf2, 0x4f, 0x46, 0xa7, 0xe6, 0xf7, 0x68, 0x30, 0x9d, 0x9d, 0xdf, 0x43, - 0x78, 0x22, 0xbf, 0x67, 0x99, 0x64, 0x24, 0xd3, 0x24, 0x0d, 0x98, 0x12, 0x98, 0xf1, 0xba, 0x8a, - 0x8f, 0xbe, 0x38, 0x28, 0x36, 0xcc, 0xba, 0x02, 0x82, 0x83, 0x68, 0x36, 0xd9, 0xd8, 0x4b, 0x24, - 0x77, 0x36, 0xce, 0xca, 0x1c, 0x6e, 0xca, 0xd9, 0xc3, 0xcd, 0x45, 0x28, 0x85, 0x05, 0x9e, 0xc8, - 0xd8, 0xe1, 0xc2, 0x39, 0xff, 0x31, 0xf4, 0x69, 0xf8, 0x4f, 0x27, 0x96, 0x25, 0x79, 0x7c, 0x2e, - 0x63, 0xbd, 0xb7, 0x72, 0x42, 0xd7, 0xf0, 0x50, 0xbc, 0x08, 0xf8, 0x84, 0x45, 0x6e, 0xf1, 0x9f, - 0xa8, 0xd8, 0x12, 0xd5, 0x23, 0x7d, 0x14, 0xe1, 0x1c, 0x4c, 0x49, 0x1e, 0x02, 0x0e, 0xec, 0x47, - 0xd9, 0xfb, 0xc4, 0xf8, 0x79, 0xdf, 0x27, 0x18, 0xdd, 0x50, 0x25, 0x5c, 0x1d, 0xaa, 0x84, 0xc3, - 0x7f, 0xb9, 0x15, 0x15, 0xb9, 0xfe, 0xbb, 0x02, 0x4c, 0x72, 0x8b, 0x6e, 0x61, 0xfe, 0x7c, 0x5e, - 0x8e, 0x95, 0x99, 0xb9, 0x47, 0xb2, 0xff, 0x05, 0x90, 0x6d, 0x32, 0x29, 0xdb, 0x64, 0xf5, 0xdf, - 0x17, 0x00, 0xb6, 0xf1, 0x35, 0xf5, 0x79, 0xe9, 0x9e, 0xac, 0x0d, 0x47, 0xd2, 0xb5, 0x61, 0xb6, - 0xba, 0xc5, 0x6c, 0x75, 0x53, 0xff, 0x31, 0x64, 0x41, 0x4b, 0x56, 0x4a, 0xf5, 0xaf, 0x0a, 0x20, - 0x6f, 0x1d, 0x10, 0xf3, 0xd0, 0xef, 0x77, 0xd3, 0x9b, 0x18, 0x8d, 0x36, 0x71, 0x07, 0xc6, 0xf6, - 0x3a, 0xc6, 0x91, 0xeb, 0xa1, 0xca, 0xd5, 0xf5, 0xeb, 0xa7, 0xf7, 0x22, 0x82, 0xe3, 0x3d, 0xa4, - 0xd1, 0x39, 0x6d, 0xf4, 0x47, 0xcf, 0x11, 0x6c, 0xd2, 0xd8, 0xc7, 0xe6, 0xff, 0x7c, 0xf3, 0x5d, - 0xed, 0xc2, 0xb7, 0xdf, 0xd5, 0x2e, 0xfc, 0xf8, 0x5d, 0xad, 0xf0, 0xd5, 0xd3, 0x5a, 0xe1, 0xd7, - 0x4f, 0x6b, 0x85, 0x3f, 0x3e, 0xad, 0x15, 0xbe, 0x79, 0x5a, 0x2b, 0xfc, 0xf5, 0x69, 0xad, 0xf0, - 0xb7, 0xa7, 0xb5, 0x0b, 0x3f, 0x3e, 0xad, 0x15, 0xbe, 0xfe, 0xbe, 0x76, 0xe1, 0x9b, 0xef, 0x6b, - 0x17, 0xbe, 0xfd, 0xbe, 0x76, 0xe1, 0xb3, 0x9b, 0xfb, 0x6e, 0xa4, 0x83, 0xed, 0x9e, 0xfc, 0x27, - 0xe8, 0x77, 0x62, 0x9f, 0xbb, 0x63, 0x18, 0x34, 0x6f, 0xfc, 0x33, 0x00, 0x00, 0xff, 0xff, 0x26, - 0x9b, 0xf5, 0x0b, 0xa7, 0x2f, 0x00, 0x00, + // 3537 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0xcd, 0x73, 0xdb, 0xc6, + 0x77, 0xa6, 0x05, 0x89, 0xe0, 0x23, 0x45, 0x41, 0xd0, 0x17, 0xa4, 0xc8, 0x94, 0xcc, 0xd8, 0x89, + 0x9c, 0x38, 0x54, 0x24, 0x3b, 0x75, 0x3e, 0xda, 0xb8, 0x92, 0x2c, 0xc7, 0x64, 0x1d, 0xdb, 0x81, + 0x94, 0x38, 0x93, 0x26, 0xc3, 0x81, 0x80, 0x95, 0x84, 0x8a, 0x04, 0x68, 0x00, 0x94, 0xcc, 0x4c, + 0x0f, 0x39, 0x74, 0x7a, 0x4e, 0x6f, 0xfd, 0x13, 0x7a, 0xec, 0xa5, 0xa7, 0x5e, 0x7a, 0xe8, 0x74, + 0x7a, 0xea, 0xe4, 0xd6, 0xdc, 0xda, 0x38, 0x97, 0x5e, 0x3a, 0xc9, 0xfc, 0xfe, 0x82, 0xdf, 0xec, + 0xdb, 0x5d, 0x7c, 0x11, 0x92, 0x20, 0xff, 0xe2, 0x43, 0x6e, 0xc4, 0xbe, 0xcf, 0x7d, 0xfb, 0xf6, + 0x7d, 0x2d, 0xe1, 0x56, 0x40, 0xba, 0x3d, 0xd7, 0x33, 0x3a, 0xab, 0x3e, 0xf1, 0x8e, 0x89, 0xb7, + 0x6a, 0xf4, 0xec, 0xd5, 0x1e, 0xf1, 0x7c, 0xdb, 0x0f, 0x88, 0x63, 0x92, 0xd5, 0xe3, 0xb5, 0x55, + 0xf2, 0x9c, 0x98, 0xfd, 0xc0, 0x76, 0x1d, 0xbf, 0xd1, 0xf3, 0xdc, 0xc0, 0x55, 0xeb, 0x82, 0xa8, + 0xc1, 0x88, 0x1a, 0x46, 0xcf, 0x6e, 0xc4, 0x88, 0x1a, 0xc7, 0x6b, 0x0b, 0xb5, 0x03, 0xd7, 0x3d, + 0xe8, 0x90, 0x55, 0xa4, 0xd8, 0xeb, 0xef, 0xaf, 0x5a, 0x7d, 0xcf, 0xa0, 0x4c, 0x18, 0x8f, 0x85, + 0xa5, 0x34, 0x3c, 0xb0, 0xbb, 0xc4, 0x0f, 0x8c, 0x6e, 0x8f, 0x23, 0x5c, 0xb5, 0x48, 0x8f, 0x38, + 0x16, 0x71, 0x4c, 0x9b, 0xf8, 0xab, 0x07, 0xee, 0x81, 0x8b, 0xeb, 0xf8, 0x8b, 0xa3, 0x5c, 0x0b, + 0x95, 0xa7, 0x5a, 0x9b, 0x6e, 0xb7, 0xeb, 0x3a, 0x54, 0xe1, 0x2e, 0xf1, 0x7d, 0xe3, 0x80, 0x64, + 0x62, 0x11, 0xa7, 0xdf, 0xf5, 0x29, 0xd2, 0x89, 0xeb, 0x1d, 0xed, 0x77, 0xdc, 0x13, 0x8e, 0x75, + 0x3d, 0x81, 0xb5, 0x6f, 0xd8, 0x9d, 0xbe, 0x47, 0x86, 0x99, 0xbd, 0x91, 0x40, 0x13, 0x3c, 0x86, + 0xf1, 0xde, 0xca, 0xb2, 0xab, 0xd9, 0x71, 0xcd, 0xa3, 0x61, 0xdc, 0x1b, 0x59, 0xb8, 0xa1, 0x9e, + 0x6c, 0x5b, 0x1c, 0xf5, 0xed, 0x33, 0x51, 0x53, 0x5b, 0x7a, 0xf3, 0x4c, 0xe4, 0xc0, 0xf0, 0x8f, + 0x38, 0xe2, 0x7b, 0xb9, 0xb8, 0xb6, 0x29, 0x45, 0x3b, 0x18, 0xf4, 0x84, 0xde, 0x37, 0xb3, 0xc8, + 0x0e, 0x6d, 0x3f, 0x70, 0xbd, 0xc1, 0xf0, 0x2e, 0x57, 0x73, 0x78, 0xda, 0xb3, 0x3e, 0xe9, 0x13, + 0xee, 0x65, 0xf5, 0xff, 0x28, 0x42, 0x69, 0xe7, 0xd0, 0xf0, 0xac, 0xa6, 0xb3, 0xef, 0xaa, 0xf3, + 0x20, 0xfb, 0xf4, 0xa3, 0x6d, 0x5b, 0x5a, 0x61, 0xb9, 0xb0, 0x32, 0xaa, 0x17, 0xf1, 0xbb, 0x69, + 0x51, 0x90, 0x67, 0x38, 0x07, 0x84, 0x82, 0x2e, 0x2f, 0x17, 0x56, 0x46, 0xf4, 0x22, 0x7e, 0x37, + 0x2d, 0x75, 0x1a, 0x46, 0xdd, 0x13, 0x87, 0x78, 0xda, 0xc8, 0x72, 0x61, 0xa5, 0xa4, 0xb3, 0x0f, + 0xf5, 0x26, 0xa8, 0x7e, 0xe0, 0x76, 0x88, 0xd3, 0xf6, 0x6d, 0xc7, 0x24, 0x6d, 0x8f, 0x38, 0xe4, + 0x44, 0x1b, 0x43, 0xae, 0x0a, 0x83, 0xec, 0x50, 0x80, 0x4e, 0xd7, 0xd5, 0x0d, 0x28, 0xf7, 0x7b, + 0x96, 0x11, 0x90, 0x36, 0x75, 0x51, 0xad, 0xb8, 0x5c, 0x58, 0x29, 0xaf, 0x2f, 0x34, 0x98, 0xff, + 0x36, 0x84, 0xff, 0x36, 0x76, 0x85, 0xff, 0x6e, 0x4a, 0xdf, 0xff, 0xcf, 0x52, 0x41, 0x07, 0x46, + 0x44, 0x97, 0xd5, 0x7b, 0x50, 0x73, 0x8c, 0x2e, 0xf1, 0x7b, 0x86, 0x49, 0xda, 0x8e, 0x1b, 0xd8, + 0xfb, 0xb6, 0x89, 0x97, 0xa1, 0x7d, 0x4c, 0x0d, 0xe0, 0x3a, 0x5a, 0x09, 0xf5, 0x5e, 0x0c, 0xb1, + 0x1e, 0xc5, 0x90, 0xbe, 0x60, 0x38, 0xea, 0xdf, 0x15, 0x60, 0xde, 0x23, 0xbd, 0x8e, 0xa0, 0xb5, + 0x3a, 0xcf, 0xda, 0x86, 0x79, 0xd4, 0xee, 0x90, 0x63, 0xd2, 0xd1, 0xc6, 0x97, 0x47, 0x56, 0xca, + 0xeb, 0xcd, 0xc6, 0xf9, 0x77, 0xb3, 0x11, 0x5a, 0xb5, 0xa1, 0x47, 0xec, 0xee, 0x75, 0x9e, 0x6d, + 0x98, 0x47, 0x0f, 0x29, 0xaf, 0x6d, 0x27, 0xf0, 0x06, 0xfa, 0xac, 0x97, 0x09, 0x54, 0x8f, 0x40, + 0xc1, 0x73, 0x8a, 0x64, 0xfb, 0x9a, 0x82, 0xc2, 0x37, 0x2e, 0x26, 0xfc, 0x33, 0xca, 0x45, 0xb0, + 0xf5, 0x99, 0xd0, 0xea, 0xb3, 0xc4, 0xa2, 0x6a, 0x40, 0x85, 0x09, 0xf3, 0x03, 0x23, 0x20, 0xbe, + 0x36, 0x89, 0x82, 0x3e, 0x7e, 0x09, 0x41, 0x3b, 0xc8, 0x80, 0x49, 0x29, 0x3f, 0x8b, 0x56, 0x16, + 0x9a, 0xf0, 0xda, 0x19, 0x66, 0x50, 0x15, 0x18, 0x39, 0x22, 0x03, 0xf4, 0xb9, 0x92, 0x4e, 0x7f, + 0x52, 0xa7, 0x3a, 0x36, 0x3a, 0x7d, 0xc2, 0x9d, 0x8d, 0x7d, 0x7c, 0x78, 0xf9, 0xfd, 0xc2, 0x42, + 0x00, 0x53, 0x19, 0x9b, 0x8a, 0xb3, 0x18, 0x65, 0x2c, 0x3e, 0x89, 0xb3, 0x28, 0xaf, 0xaf, 0xe5, + 0xd9, 0x4f, 0x82, 0x73, 0x5c, 0xaa, 0x03, 0x4a, 0x7a, 0x87, 0x19, 0x22, 0xef, 0x25, 0x45, 0x36, + 0x72, 0x8b, 0x44, 0xb6, 0x31, 0x79, 0x2d, 0x49, 0x96, 0x94, 0xd1, 0x96, 0x24, 0x8f, 0x2a, 0x63, + 0x2d, 0x49, 0x96, 0x95, 0x52, 0x4b, 0x92, 0x41, 0x29, 0xb7, 0x24, 0xb9, 0xac, 0x54, 0x5a, 0x92, + 0x5c, 0x51, 0xc6, 0x5b, 0x92, 0x5c, 0x55, 0x26, 0x5a, 0x92, 0x3c, 0xa1, 0x28, 0xf5, 0x7f, 0xbd, + 0x0a, 0x33, 0x4f, 0x79, 0x10, 0xd9, 0x16, 0xb9, 0x04, 0x2f, 0xf5, 0x55, 0xa8, 0x44, 0xf7, 0x82, + 0x5f, 0xec, 0x92, 0x5e, 0x0e, 0xd7, 0x9a, 0x96, 0xba, 0x04, 0xe5, 0x30, 0x00, 0xf1, 0xfb, 0x5d, + 0xd2, 0x41, 0x2c, 0x35, 0x2d, 0xb5, 0x01, 0x53, 0x3d, 0xc3, 0x23, 0x4e, 0xd0, 0x4e, 0xb0, 0x62, + 0x17, 0x7e, 0x92, 0x81, 0x1e, 0xc5, 0x18, 0xde, 0x04, 0x95, 0xe3, 0xc7, 0xf9, 0x4a, 0x88, 0xae, + 0x30, 0xc8, 0xd3, 0x88, 0x7b, 0x1d, 0xc6, 0x39, 0xb6, 0xd7, 0x77, 0x28, 0xe2, 0x28, 0x53, 0x91, + 0x2d, 0xea, 0x7d, 0x27, 0xa1, 0x81, 0xed, 0xd8, 0x81, 0x6d, 0x04, 0x04, 0xa3, 0xd4, 0x18, 0x7a, + 0x07, 0xd7, 0xa0, 0x29, 0x20, 0x4d, 0x4b, 0xfd, 0x00, 0xe6, 0x4d, 0xb7, 0xdb, 0xeb, 0x10, 0xbc, + 0xc5, 0xe4, 0x98, 0x52, 0xee, 0x19, 0x81, 0x79, 0x48, 0xa9, 0x8a, 0x48, 0x35, 0x1b, 0x21, 0x6c, + 0x53, 0xf8, 0x26, 0x05, 0x37, 0x2d, 0xf5, 0x0a, 0x00, 0x46, 0x61, 0xf4, 0x5f, 0x0c, 0x1a, 0x25, + 0xbd, 0x44, 0x57, 0xf0, 0xa4, 0xe8, 0xde, 0xa2, 0x68, 0x3d, 0xe8, 0x11, 0x34, 0x89, 0x06, 0x6c, + 0x6f, 0x02, 0xb2, 0x3b, 0xe8, 0x11, 0x6a, 0x10, 0xf5, 0x1b, 0x58, 0x08, 0xb1, 0xc3, 0x1c, 0x8f, + 0x41, 0xce, 0xed, 0x07, 0x5a, 0x19, 0xdd, 0x64, 0x7e, 0x28, 0xce, 0xdd, 0xe3, 0x79, 0x7c, 0x53, + 0xfa, 0x47, 0x1a, 0xe6, 0xb4, 0x93, 0xf4, 0xc9, 0xee, 0x32, 0x06, 0xea, 0x67, 0x30, 0x1d, 0xb2, + 0xa7, 0xc6, 0x13, 0x8c, 0x2b, 0xf9, 0x18, 0x87, 0x3b, 0xd1, 0xfb, 0x21, 0xcb, 0x3d, 0xb8, 0x62, + 0x91, 0x7d, 0xa3, 0xdf, 0x89, 0x1d, 0x1e, 0xcb, 0x4a, 0x9c, 0xf7, 0x78, 0x3e, 0xde, 0x0b, 0x9c, + 0x8b, 0x38, 0xe8, 0x5d, 0xc3, 0x3f, 0x12, 0x32, 0xde, 0x06, 0xb5, 0x63, 0xf8, 0x01, 0x3f, 0x17, + 0xe4, 0x6e, 0x5b, 0xda, 0x24, 0x1e, 0xcb, 0x04, 0x85, 0xe0, 0x81, 0x50, 0x8a, 0xa6, 0xa5, 0xbe, + 0x03, 0x53, 0x88, 0xbc, 0x6f, 0x7b, 0x21, 0x89, 0x6d, 0x69, 0x2a, 0x62, 0x2b, 0x14, 0x74, 0x9f, + 0x42, 0x90, 0xa4, 0x69, 0xa9, 0x7f, 0x05, 0xaf, 0x23, 0x7a, 0x52, 0x79, 0x3f, 0x30, 0x3c, 0xea, + 0x33, 0x21, 0xf9, 0x14, 0x92, 0xd7, 0x28, 0x6a, 0x5c, 0xc3, 0x1d, 0x86, 0x27, 0x98, 0xdd, 0x05, + 0x40, 0x4a, 0x96, 0x96, 0xa6, 0x73, 0xa6, 0xa5, 0x12, 0xd2, 0x60, 0x56, 0x6a, 0x01, 0x6a, 0xd8, + 0x8e, 0x67, 0xb7, 0x99, 0x9c, 0x6c, 0xaa, 0x94, 0xf2, 0xf3, 0x28, 0xc3, 0xad, 0xc3, 0x4c, 0x72, + 0x53, 0x22, 0xb1, 0xcd, 0xe2, 0x5e, 0xa6, 0x4e, 0x62, 0xfb, 0x10, 0xf9, 0xec, 0x3e, 0x2c, 0xa7, + 0x0c, 0x61, 0x1e, 0x12, 0xab, 0xdf, 0x89, 0x9b, 0x62, 0x8e, 0xe5, 0xc5, 0x38, 0xf9, 0x8e, 0xc0, + 0x12, 0x86, 0xd8, 0x84, 0xda, 0x39, 0x06, 0xd5, 0x90, 0xcb, 0xc2, 0xc9, 0xe9, 0xc6, 0xdc, 0x49, + 0xeb, 0x2f, 0x3c, 0x6a, 0x3e, 0x9f, 0x47, 0x25, 0x36, 0x28, 0x5c, 0x69, 0xc8, 0x28, 0x46, 0x40, + 0x83, 0x6e, 0xa0, 0x2d, 0x60, 0x58, 0x4e, 0xd0, 0x6c, 0x30, 0x50, 0xe2, 0x52, 0x26, 0x36, 0x83, + 0xc7, 0xf3, 0x5a, 0xce, 0xe3, 0x99, 0xcb, 0xd8, 0x2a, 0x9e, 0x93, 0x01, 0x8b, 0xa7, 0xd9, 0x1c, + 0x05, 0x2c, 0xe6, 0x14, 0x30, 0x9f, 0x79, 0x22, 0x28, 0xc2, 0x83, 0xeb, 0x49, 0x11, 0xae, 0x67, + 0x1f, 0xd8, 0x8e, 0xd1, 0x49, 0xcb, 0xaa, 0xe5, 0x94, 0x75, 0x35, 0x2e, 0xeb, 0x31, 0x67, 0x96, + 0x94, 0x79, 0x07, 0xb4, 0xa4, 0x4c, 0x8f, 0x3c, 0xeb, 0x13, 0x1f, 0x0f, 0x7f, 0x09, 0xc3, 0xdf, + 0x4c, 0x9c, 0x89, 0xce, 0xa0, 0x4d, 0x4b, 0xfd, 0x3a, 0x1e, 0x31, 0x45, 0x7d, 0xab, 0xdd, 0x5b, + 0x2e, 0xac, 0x54, 0x4f, 0x49, 0x91, 0x58, 0x17, 0xd3, 0xe4, 0x98, 0x08, 0x1e, 0x83, 0x1e, 0x89, + 0x45, 0x58, 0xbe, 0xa2, 0x3e, 0x4e, 0x9b, 0xc2, 0xef, 0x1f, 0x1c, 0x50, 0xb5, 0x4c, 0xd7, 0x09, + 0x6c, 0x87, 0xd6, 0x50, 0x7e, 0x9b, 0xd6, 0x9e, 0xdb, 0xcb, 0x85, 0x15, 0x59, 0x5f, 0x4e, 0x18, + 0x95, 0xa1, 0x6e, 0x71, 0xcc, 0x0d, 0xff, 0x11, 0x39, 0x19, 0xbe, 0x32, 0xbc, 0xdc, 0x6e, 0xfb, + 0xf6, 0xb7, 0xa4, 0xbd, 0x37, 0xa0, 0x25, 0xd2, 0xfd, 0xe1, 0x2b, 0xf3, 0x80, 0x61, 0xed, 0xd8, + 0xdf, 0x92, 0x4d, 0x8a, 0xa3, 0xde, 0x00, 0xc5, 0x34, 0x1c, 0x93, 0x74, 0x84, 0xa1, 0x88, 0xa5, + 0x5d, 0x41, 0x1d, 0x26, 0xd8, 0xba, 0x2e, 0x96, 0xd5, 0xb7, 0x60, 0x32, 0x89, 0x4a, 0x6d, 0xba, + 0x8c, 0x36, 0x4d, 0xe2, 0x36, 0x11, 0xd7, 0x0f, 0x6c, 0xf3, 0x68, 0xd0, 0x8e, 0x65, 0xa9, 0xab, + 0x0c, 0x97, 0x01, 0x76, 0xc3, 0x5c, 0x75, 0x00, 0xcb, 0x1c, 0x57, 0xb8, 0x45, 0x3b, 0x70, 0xdb, + 0x51, 0x44, 0xa3, 0x97, 0xaf, 0x9e, 0xef, 0xf2, 0x2d, 0x32, 0x46, 0xc2, 0x25, 0x76, 0xdd, 0x1d, + 0x11, 0xe3, 0xe8, 0x2d, 0xd4, 0xa0, 0x28, 0xee, 0xdd, 0xeb, 0xac, 0x71, 0xe0, 0x9f, 0xea, 0xe7, + 0x30, 0xeb, 0x91, 0xc0, 0x1b, 0xf0, 0xbc, 0xdd, 0x69, 0xdb, 0x4e, 0x40, 0xbc, 0x63, 0xa3, 0xa3, + 0x5d, 0xcb, 0x27, 0x78, 0x1a, 0xc9, 0x59, 0x6e, 0xef, 0x34, 0x39, 0x71, 0xc4, 0xb6, 0x6b, 0x3c, + 0xb7, 0xbb, 0xfd, 0x6e, 0xc4, 0xf6, 0xfa, 0x45, 0xd8, 0x7e, 0xca, 0xa8, 0x43, 0xb6, 0xb7, 0xd3, + 0x6c, 0xf9, 0x36, 0x7c, 0xed, 0x0d, 0xdc, 0x56, 0x82, 0x8a, 0x87, 0x13, 0x5f, 0xfd, 0x90, 0xf6, + 0x0c, 0x94, 0x6a, 0xcf, 0x30, 0x8f, 0xdc, 0xfd, 0xfd, 0xb6, 0xe9, 0x92, 0xfd, 0x7d, 0xdb, 0xb4, + 0x89, 0x13, 0x68, 0x6f, 0x2e, 0x17, 0x56, 0x0a, 0xfa, 0x1c, 0x22, 0x6c, 0x32, 0xf8, 0x56, 0x04, + 0x56, 0xbb, 0x50, 0xcf, 0x28, 0x10, 0xc8, 0xf3, 0x9e, 0xcd, 0xd4, 0x65, 0xd7, 0x78, 0x25, 0xe7, + 0x35, 0x5e, 0x1a, 0xaa, 0x14, 0xb6, 0x43, 0x4e, 0xbc, 0x4b, 0x5a, 0x62, 0xaa, 0x3a, 0xae, 0xd3, + 0xc6, 0x5f, 0xc6, 0x5e, 0x87, 0xb4, 0x89, 0xe7, 0xb9, 0x1e, 0xde, 0x4b, 0x5f, 0xbb, 0xb1, 0x3c, + 0xb2, 0x52, 0xd2, 0x5f, 0x43, 0xe0, 0x23, 0xd7, 0xd1, 0x05, 0xd2, 0x36, 0xc5, 0xa1, 0x57, 0xce, + 0x57, 0x57, 0x40, 0x39, 0x34, 0x7c, 0x46, 0xdf, 0xee, 0xb9, 0x1d, 0xdb, 0x1c, 0x68, 0x6f, 0xa1, + 0x6b, 0x57, 0x0f, 0x0d, 0x1f, 0x29, 0x9e, 0xe0, 0xaa, 0xfa, 0x3a, 0x8c, 0x9b, 0x9e, 0xeb, 0x84, + 0xfe, 0xa7, 0xbd, 0x8d, 0x9e, 0x5a, 0xa1, 0x8b, 0xc2, 0x97, 0x68, 0x89, 0xea, 0xdb, 0x07, 0x34, + 0x7a, 0x99, 0x6e, 0xdf, 0x09, 0xb4, 0x06, 0xde, 0xae, 0x32, 0x5b, 0xdb, 0xa2, 0x4b, 0xea, 0x67, + 0x30, 0x69, 0xf4, 0x03, 0xb7, 0xed, 0x11, 0x9f, 0x04, 0xed, 0x9e, 0x6b, 0x3b, 0x81, 0xaf, 0xdd, + 0x42, 0xab, 0x5c, 0x8f, 0x42, 0x08, 0x8d, 0x1d, 0x61, 0x83, 0x7e, 0xbc, 0xd6, 0xd0, 0x29, 0xf6, + 0x13, 0x44, 0xd6, 0x27, 0x28, 0x7d, 0x6c, 0x41, 0xfd, 0x5b, 0x98, 0xf4, 0x89, 0xe1, 0x99, 0x87, + 0xf4, 0x90, 0x3d, 0x7b, 0xaf, 0x4f, 0x2f, 0xf6, 0x6d, 0xec, 0x7d, 0x1e, 0xe7, 0x29, 0xdc, 0x33, + 0xcb, 0xed, 0xc6, 0x0e, 0xb2, 0xdc, 0x08, 0x39, 0xb2, 0x66, 0x48, 0xf1, 0x53, 0xcb, 0xea, 0x53, + 0x90, 0xba, 0xa4, 0xeb, 0x6a, 0xef, 0xa1, 0xc0, 0xad, 0x97, 0x17, 0xf8, 0x29, 0xe9, 0xba, 0x4c, + 0x08, 0x32, 0x54, 0xbf, 0x81, 0x49, 0x5e, 0x17, 0xf0, 0xc0, 0x65, 0x13, 0x5f, 0xfb, 0x33, 0xb4, + 0xd4, 0xbb, 0x99, 0x52, 0x78, 0x78, 0xa3, 0x12, 0x78, 0xd5, 0xf0, 0x40, 0xd0, 0xe9, 0xca, 0x71, + 0x6a, 0x45, 0xbd, 0x05, 0xb3, 0xbc, 0x10, 0x0b, 0x9d, 0x95, 0x57, 0xed, 0x77, 0xf0, 0x64, 0xa7, + 0x10, 0x1a, 0xaa, 0xc8, 0xaa, 0xf7, 0xbf, 0x86, 0x89, 0x08, 0x9d, 0x76, 0x99, 0xbe, 0xf6, 0x3e, + 0x6a, 0xb4, 0x9e, 0x67, 0xdf, 0x21, 0x33, 0xda, 0x25, 0xf9, 0x7a, 0x95, 0x24, 0xbe, 0x13, 0xe9, + 0x96, 0xaa, 0x92, 0xbe, 0x3b, 0x1f, 0x5c, 0x34, 0xdd, 0xea, 0xfd, 0xf4, 0xad, 0xb9, 0x0d, 0x73, + 0x43, 0x25, 0x68, 0xf0, 0x1c, 0x77, 0xfd, 0x21, 0xab, 0xbd, 0x92, 0x65, 0xe8, 0xee, 0x73, 0xba, + 0xeb, 0xdb, 0x30, 0x8b, 0x1d, 0x75, 0x3b, 0xf0, 0x0c, 0xc7, 0xb7, 0x51, 0x23, 0xe6, 0xe0, 0x1f, + 0x21, 0xd1, 0x34, 0x42, 0x77, 0x43, 0x20, 0xf3, 0xf4, 0x4f, 0xa0, 0x9a, 0x6c, 0x14, 0xb4, 0x3f, + 0xcf, 0xb9, 0x81, 0x71, 0x12, 0x6f, 0x0f, 0xd4, 0x55, 0x98, 0x76, 0xc8, 0xc9, 0xf0, 0x39, 0xfd, + 0x05, 0xeb, 0xda, 0x1c, 0x72, 0x92, 0x3a, 0xa5, 0x87, 0x50, 0xe1, 0x3d, 0x16, 0x0e, 0xd1, 0xb4, + 0x8f, 0x51, 0xee, 0x8d, 0xcc, 0x23, 0x42, 0x0c, 0xe6, 0x32, 0x66, 0xe0, 0x7a, 0x5b, 0xf4, 0x53, + 0x74, 0x6c, 0xf8, 0xa1, 0xbe, 0x0f, 0xda, 0x50, 0xc7, 0x26, 0x0a, 0xd6, 0xbb, 0xac, 0x01, 0x4b, + 0xb5, 0x6d, 0xa2, 0x66, 0xbd, 0x05, 0xb3, 0x66, 0xc7, 0xf5, 0xb9, 0xdd, 0xf6, 0x89, 0x17, 0x76, + 0x08, 0x7f, 0xc9, 0x8c, 0x8d, 0xd0, 0x5d, 0x0e, 0xe4, 0x5d, 0xc2, 0x1d, 0xd0, 0x18, 0xd1, 0xb1, + 0xed, 0xdb, 0x7b, 0x76, 0xc7, 0x0e, 0x06, 0x21, 0xd9, 0x06, 0x92, 0xcd, 0x20, 0xfc, 0x8b, 0x10, + 0xcc, 0x09, 0xef, 0x02, 0x70, 0x69, 0xd4, 0xd6, 0x9b, 0x79, 0x4b, 0x7c, 0xa6, 0x03, 0xb5, 0xf3, + 0x36, 0x2c, 0x65, 0x4b, 0xe6, 0xfd, 0x25, 0xb1, 0xb4, 0x2d, 0x8c, 0x8d, 0x8b, 0x19, 0x0a, 0x6c, + 0x09, 0x9c, 0x05, 0x0b, 0x66, 0x32, 0x63, 0x47, 0xc6, 0x70, 0xe4, 0xbd, 0xe4, 0x98, 0x61, 0x29, + 0x19, 0x00, 0xf9, 0x30, 0xf3, 0x78, 0xad, 0xf1, 0xc4, 0x18, 0x74, 0x5c, 0xc3, 0x8a, 0xcf, 0x31, + 0xbe, 0x84, 0x52, 0x18, 0x30, 0x7e, 0x53, 0xce, 0xe1, 0x94, 0x22, 0x9c, 0x49, 0xb4, 0x24, 0x59, + 0x51, 0x26, 0x5b, 0x92, 0x7c, 0x53, 0x79, 0xa7, 0x25, 0xc9, 0xef, 0x28, 0x8d, 0x96, 0x24, 0xaf, + 0x2a, 0xef, 0xb6, 0x24, 0xf9, 0x5d, 0x65, 0xad, 0x25, 0xc9, 0x6b, 0xca, 0x7a, 0x4b, 0x92, 0xd7, + 0x95, 0x5b, 0xf5, 0x5b, 0x50, 0x4d, 0x5e, 0x72, 0x9a, 0x12, 0xe2, 0x65, 0x17, 0xea, 0x38, 0xa2, + 0x97, 0x0f, 0xa3, 0x22, 0xab, 0xfe, 0x4b, 0x01, 0x66, 0x87, 0x42, 0x22, 0x0e, 0x52, 0xb0, 0x9e, + 0xf2, 0x08, 0xbd, 0x7a, 0xb1, 0x7a, 0xaa, 0xc0, 0xeb, 0x29, 0x04, 0x44, 0xf5, 0xd4, 0x0c, 0x8c, + 0xf1, 0x8b, 0xc1, 0xe6, 0x1e, 0xa3, 0x1e, 0x5e, 0x86, 0x16, 0x8c, 0xe2, 0xf5, 0xc4, 0x21, 0x47, + 0x75, 0xfd, 0x76, 0xbe, 0x3a, 0x35, 0xa9, 0x87, 0xce, 0x58, 0xa8, 0xf7, 0x61, 0x8c, 0xfe, 0xe8, + 0xfb, 0x38, 0x02, 0x49, 0x14, 0xbd, 0xe7, 0x73, 0xe9, 0xfb, 0x3a, 0xa7, 0xae, 0xff, 0x61, 0x0c, + 0x94, 0x84, 0xdb, 0xff, 0x56, 0xf3, 0x9d, 0xc8, 0x06, 0x23, 0x71, 0x1b, 0x6c, 0x41, 0x29, 0xaa, + 0xd7, 0x99, 0xea, 0x6f, 0x9c, 0x6d, 0x87, 0xb0, 0x4e, 0x97, 0x03, 0x51, 0x9f, 0x37, 0x60, 0x2a, + 0x30, 0xbc, 0x03, 0x92, 0x9a, 0x1d, 0xb1, 0x19, 0xcf, 0x24, 0x03, 0xa5, 0x66, 0x47, 0x1c, 0x3f, + 0xae, 0xf3, 0x18, 0x9b, 0xaf, 0x30, 0x48, 0x72, 0x76, 0xc4, 0xb1, 0xf9, 0x06, 0x8a, 0x6c, 0xfb, + 0x6c, 0x91, 0xc5, 0xb5, 0xe4, 0x40, 0x47, 0x4e, 0x0f, 0x74, 0x3e, 0x82, 0x05, 0xce, 0xc2, 0x3c, + 0xb4, 0x3b, 0x56, 0x24, 0xd6, 0x75, 0x3a, 0x03, 0x9c, 0xff, 0xc8, 0xfa, 0x1c, 0xc3, 0xd8, 0xa2, + 0x08, 0x42, 0xfa, 0x63, 0xa7, 0x33, 0xc0, 0x31, 0xf7, 0x70, 0x47, 0x0d, 0x6c, 0x36, 0xe1, 0xa7, + 0xbb, 0x68, 0x0d, 0x8a, 0x22, 0x04, 0x96, 0xd9, 0x10, 0x9d, 0x7f, 0xaa, 0x73, 0x50, 0x14, 0xd1, + 0xaa, 0x82, 0x90, 0xb1, 0x80, 0x85, 0xa7, 0x26, 0x4c, 0xc4, 0xe3, 0x0a, 0x8d, 0x51, 0xe3, 0x79, + 0xe7, 0x07, 0x11, 0x21, 0x06, 0xaa, 0x9b, 0xa0, 0x5a, 0x84, 0x06, 0x9b, 0xb6, 0xb1, 0x1f, 0x10, + 0xaf, 0x8d, 0xe1, 0x48, 0x9b, 0xc0, 0x0d, 0x2a, 0x0c, 0xb2, 0x41, 0x01, 0x5b, 0x74, 0x5d, 0xfd, + 0x87, 0x02, 0xb0, 0x80, 0x15, 0x9f, 0x5b, 0x51, 0x15, 0x2d, 0x12, 0x18, 0x36, 0xce, 0xa3, 0xa9, + 0x1a, 0x8f, 0xf2, 0x64, 0xf0, 0xb4, 0xd3, 0x36, 0x50, 0x44, 0x34, 0xcd, 0x32, 0xfc, 0xa3, 0x7b, + 0x8c, 0xeb, 0x83, 0x4b, 0xfa, 0xbc, 0x79, 0x1a, 0x70, 0xe1, 0x6b, 0x98, 0x3f, 0x95, 0x52, 0xbd, + 0x0b, 0x8b, 0xa6, 0xe1, 0xb4, 0xfd, 0x23, 0xbb, 0x17, 0x0f, 0xc5, 0x34, 0xa4, 0xda, 0xb4, 0x31, + 0x28, 0xe0, 0x46, 0xe7, 0x4d, 0xc3, 0xd9, 0x39, 0xb2, 0x7b, 0x51, 0x18, 0xde, 0xe0, 0x08, 0x9b, + 0x55, 0xa8, 0xc4, 0x37, 0xc8, 0x62, 0x59, 0xfd, 0x5f, 0x24, 0x98, 0x8a, 0xcd, 0xae, 0x7f, 0x37, + 0xf7, 0x2e, 0xe6, 0x6b, 0xa3, 0x49, 0x5f, 0xbb, 0x06, 0xd5, 0xd4, 0x2c, 0x8d, 0x8d, 0x51, 0x2b, + 0xfb, 0xf1, 0x39, 0x5a, 0x1d, 0xc6, 0x1d, 0xf2, 0x3c, 0x86, 0xc4, 0xa6, 0xa6, 0x65, 0xba, 0x28, + 0x70, 0xb2, 0xbd, 0x5f, 0x3e, 0xc5, 0xfb, 0xaf, 0x42, 0x65, 0xcf, 0x33, 0x1c, 0xf3, 0xb0, 0x1d, + 0xb8, 0x47, 0x84, 0x5d, 0x81, 0x8a, 0x5e, 0x66, 0x6b, 0xbb, 0x74, 0x49, 0xd4, 0x2c, 0xd4, 0x28, + 0x09, 0xd4, 0x71, 0x44, 0xa5, 0x35, 0x8b, 0xde, 0x77, 0x36, 0x63, 0x04, 0xb1, 0x7b, 0x33, 0x71, + 0xde, 0xbd, 0x51, 0x5e, 0xf2, 0xde, 0x2c, 0x02, 0x08, 0xa5, 0xf8, 0x94, 0xb2, 0xa4, 0xcb, 0x4c, + 0x95, 0xa6, 0xd5, 0x92, 0xe4, 0x92, 0x02, 0xe1, 0x74, 0x3e, 0x9c, 0xcb, 0xd7, 0xff, 0x7f, 0x04, + 0xd4, 0x54, 0xb1, 0xf1, 0xfb, 0x76, 0x9b, 0x98, 0xa9, 0xc7, 0xce, 0x33, 0x75, 0xf1, 0x25, 0x4d, + 0x9d, 0x2c, 0xc6, 0xe4, 0x8b, 0x17, 0x63, 0xc9, 0x81, 0x6d, 0xe9, 0xe2, 0x03, 0xdb, 0xb3, 0xea, + 0x48, 0x38, 0xa3, 0x8e, 0xac, 0xff, 0x22, 0xc1, 0x38, 0xe5, 0xf0, 0xfb, 0xc9, 0xcc, 0xdb, 0x50, + 0xe1, 0x43, 0x20, 0xc6, 0x67, 0x14, 0xf9, 0xd4, 0x4f, 0x29, 0x4e, 0xf8, 0xa8, 0x07, 0x79, 0x94, + 0x83, 0xe8, 0x43, 0x25, 0xb1, 0x09, 0xac, 0x18, 0x80, 0x20, 0xbf, 0x31, 0xe4, 0xb7, 0x96, 0xaf, + 0x72, 0xe2, 0xa3, 0x11, 0x64, 0x1f, 0x0e, 0x6d, 0x63, 0x8b, 0x71, 0xc7, 0x2c, 0x26, 0x1d, 0xf3, + 0x06, 0x84, 0xb1, 0x26, 0x9c, 0xfe, 0xca, 0x38, 0xae, 0x99, 0x10, 0xeb, 0x62, 0xf2, 0x3b, 0x0f, + 0x72, 0x18, 0xa6, 0xd8, 0x73, 0x70, 0x91, 0xf0, 0xe8, 0x14, 0x73, 0x6f, 0x38, 0xcf, 0xbd, 0xcb, + 0x2f, 0xe9, 0xde, 0xe9, 0x08, 0x58, 0x19, 0x8e, 0x80, 0x37, 0x40, 0x31, 0x3a, 0x1e, 0x31, 0x2c, + 0x91, 0xb9, 0x88, 0x85, 0xd1, 0x4f, 0xd6, 0x27, 0xf8, 0xfa, 0x06, 0x5f, 0xae, 0xff, 0xf3, 0x65, + 0x50, 0x44, 0xf2, 0x0a, 0x9d, 0x2e, 0xb6, 0x8d, 0x42, 0x62, 0x1b, 0x69, 0x6f, 0xbc, 0x7c, 0xae, + 0x37, 0x8e, 0x9c, 0xe1, 0x8d, 0xd2, 0xa9, 0xde, 0x38, 0xfa, 0xa7, 0x07, 0x9e, 0xb1, 0xe4, 0xf9, + 0xfe, 0x76, 0xf1, 0xa5, 0xfe, 0xf7, 0x55, 0xa8, 0x6c, 0x98, 0x81, 0x7d, 0x6c, 0x07, 0x03, 0x34, + 0x57, 0x4c, 0x6a, 0x21, 0x29, 0xf5, 0x0e, 0x68, 0xe9, 0xdc, 0x16, 0x3e, 0x20, 0xb2, 0x47, 0xe9, + 0x99, 0x64, 0x86, 0x13, 0xef, 0x87, 0x9f, 0x40, 0x35, 0x35, 0x84, 0x97, 0xf2, 0x36, 0xf0, 0x7e, + 0x62, 0xe0, 0xbe, 0x02, 0xca, 0xd0, 0x2b, 0x0b, 0x8b, 0xc9, 0x55, 0x3f, 0xf9, 0xb2, 0xb2, 0x05, + 0x95, 0xc4, 0x13, 0x46, 0x5e, 0xf3, 0x94, 0xfd, 0xd8, 0xb3, 0xc5, 0x12, 0x94, 0x0d, 0x6e, 0x1a, + 0x91, 0xc5, 0x4b, 0x3a, 0x88, 0x25, 0x56, 0x47, 0xc7, 0xda, 0x29, 0xfe, 0x30, 0xea, 0x85, 0x8d, + 0xd4, 0x57, 0x30, 0x7f, 0xfa, 0x94, 0x19, 0xf2, 0x4d, 0x65, 0x67, 0xfd, 0xec, 0xf9, 0x72, 0x8a, + 0x77, 0x94, 0x23, 0x2e, 0xf0, 0x8a, 0x1a, 0xe3, 0xbd, 0x25, 0xf2, 0x05, 0xe5, 0xbd, 0x8b, 0x63, + 0x1a, 0xaa, 0x6b, 0x9a, 0x71, 0xce, 0x57, 0xd4, 0x29, 0x96, 0x3d, 0x92, 0x5c, 0x1f, 0xc2, 0xe4, + 0x21, 0x31, 0xbc, 0x60, 0x8f, 0x18, 0xc1, 0x45, 0x9f, 0x4e, 0x95, 0x90, 0x52, 0x70, 0xcb, 0x7a, + 0x4b, 0xa8, 0x5e, 0xe0, 0x2d, 0x81, 0xd5, 0x46, 0x59, 0x6f, 0x09, 0x54, 0x35, 0x2f, 0x7c, 0x05, + 0xa3, 0x3d, 0xaa, 0xc2, 0x42, 0x67, 0x20, 0x72, 0x19, 0x6b, 0x42, 0xe3, 0x23, 0xfe, 0xc9, 0xe4, + 0x88, 0x3f, 0xd9, 0x5f, 0xa9, 0xe9, 0xfe, 0xea, 0x46, 0xe4, 0xc6, 0xb6, 0x45, 0x9c, 0xc0, 0x0e, + 0x06, 0xf8, 0xfa, 0x8a, 0xef, 0x15, 0xb8, 0xde, 0xe4, 0xcb, 0x99, 0x73, 0xe5, 0xe9, 0xcc, 0xb9, + 0xf2, 0xe9, 0xcf, 0x0a, 0x33, 0xaf, 0xe6, 0x59, 0x61, 0xf6, 0xd5, 0x3c, 0x2b, 0xcc, 0x9d, 0xf1, + 0xac, 0xb0, 0x0b, 0x33, 0x8c, 0x2a, 0x3d, 0xd1, 0xd4, 0x72, 0x5e, 0xef, 0x29, 0x24, 0x4f, 0xcd, + 0x32, 0xcf, 0x7c, 0xac, 0x98, 0x3f, 0xfb, 0xb1, 0x22, 0xc7, 0xeb, 0xc1, 0xc2, 0xf9, 0xaf, 0x07, + 0x8f, 0x40, 0x65, 0x5c, 0xd8, 0x4c, 0x95, 0xfd, 0x0d, 0x90, 0x3f, 0xbb, 0x2e, 0x27, 0xab, 0x0f, + 0x0e, 0xa4, 0x29, 0xe3, 0x3e, 0xfb, 0xa9, 0x2b, 0x48, 0xfb, 0xd0, 0xf0, 0x03, 0xbe, 0x42, 0x1b, + 0xf8, 0x18, 0x3f, 0x9a, 0xae, 0x88, 0x17, 0xb9, 0xda, 0x22, 0xba, 0xda, 0x5c, 0x48, 0xf5, 0x14, + 0xe1, 0xa1, 0xcb, 0x65, 0xb7, 0x30, 0xb5, 0x53, 0x5a, 0x98, 0x2f, 0x60, 0x16, 0x85, 0x44, 0x57, + 0x5b, 0x74, 0xc3, 0x4b, 0x59, 0xea, 0x0f, 0x0d, 0xcc, 0x7c, 0x7d, 0x9a, 0xd2, 0x3f, 0x10, 0xe4, + 0xa2, 0x77, 0xfd, 0x06, 0x16, 0x52, 0x7c, 0xe3, 0x7f, 0x18, 0x58, 0xce, 0xfb, 0x22, 0x9d, 0xe0, + 0x1d, 0xfd, 0x73, 0xa0, 0x25, 0xc9, 0x23, 0x8a, 0xd4, 0x92, 0xe4, 0x31, 0xa5, 0xd8, 0x92, 0xe4, + 0x2b, 0x4a, 0xad, 0xfe, 0x5f, 0x05, 0x28, 0x61, 0xb5, 0x7a, 0x4e, 0x16, 0xcc, 0xca, 0x41, 0x97, + 0x33, 0x73, 0xd0, 0x06, 0x94, 0xd1, 0x4f, 0x79, 0x86, 0x1e, 0xc9, 0xfb, 0x17, 0x3e, 0x46, 0x24, + 0x32, 0x50, 0x3c, 0x10, 0x49, 0x28, 0x07, 0x63, 0x0b, 0x8f, 0x41, 0xf3, 0x20, 0xb3, 0x78, 0x15, + 0x0e, 0x90, 0x8a, 0xf8, 0xdd, 0xb4, 0xea, 0xff, 0x2d, 0x81, 0x8a, 0xe3, 0x99, 0xe4, 0xbf, 0x9f, + 0xce, 0xcc, 0xef, 0xd1, 0x60, 0x3a, 0x3b, 0xbf, 0x87, 0xf0, 0x44, 0x7e, 0xcf, 0x32, 0xc9, 0x48, + 0xa6, 0x49, 0x1a, 0x30, 0x25, 0x30, 0xe3, 0x75, 0x15, 0x1f, 0x7d, 0x71, 0x50, 0x6c, 0x98, 0x75, + 0x0d, 0x04, 0x07, 0xd1, 0x6c, 0xb2, 0xb1, 0x97, 0x48, 0xee, 0x6c, 0x9c, 0x95, 0x39, 0xdc, 0x94, + 0xb3, 0x87, 0x9b, 0x8b, 0x50, 0x0a, 0x0b, 0x3c, 0x91, 0xb1, 0xc3, 0x85, 0x0b, 0xfe, 0x95, 0xe9, + 0xcb, 0xf0, 0x2f, 0x58, 0x2c, 0x4b, 0xf2, 0xf8, 0x5c, 0xc6, 0x7a, 0x6f, 0xe5, 0x94, 0xae, 0xe1, + 0x89, 0x78, 0x11, 0xf0, 0x09, 0x8b, 0xdc, 0xe2, 0xcf, 0x5a, 0xb1, 0x25, 0xaa, 0x47, 0xfa, 0x28, + 0xc2, 0x39, 0x98, 0x92, 0x3c, 0x04, 0x1c, 0xd8, 0x8f, 0xb2, 0xf7, 0x89, 0xf1, 0x8b, 0xbe, 0x4f, + 0x30, 0xba, 0xa1, 0x4a, 0xb8, 0x3a, 0x54, 0x09, 0x87, 0x7f, 0xbf, 0x2b, 0x2a, 0x72, 0xfd, 0xdf, + 0x0a, 0x30, 0xc9, 0x2d, 0xba, 0x85, 0xf9, 0xf3, 0x55, 0x39, 0x56, 0x66, 0xe6, 0x1e, 0xc9, 0xfe, + 0x17, 0x40, 0xb6, 0xc9, 0xa4, 0x6c, 0x93, 0xd5, 0xff, 0xbd, 0x00, 0xb0, 0x83, 0xaf, 0xa9, 0xaf, + 0x4a, 0xf7, 0x64, 0x6d, 0x38, 0x92, 0xae, 0x0d, 0xb3, 0xd5, 0x2d, 0x66, 0xab, 0x9b, 0xfa, 0xf3, + 0x23, 0x0b, 0x5a, 0xb2, 0x52, 0xaa, 0x7f, 0x57, 0x00, 0x79, 0xeb, 0x90, 0x98, 0x47, 0x7e, 0xbf, + 0x9b, 0xde, 0xc4, 0x68, 0xb4, 0x89, 0x7b, 0x30, 0xb6, 0xdf, 0x31, 0x8e, 0x5d, 0x0f, 0x55, 0xae, + 0xae, 0xdf, 0x3c, 0xbb, 0x17, 0x11, 0x1c, 0xef, 0x23, 0x8d, 0xce, 0x69, 0xa3, 0x7f, 0xa0, 0x8e, + 0x60, 0x93, 0xc6, 0x3e, 0x36, 0xff, 0xe6, 0x87, 0x9f, 0x6a, 0x97, 0x7e, 0xfc, 0xa9, 0x76, 0xe9, + 0xd7, 0x9f, 0x6a, 0x85, 0xef, 0x5e, 0xd4, 0x0a, 0xff, 0xf4, 0xa2, 0x56, 0xf8, 0xcf, 0x17, 0xb5, + 0xc2, 0x0f, 0x2f, 0x6a, 0x85, 0xff, 0x7d, 0x51, 0x2b, 0xfc, 0xdf, 0x8b, 0xda, 0xa5, 0x5f, 0x5f, + 0xd4, 0x0a, 0xdf, 0xff, 0x5c, 0xbb, 0xf4, 0xc3, 0xcf, 0xb5, 0x4b, 0x3f, 0xfe, 0x5c, 0xbb, 0xf4, + 0xd5, 0xed, 0x03, 0x37, 0xd2, 0xc1, 0x76, 0x4f, 0xff, 0x77, 0xf6, 0x47, 0xb1, 0xcf, 0xbd, 0x31, + 0x0c, 0x9a, 0xb7, 0xfe, 0x18, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x0b, 0x92, 0x45, 0x40, 0x30, 0x00, + 0x00, } func (this *ShardInfo) Equal(that interface{}) bool { @@ -2656,6 +2676,12 @@ func (this *WorkflowExecutionInfo) Equal(that interface{}) bool { if this.WorkflowTaskType != that1.WorkflowTaskType { return false } + if this.WorkflowTaskSuggestContinueAsNew != that1.WorkflowTaskSuggestContinueAsNew { + return false + } + if this.WorkflowTaskHistorySizeBytes != that1.WorkflowTaskHistorySizeBytes { + return false + } if this.CancelRequested != that1.CancelRequested { return false } @@ -3634,7 +3660,7 @@ func (this *WorkflowExecutionInfo) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 62) + s := make([]string, 0, 64) s = append(s, "&persistence.WorkflowExecutionInfo{") s = append(s, "NamespaceId: "+fmt.Sprintf("%#v", this.NamespaceId)+",\n") s = append(s, "WorkflowId: "+fmt.Sprintf("%#v", this.WorkflowId)+",\n") @@ -3663,6 +3689,8 @@ func (this *WorkflowExecutionInfo) GoString() string { s = append(s, "WorkflowTaskOriginalScheduledTime: "+fmt.Sprintf("%#v", this.WorkflowTaskOriginalScheduledTime)+",\n") s = append(s, "WorkflowTaskRequestId: "+fmt.Sprintf("%#v", this.WorkflowTaskRequestId)+",\n") s = append(s, "WorkflowTaskType: "+fmt.Sprintf("%#v", this.WorkflowTaskType)+",\n") + s = append(s, "WorkflowTaskSuggestContinueAsNew: "+fmt.Sprintf("%#v", this.WorkflowTaskSuggestContinueAsNew)+",\n") + s = append(s, "WorkflowTaskHistorySizeBytes: "+fmt.Sprintf("%#v", this.WorkflowTaskHistorySizeBytes)+",\n") s = append(s, "CancelRequested: "+fmt.Sprintf("%#v", this.CancelRequested)+",\n") s = append(s, "CancelRequestId: "+fmt.Sprintf("%#v", this.CancelRequestId)+",\n") s = append(s, "StickyTaskQueue: "+fmt.Sprintf("%#v", this.StickyTaskQueue)+",\n") @@ -4149,6 +4177,25 @@ func (m *WorkflowExecutionInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.WorkflowTaskHistorySizeBytes != 0 { + i = encodeVarintExecutions(dAtA, i, uint64(m.WorkflowTaskHistorySizeBytes)) + i-- + dAtA[i] = 0x4 + i-- + dAtA[i] = 0xb0 + } + if m.WorkflowTaskSuggestContinueAsNew { + i-- + if m.WorkflowTaskSuggestContinueAsNew { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x4 + i-- + dAtA[i] = 0xa8 + } if m.WorkflowTaskType != 0 { i = encodeVarintExecutions(dAtA, i, uint64(m.WorkflowTaskType)) i-- @@ -6256,6 +6303,12 @@ func (m *WorkflowExecutionInfo) Size() (n int) { if m.WorkflowTaskType != 0 { n += 2 + sovExecutions(uint64(m.WorkflowTaskType)) } + if m.WorkflowTaskSuggestContinueAsNew { + n += 3 + } + if m.WorkflowTaskHistorySizeBytes != 0 { + n += 2 + sovExecutions(uint64(m.WorkflowTaskHistorySizeBytes)) + } return n } @@ -6961,6 +7014,8 @@ func (this *WorkflowExecutionInfo) String() string { `CloseTime:` + strings.Replace(fmt.Sprintf("%v", this.CloseTime), "Timestamp", "types.Timestamp", 1) + `,`, `CloseVisibilityTaskCompleted:` + fmt.Sprintf("%v", this.CloseVisibilityTaskCompleted) + `,`, `WorkflowTaskType:` + fmt.Sprintf("%v", this.WorkflowTaskType) + `,`, + `WorkflowTaskSuggestContinueAsNew:` + fmt.Sprintf("%v", this.WorkflowTaskSuggestContinueAsNew) + `,`, + `WorkflowTaskHistorySizeBytes:` + fmt.Sprintf("%v", this.WorkflowTaskHistorySizeBytes) + `,`, `}`, }, "") return s @@ -9638,6 +9693,45 @@ func (m *WorkflowExecutionInfo) Unmarshal(dAtA []byte) error { break } } + case 69: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkflowTaskSuggestContinueAsNew", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExecutions + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WorkflowTaskSuggestContinueAsNew = bool(v != 0) + case 70: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WorkflowTaskHistorySizeBytes", wireType) + } + m.WorkflowTaskHistorySizeBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExecutions + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.WorkflowTaskHistorySizeBytes |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipExecutions(dAtA[iNdEx:]) diff --git a/common/dynamicconfig/constants.go b/common/dynamicconfig/constants.go index cbf1d9d97f2..5e5196894b8 100644 --- a/common/dynamicconfig/constants.go +++ b/common/dynamicconfig/constants.go @@ -132,10 +132,16 @@ const ( HistorySizeLimitError = "limit.historySize.error" // HistorySizeLimitWarn is the per workflow execution history size limit for warning HistorySizeLimitWarn = "limit.historySize.warn" + // HistorySizeSuggestContinueAsNew is the workflow execution history size limit to suggest + // continue-as-new (in workflow task started event) + HistorySizeSuggestContinueAsNew = "limit.historySize.suggestContinueAsNew" // HistoryCountLimitError is the per workflow execution history event count limit HistoryCountLimitError = "limit.historyCount.error" // HistoryCountLimitWarn is the per workflow execution history event count limit for warning HistoryCountLimitWarn = "limit.historyCount.warn" + // HistoryCountSuggestContinueAsNew is the workflow execution history event count limit to + // suggest continue-as-new (in workflow task started event) + HistoryCountSuggestContinueAsNew = "limit.historyCount.suggestContinueAsNew" // MaxIDLengthLimit is the length limit for various IDs, including: Namespace, TaskQueue, WorkflowID, ActivityID, TimerID, // WorkflowType, ActivityType, SignalName, MarkerName, ErrorReason/FailureReason/CancelCause, Identity, RequestID MaxIDLengthLimit = "limit.maxIDLength" diff --git a/proto/internal/temporal/server/api/persistence/v1/executions.proto b/proto/internal/temporal/server/api/persistence/v1/executions.proto index 58c8759a3d6..8235da9260f 100644 --- a/proto/internal/temporal/server/api/persistence/v1/executions.proto +++ b/proto/internal/temporal/server/api/persistence/v1/executions.proto @@ -100,6 +100,8 @@ message WorkflowExecutionInfo { google.protobuf.Timestamp workflow_task_original_scheduled_time = 30 [(gogoproto.stdtime) = true]; string workflow_task_request_id = 31; temporal.server.api.enums.v1.WorkflowTaskType workflow_task_type = 68; + bool workflow_task_suggest_continue_as_new = 69; + int64 workflow_task_history_size_bytes = 70; bool cancel_requested = 29; string cancel_request_id = 32; diff --git a/service/history/configs/config.go b/service/history/configs/config.go index e6565e92292..044ee28ef63 100644 --- a/service/history/configs/config.go +++ b/service/history/configs/config.go @@ -181,18 +181,20 @@ type Config struct { DurableArchivalEnabled dynamicconfig.BoolPropertyFn // Size limit related settings - BlobSizeLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter - BlobSizeLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter - MemoSizeLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter - MemoSizeLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter - HistorySizeLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter - HistorySizeLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter - HistoryCountLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter - HistoryCountLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter - NumPendingChildExecutionsLimit dynamicconfig.IntPropertyFnWithNamespaceFilter - NumPendingActivitiesLimit dynamicconfig.IntPropertyFnWithNamespaceFilter - NumPendingSignalsLimit dynamicconfig.IntPropertyFnWithNamespaceFilter - NumPendingCancelsRequestLimit dynamicconfig.IntPropertyFnWithNamespaceFilter + BlobSizeLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter + BlobSizeLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter + MemoSizeLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter + MemoSizeLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter + HistorySizeLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter + HistorySizeLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter + HistorySizeSuggestContinueAsNew dynamicconfig.IntPropertyFnWithNamespaceFilter + HistoryCountLimitError dynamicconfig.IntPropertyFnWithNamespaceFilter + HistoryCountLimitWarn dynamicconfig.IntPropertyFnWithNamespaceFilter + HistoryCountSuggestContinueAsNew dynamicconfig.IntPropertyFnWithNamespaceFilter + NumPendingChildExecutionsLimit dynamicconfig.IntPropertyFnWithNamespaceFilter + NumPendingActivitiesLimit dynamicconfig.IntPropertyFnWithNamespaceFilter + NumPendingSignalsLimit dynamicconfig.IntPropertyFnWithNamespaceFilter + NumPendingCancelsRequestLimit dynamicconfig.IntPropertyFnWithNamespaceFilter // DefaultActivityRetryOptions specifies the out-of-box retry policy if // none is configured on the Activity by the user. @@ -417,18 +419,20 @@ func NewConfig(dc *dynamicconfig.Collection, numberOfShards int32, isAdvancedVis ArchiveSignalTimeout: dc.GetDurationProperty(dynamicconfig.ArchiveSignalTimeout, 300*time.Millisecond), DurableArchivalEnabled: dc.GetBoolProperty(dynamicconfig.DurableArchivalEnabled, true), - BlobSizeLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.BlobSizeLimitError, 2*1024*1024), - BlobSizeLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.BlobSizeLimitWarn, 512*1024), - MemoSizeLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.MemoSizeLimitError, 2*1024*1024), - MemoSizeLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.MemoSizeLimitWarn, 2*1024), - NumPendingChildExecutionsLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingChildExecutionsLimitError, 50000), - NumPendingActivitiesLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingActivitiesLimitError, 50000), - NumPendingSignalsLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingSignalsLimitError, 50000), - NumPendingCancelsRequestLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingCancelRequestsLimitError, 50000), - HistorySizeLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistorySizeLimitError, 50*1024*1024), - HistorySizeLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistorySizeLimitWarn, 10*1024*1024), - HistoryCountLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistoryCountLimitError, 50*1024), - HistoryCountLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistoryCountLimitWarn, 10*1024), + BlobSizeLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.BlobSizeLimitError, 2*1024*1024), + BlobSizeLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.BlobSizeLimitWarn, 512*1024), + MemoSizeLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.MemoSizeLimitError, 2*1024*1024), + MemoSizeLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.MemoSizeLimitWarn, 2*1024), + NumPendingChildExecutionsLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingChildExecutionsLimitError, 50000), + NumPendingActivitiesLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingActivitiesLimitError, 50000), + NumPendingSignalsLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingSignalsLimitError, 50000), + NumPendingCancelsRequestLimit: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.NumPendingCancelRequestsLimitError, 50000), + HistorySizeLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistorySizeLimitError, 50*1024*1024), + HistorySizeLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistorySizeLimitWarn, 10*1024*1024), + HistorySizeSuggestContinueAsNew: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistorySizeSuggestContinueAsNew, 4*1024*1024), + HistoryCountLimitError: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistoryCountLimitError, 50*1024), + HistoryCountLimitWarn: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistoryCountLimitWarn, 10*1024), + HistoryCountSuggestContinueAsNew: dc.GetIntPropertyFilteredByNamespace(dynamicconfig.HistoryCountSuggestContinueAsNew, 4*1024), ThrottledLogRPS: dc.GetIntProperty(dynamicconfig.HistoryThrottledLogRPS, 4), EnableStickyQuery: dc.GetBoolPropertyFnWithNamespaceFilter(dynamicconfig.EnableStickyQuery, true), diff --git a/service/history/workflow/history_builder.go b/service/history/workflow/history_builder.go index d2b1cd2d0e5..75ac1924b4e 100644 --- a/service/history/workflow/history_builder.go +++ b/service/history/workflow/history_builder.go @@ -218,13 +218,17 @@ func (b *HistoryBuilder) AddWorkflowTaskStartedEvent( requestID string, identity string, startTime time.Time, + suggestContinueAsNew bool, + historySizeBytes int64, ) *historypb.HistoryEvent { event := b.createNewHistoryEvent(enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED, startTime) event.Attributes = &historypb.HistoryEvent_WorkflowTaskStartedEventAttributes{ WorkflowTaskStartedEventAttributes: &historypb.WorkflowTaskStartedEventAttributes{ - ScheduledEventId: scheduledEventID, - Identity: identity, - RequestId: requestID, + ScheduledEventId: scheduledEventID, + Identity: identity, + RequestId: requestID, + SuggestContinueAsNew: suggestContinueAsNew, + HistorySizeBytes: historySizeBytes, }, } diff --git a/service/history/workflow/history_builder_test.go b/service/history/workflow/history_builder_test.go index 9b72154f290..82dd34c33ec 100644 --- a/service/history/workflow/history_builder_test.go +++ b/service/history/workflow/history_builder_test.go @@ -639,6 +639,8 @@ func (s *historyBuilderSuite) TestWorkflowTaskStarted() { testRequestID, testIdentity, s.now, + false, + 123678, ) s.Equal(event, s.flush()) s.Equal(&historypb.HistoryEvent{ @@ -649,9 +651,11 @@ func (s *historyBuilderSuite) TestWorkflowTaskStarted() { Version: s.version, Attributes: &historypb.HistoryEvent_WorkflowTaskStartedEventAttributes{ WorkflowTaskStartedEventAttributes: &historypb.WorkflowTaskStartedEventAttributes{ - ScheduledEventId: scheduledEventID, - Identity: testIdentity, - RequestId: testRequestID, + ScheduledEventId: scheduledEventID, + Identity: testIdentity, + RequestId: testRequestID, + SuggestContinueAsNew: false, + HistorySizeBytes: 123678, }, }, }, event) diff --git a/service/history/workflow/mutable_state.go b/service/history/workflow/mutable_state.go index ce37620d7be..9cfc0ed73fd 100644 --- a/service/history/workflow/mutable_state.go +++ b/service/history/workflow/mutable_state.go @@ -89,6 +89,13 @@ type ( // Indicate type of the current workflow task (normal, transient, or speculative). Type enumsspb.WorkflowTaskType + + // These two fields are sent to workers in the WorkflowTaskStarted event. We need to save a + // copy here to ensure that we send the same values with every transient WorkflowTaskStarted + // event, otherwise a dynamic config change of the suggestion threshold could cause the + // event that the worker used to not match the event we saved in history. + SuggestContinueAsNew bool + HistorySizeBytes int64 } MutableState interface { @@ -224,7 +231,7 @@ type ( ReplicateWorkflowTaskCompletedEvent(*historypb.HistoryEvent) error ReplicateWorkflowTaskFailedEvent() error ReplicateWorkflowTaskScheduledEvent(int64, int64, *taskqueuepb.TaskQueue, *time.Duration, int32, *time.Time, *time.Time, enumsspb.WorkflowTaskType) (*WorkflowTaskInfo, error) - ReplicateWorkflowTaskStartedEvent(*WorkflowTaskInfo, int64, int64, int64, string, time.Time) (*WorkflowTaskInfo, error) + ReplicateWorkflowTaskStartedEvent(*WorkflowTaskInfo, int64, int64, int64, string, time.Time, bool, int64) (*WorkflowTaskInfo, error) ReplicateWorkflowTaskTimedOutEvent(enumspb.TimeoutType) error ReplicateExternalWorkflowExecutionCancelRequested(*historypb.HistoryEvent) error ReplicateExternalWorkflowExecutionSignaled(*historypb.HistoryEvent) error diff --git a/service/history/workflow/mutable_state_impl.go b/service/history/workflow/mutable_state_impl.go index 505b6a80d58..59a3801f3ae 100644 --- a/service/history/workflow/mutable_state_impl.go +++ b/service/history/workflow/mutable_state_impl.go @@ -1330,6 +1330,10 @@ func (ms *MutableStateImpl) ClearTransientWorkflowTask() error { TaskQueue: nil, OriginalScheduledTime: timestamp.UnixOrZeroTimePtr(0), Type: enumsspb.WORKFLOW_TASK_TYPE_UNSPECIFIED, + + // QUESTION: should we preserve values here? this is called by nDCBranchMgr + SuggestContinueAsNew: false, + HistorySizeBytes: 0, } ms.workflowTaskManager.UpdateWorkflowTask(emptyWorkflowTaskInfo) return nil @@ -1792,9 +1796,11 @@ func (ms *MutableStateImpl) ReplicateWorkflowTaskStartedEvent( startedEventID int64, requestID string, timestamp time.Time, + suggestContinueAsNew bool, + historySizeBytes int64, ) (*WorkflowTaskInfo, error) { - - return ms.workflowTaskManager.ReplicateWorkflowTaskStartedEvent(workflowTask, version, scheduledEventID, startedEventID, requestID, timestamp) + return ms.workflowTaskManager.ReplicateWorkflowTaskStartedEvent(workflowTask, version, scheduledEventID, + startedEventID, requestID, timestamp, suggestContinueAsNew, historySizeBytes) } // TODO (alex-update): Transient needs to be renamed to "TransientOrSpeculative" diff --git a/service/history/workflow/mutable_state_impl_test.go b/service/history/workflow/mutable_state_impl_test.go index 4d89319c48f..411eeb0bd3f 100644 --- a/service/history/workflow/mutable_state_impl_test.go +++ b/service/history/workflow/mutable_state_impl_test.go @@ -597,6 +597,8 @@ func (s *mutableStateSuite) prepareTransientWorkflowTaskCompletionFirstBatchRepl workflowTaskStartedEvent.GetEventId(), workflowTaskStartedEvent.GetWorkflowTaskStartedEventAttributes().GetRequestId(), timestamp.TimeValue(workflowTaskStartedEvent.GetEventTime()), + false, + 123678, ) s.Nil(err) s.NotNil(wt) @@ -649,6 +651,8 @@ func (s *mutableStateSuite) prepareTransientWorkflowTaskCompletionFirstBatchRepl newWorkflowTaskStartedEvent.GetEventId(), newWorkflowTaskStartedEvent.GetWorkflowTaskStartedEventAttributes().GetRequestId(), timestamp.TimeValue(newWorkflowTaskStartedEvent.GetEventTime()), + false, + 123678, ) s.Nil(err) s.NotNil(wt) diff --git a/service/history/workflow/mutable_state_mock.go b/service/history/workflow/mutable_state_mock.go index a3b79ac02e9..4ec7f0edf89 100644 --- a/service/history/workflow/mutable_state_mock.go +++ b/service/history/workflow/mutable_state_mock.go @@ -2359,18 +2359,18 @@ func (mr *MockMutableStateMockRecorder) ReplicateWorkflowTaskScheduledEvent(arg0 } // ReplicateWorkflowTaskStartedEvent mocks base method. -func (m *MockMutableState) ReplicateWorkflowTaskStartedEvent(arg0 *WorkflowTaskInfo, arg1, arg2, arg3 int64, arg4 string, arg5 time.Time) (*WorkflowTaskInfo, error) { +func (m *MockMutableState) ReplicateWorkflowTaskStartedEvent(arg0 *WorkflowTaskInfo, arg1, arg2, arg3 int64, arg4 string, arg5 time.Time, arg6 bool, arg7 int64) (*WorkflowTaskInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReplicateWorkflowTaskStartedEvent", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "ReplicateWorkflowTaskStartedEvent", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) ret0, _ := ret[0].(*WorkflowTaskInfo) ret1, _ := ret[1].(error) return ret0, ret1 } // ReplicateWorkflowTaskStartedEvent indicates an expected call of ReplicateWorkflowTaskStartedEvent. -func (mr *MockMutableStateMockRecorder) ReplicateWorkflowTaskStartedEvent(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockMutableStateMockRecorder) ReplicateWorkflowTaskStartedEvent(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicateWorkflowTaskStartedEvent", reflect.TypeOf((*MockMutableState)(nil).ReplicateWorkflowTaskStartedEvent), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicateWorkflowTaskStartedEvent", reflect.TypeOf((*MockMutableState)(nil).ReplicateWorkflowTaskStartedEvent), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } // ReplicateWorkflowTaskTimedOutEvent mocks base method. diff --git a/service/history/workflow/mutable_state_rebuilder.go b/service/history/workflow/mutable_state_rebuilder.go index 35a56540bda..324b4bc277f 100644 --- a/service/history/workflow/mutable_state_rebuilder.go +++ b/service/history/workflow/mutable_state_rebuilder.go @@ -216,6 +216,8 @@ func (b *MutableStateRebuilderImpl) ApplyEvents( event.GetEventId(), attributes.GetRequestId(), timestamp.TimeValue(event.GetEventTime()), + attributes.GetSuggestContinueAsNew(), + attributes.GetHistorySizeBytes(), ) if err != nil { return nil, err diff --git a/service/history/workflow/mutable_state_rebuilder_test.go b/service/history/workflow/mutable_state_rebuilder_test.go index 8ce0ca2d15b..94ca92206d8 100644 --- a/service/history/workflow/mutable_state_rebuilder_test.go +++ b/service/history/workflow/mutable_state_rebuilder_test.go @@ -808,6 +808,7 @@ func (s *stateBuilderSuite) TestApplyEvents_EventTypeWorkflowTaskStarted() { } s.mockMutableState.EXPECT().ReplicateWorkflowTaskStartedEvent( (*WorkflowTaskInfo)(nil), event.GetVersion(), scheduledEventID, event.GetEventId(), workflowTaskRequestID, timestamp.TimeValue(event.GetEventTime()), + false, gomock.Any(), ).Return(wt, nil) s.mockUpdateVersion(event) s.mockTaskGenerator.EXPECT().GenerateStartWorkflowTaskTasks( diff --git a/service/history/workflow/workflow_task_state_machine.go b/service/history/workflow/workflow_task_state_machine.go index 8ddef66043f..d353c80c1de 100644 --- a/service/history/workflow/workflow_task_state_machine.go +++ b/service/history/workflow/workflow_task_state_machine.go @@ -104,6 +104,9 @@ func (m *workflowTaskStateMachine) ReplicateWorkflowTaskScheduledEvent( StartedTime: nil, OriginalScheduledTime: originalScheduledTimestamp, Type: workflowTaskType, + // preserve these across attempts: + SuggestContinueAsNew: m.ms.executionInfo.WorkflowTaskSuggestContinueAsNew, + HistorySizeBytes: m.ms.executionInfo.WorkflowTaskHistorySizeBytes, } m.UpdateWorkflowTask(workflowTask) @@ -147,6 +150,11 @@ func (m *workflowTaskStateMachine) ReplicateTransientWorkflowTaskScheduled() (*W ScheduledTime: timestamp.TimePtr(m.ms.timeSource.Now()), StartedTime: timestamp.UnixOrZeroTimePtr(0), Type: enumsspb.WORKFLOW_TASK_TYPE_NORMAL, + // QUESTION: should we preserve these here? this is used by mutable state rebuilder. it + // seems like the same logic as case 1 above applies: if a failover happens right after + // this, then AddWorkflowTaskStartedEvent will rewrite these anyway. is that correct? + SuggestContinueAsNew: false, + HistorySizeBytes: 0, } m.UpdateWorkflowTask(workflowTask) @@ -160,6 +168,8 @@ func (m *workflowTaskStateMachine) ReplicateWorkflowTaskStartedEvent( startedEventID int64, requestID string, timestamp time.Time, + suggestContinueAsNew bool, + historySizeBytes int64, ) (*WorkflowTaskInfo, error) { // When this function is called from ApplyEvents, workflowTask is nil. // It is safe to look up the workflow task as it does not have to deal with transient workflow task case. @@ -196,6 +206,8 @@ func (m *workflowTaskStateMachine) ReplicateWorkflowTaskStartedEvent( TaskQueue: workflowTask.TaskQueue, OriginalScheduledTime: workflowTask.OriginalScheduledTime, Type: workflowTask.Type, + SuggestContinueAsNew: suggestContinueAsNew, + HistorySizeBytes: historySizeBytes, } m.UpdateWorkflowTask(workflowTask) @@ -239,9 +251,6 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskScheduleToStartTimeoutEvent( return nil, m.ms.createInternalServerError(opTag) } - // clear stickiness whenever workflow task fails - m.ms.ClearStickyness() - event := m.ms.hBuilder.AddWorkflowTaskTimedOutEvent( scheduledEventID, common.EmptyEventID, @@ -441,17 +450,24 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskStartedEvent( // (it wasn't created for transient/speculative WT). var startedEvent *historypb.HistoryEvent if workflowTaskScheduledEventCreated { + workflowTask.SuggestContinueAsNew, workflowTask.HistorySizeBytes = m.getHistorySizeInfo() + startedEvent = m.ms.hBuilder.AddWorkflowTaskStartedEvent( scheduledEventID, requestID, identity, startTime, + workflowTask.SuggestContinueAsNew, + workflowTask.HistorySizeBytes, ) m.ms.hBuilder.FlushAndCreateNewBatch() startedEventID = startedEvent.GetEventId() } - workflowTask, err := m.ReplicateWorkflowTaskStartedEvent(workflowTask, m.ms.GetCurrentVersion(), scheduledEventID, startedEventID, requestID, startTime) + workflowTask, err := m.ReplicateWorkflowTaskStartedEvent( + workflowTask, m.ms.GetCurrentVersion(), scheduledEventID, startedEventID, requestID, startTime, + workflowTask.SuggestContinueAsNew, workflowTask.HistorySizeBytes, + ) m.emitWorkflowTaskAttemptStats(workflowTask.Attempt) @@ -510,6 +526,8 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskCompletedEvent( workflowTask.RequestID, request.GetIdentity(), timestamp.TimeValue(workflowTask.StartedTime), + workflowTask.SuggestContinueAsNew, + workflowTask.HistorySizeBytes, ) m.ms.hBuilder.FlushAndCreateNewBatch() workflowTask.StartedEventID = startedEvent.GetEventId() @@ -554,6 +572,8 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskFailedEvent( workflowTask.RequestID, identity, timestamp.TimeValue(workflowTask.StartedTime), + workflowTask.SuggestContinueAsNew, + workflowTask.HistorySizeBytes, ) // TODO (alex-update): Do we need to call next line here same as in AddWorkflowTaskCompletedEvent? m.ms.hBuilder.FlushAndCreateNewBatch() @@ -630,6 +650,9 @@ func (m *workflowTaskStateMachine) FailWorkflowTask( OriginalScheduledTime: timestamp.UnixOrZeroTimePtr(0), Attempt: 1, Type: enumsspb.WORKFLOW_TASK_TYPE_UNSPECIFIED, + // preserve these across attempts: + SuggestContinueAsNew: m.ms.executionInfo.WorkflowTaskSuggestContinueAsNew, + HistorySizeBytes: m.ms.executionInfo.WorkflowTaskHistorySizeBytes, } if incrementAttempt { failWorkflowTaskInfo.Attempt = m.ms.executionInfo.WorkflowTaskAttempt + 1 @@ -654,6 +677,8 @@ func (m *workflowTaskStateMachine) DeleteWorkflowTask() { // Keep the last original scheduled Timestamp, so that AddWorkflowTaskScheduledEventAsHeartbeat can continue with it. OriginalScheduledTime: m.getWorkflowTaskInfo().OriginalScheduledTime, Type: enumsspb.WORKFLOW_TASK_TYPE_UNSPECIFIED, + SuggestContinueAsNew: false, + HistorySizeBytes: 0, } m.UpdateWorkflowTask(resetWorkflowTaskInfo) } @@ -672,6 +697,8 @@ func (m *workflowTaskStateMachine) UpdateWorkflowTask( m.ms.executionInfo.WorkflowTaskScheduledTime = workflowTask.ScheduledTime m.ms.executionInfo.WorkflowTaskOriginalScheduledTime = workflowTask.OriginalScheduledTime m.ms.executionInfo.WorkflowTaskType = workflowTask.Type + m.ms.executionInfo.WorkflowTaskSuggestContinueAsNew = workflowTask.SuggestContinueAsNew + m.ms.executionInfo.WorkflowTaskHistorySizeBytes = workflowTask.HistorySizeBytes // NOTE: do not update task queue in execution info @@ -803,9 +830,11 @@ func (m *workflowTaskStateMachine) GetTransientWorkflowTaskInfo( Version: m.ms.currentVersion, Attributes: &historypb.HistoryEvent_WorkflowTaskStartedEventAttributes{ WorkflowTaskStartedEventAttributes: &historypb.WorkflowTaskStartedEventAttributes{ - ScheduledEventId: workflowTask.ScheduledEventID, - Identity: identity, - RequestId: workflowTask.RequestID, + ScheduledEventId: workflowTask.ScheduledEventID, + Identity: identity, + RequestId: workflowTask.RequestID, + SuggestContinueAsNew: workflowTask.SuggestContinueAsNew, + HistorySizeBytes: workflowTask.HistorySizeBytes, }, }, } @@ -828,6 +857,8 @@ func (m *workflowTaskStateMachine) getWorkflowTaskInfo() *WorkflowTaskInfo { TaskQueue: m.ms.TaskQueue(), OriginalScheduledTime: m.ms.executionInfo.WorkflowTaskOriginalScheduledTime, Type: m.ms.executionInfo.WorkflowTaskType, + SuggestContinueAsNew: m.ms.executionInfo.WorkflowTaskSuggestContinueAsNew, + HistorySizeBytes: m.ms.executionInfo.WorkflowTaskHistorySizeBytes, } } @@ -885,3 +916,22 @@ func (m *workflowTaskStateMachine) getStartToCloseTimeout( startToCloseTimeout := *defaultTimeout + policy.ComputeNextDelay(0, int(attempt)-workflowTaskRetryBackoffMinAttempts) return &startToCloseTimeout } + +func (m *workflowTaskStateMachine) getHistorySizeInfo() (bool, int64) { + stats := m.ms.GetExecutionInfo().ExecutionStats + if stats == nil { + return false, 0 + } + // QUESTION: in some cases we might have history events in memory that we haven't written + // out yet, so they won't show up here. should we try to include them? + historySize := stats.HistorySize + // This is called right before AddWorkflowTaskStartedEvent, so at this point, nextEventID + // is the ID of the workflow task started event. + historyCount := m.ms.GetNextEventID() + config := m.ms.shard.GetConfig() + namespaceName := m.ms.GetNamespaceEntry().Name().String() + sizeLimit := int64(config.HistorySizeSuggestContinueAsNew(namespaceName)) + countLimit := int64(config.HistoryCountSuggestContinueAsNew(namespaceName)) + suggestContinueAsNew := historySize >= sizeLimit || historyCount >= countLimit + return suggestContinueAsNew, historySize +} diff --git a/tests/transient_task_test.go b/tests/transient_task_test.go index 64a6e044e21..8aea75ca66c 100644 --- a/tests/transient_task_test.go +++ b/tests/transient_task_test.go @@ -37,6 +37,7 @@ import ( taskqueuepb "go.temporal.io/api/taskqueue/v1" "go.temporal.io/api/workflowservice/v1" + "go.temporal.io/server/common/dynamicconfig" "go.temporal.io/server/common/log/tag" "go.temporal.io/server/common/payloads" "go.temporal.io/server/common/primitives/timestamp" @@ -132,6 +133,167 @@ func (s *integrationSuite) TestTransientWorkflowTaskTimeout() { s.True(workflowComplete) } +func (s *integrationSuite) TestTransientWorkflowTaskHistorySize() { + id := "integration-transient-workflow-task-history-size-test" + wt := "integration-transient-workflow-task-history-size-test-type" + tl := "integration-transient-workflow-task-history-size-test-taskqueue" + identity := "worker1" + + // Start workflow execution + request := &workflowservice.StartWorkflowExecutionRequest{ + RequestId: uuid.New(), + Namespace: s.namespace, + WorkflowId: id, + WorkflowType: &commonpb.WorkflowType{Name: wt}, + TaskQueue: &taskqueuepb.TaskQueue{Name: tl}, + Input: nil, + WorkflowRunTimeout: timestamp.DurationPtr(100 * time.Second), + WorkflowTaskTimeout: timestamp.DurationPtr(2 * time.Second), + Identity: identity, + } + + we, err0 := s.engine.StartWorkflowExecution(NewContext(), request) + s.NoError(err0) + s.Logger.Info("StartWorkflowExecution", tag.WorkflowRunID(we.RunId)) + + workflowExecution := &commonpb.WorkflowExecution{ + WorkflowId: id, + RunId: we.RunId, + } + + // start with 2mb limit + s.testCluster.host.dcClient.OverrideValue(dynamicconfig.HistorySizeSuggestContinueAsNew, 2*1024*1024) + + // workflow logic + stage := 0 + workflowComplete := false + largeValue := make([]byte, 1024*1024) + var sawHistorySize int64 + wtHandler := func(execution *commonpb.WorkflowExecution, wt *commonpb.WorkflowType, + previousStartedEventID, startedEventID int64, history *historypb.History) ([]*commandpb.Command, error) { + + // find workflow task started event + event := history.Events[len(history.Events)-1] + s.Equal(event.GetEventType(), enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED) + attrs := event.GetWorkflowTaskStartedEventAttributes() + s.Logger.Info("wtHandler", tag.Counter(stage)) + + stage++ + switch stage { + case 1: + s.Less(attrs.HistorySizeBytes, int64(1024*1024)) + s.False(attrs.SuggestContinueAsNew) + // record a large marker + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_RECORD_MARKER, + Attributes: &commandpb.Command_RecordMarkerCommandAttributes{RecordMarkerCommandAttributes: &commandpb.RecordMarkerCommandAttributes{ + MarkerName: "big marker", + Details: map[string]*commonpb.Payloads{"value": payloads.EncodeBytes(largeValue)}, + }}, + }}, nil + + case 2: + s.Greater(attrs.HistorySizeBytes, int64(1024*1024)) + s.False(attrs.SuggestContinueAsNew) + // record another large marker + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_RECORD_MARKER, + Attributes: &commandpb.Command_RecordMarkerCommandAttributes{RecordMarkerCommandAttributes: &commandpb.RecordMarkerCommandAttributes{ + MarkerName: "big marker", + Details: map[string]*commonpb.Payloads{"value": payloads.EncodeBytes(largeValue)}, + }}, + }}, nil + + case 3: + s.Greater(attrs.HistorySizeBytes, int64(2048*1024)) + s.True(attrs.SuggestContinueAsNew) + sawHistorySize = attrs.HistorySizeBytes + // fail workflow task and we'll get a transient one + return nil, errors.New("oops") + + case 4: + // we should get the exact same value + s.Equal(sawHistorySize, attrs.HistorySizeBytes) + s.True(attrs.SuggestContinueAsNew) + + workflowComplete = true + return nil, nil + + case 5: + // we should get just a little larger + s.Greater(attrs.HistorySizeBytes, sawHistorySize) + s.Less(attrs.HistorySizeBytes, sawHistorySize+10000) + s.False(attrs.SuggestContinueAsNew) // now false + + workflowComplete = true + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{ + Result: payloads.EncodeString("done"), + }}, + }}, nil + } + + return nil, errors.New("bad stage") + } + + poller := &TaskPoller{ + Engine: s.engine, + Namespace: s.namespace, + TaskQueue: &taskqueuepb.TaskQueue{Name: tl}, + Identity: identity, + WorkflowTaskHandler: wtHandler, + ActivityTaskHandler: nil, + Logger: s.Logger, + T: s.T(), + } + + // stage 1 + _, err := poller.PollAndProcessWorkflowTask(false, false) + s.Logger.Info("PollAndProcessWorkflowTask", tag.Error(err)) + s.NoError(err) + + err = s.sendSignal(s.namespace, workflowExecution, "signal", nil, identity) + s.NoError(err, "failed to send signal to execution") + + // stage 2 + _, err = poller.PollAndProcessWorkflowTask(false, false) + s.Logger.Info("PollAndProcessWorkflowTask", tag.Error(err)) + s.NoError(err) + + err = s.sendSignal(s.namespace, workflowExecution, "signal", nil, identity) + s.NoError(err, "failed to send signal to execution") + + // stage 3: this one fails with a panic + _, err = poller.PollAndProcessWorkflowTask(false, false) + s.Logger.Info("PollAndProcessWorkflowTask", tag.Error(err)) + s.NoError(err) + + // change the dynamic config so that SuggestContinueAsNew should now be false. the current + // workflow task should still see true, but the next one will see false. + s.testCluster.host.dcClient.OverrideValue(dynamicconfig.HistorySizeSuggestContinueAsNew, 8*1024*1024) + + // stage 4 + _, err = poller.PollAndProcessWorkflowTask(false, false) + s.Logger.Info("PollAndProcessWorkflowTask", tag.Error(err)) + s.NoError(err) + + err = s.sendSignal(s.namespace, workflowExecution, "signal", nil, identity) + s.NoError(err, "failed to send signal to execution") + + // drop workflow task to cause a workflow task timeout + _, err = poller.PollAndProcessWorkflowTask(true, true) + s.Logger.Info("PollAndProcessWorkflowTask", tag.Error(err)) + s.NoError(err) + + // stage 5 + _, err = poller.PollAndProcessWorkflowTask(false, false) + s.Logger.Info("PollAndProcessWorkflowTask", tag.Error(err)) + s.NoError(err) + + s.True(workflowComplete) +} + func (s *integrationSuite) TestNoTransientWorkflowTaskAfterFlushBufferedEvents() { id := "integration-no-transient-workflow-task-after-flush-buffered-events-test" wt := "integration-no-transient-workflow-task-after-flush-buffered-events-test-type" From 6d352603b496ef74c827c38e6326976e9c6a6e97 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Wed, 8 Feb 2023 22:30:52 -0800 Subject: [PATCH 2/4] simplify logic slightly, recompute on every attempt --- .../history/workflow/mutable_state_impl.go | 1 - .../workflow/workflow_task_state_machine.go | 47 ++++++++++--------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/service/history/workflow/mutable_state_impl.go b/service/history/workflow/mutable_state_impl.go index 59a3801f3ae..eaa3eb02aee 100644 --- a/service/history/workflow/mutable_state_impl.go +++ b/service/history/workflow/mutable_state_impl.go @@ -1331,7 +1331,6 @@ func (ms *MutableStateImpl) ClearTransientWorkflowTask() error { OriginalScheduledTime: timestamp.UnixOrZeroTimePtr(0), Type: enumsspb.WORKFLOW_TASK_TYPE_UNSPECIFIED, - // QUESTION: should we preserve values here? this is called by nDCBranchMgr SuggestContinueAsNew: false, HistorySizeBytes: 0, } diff --git a/service/history/workflow/workflow_task_state_machine.go b/service/history/workflow/workflow_task_state_machine.go index d353c80c1de..ce288f343d4 100644 --- a/service/history/workflow/workflow_task_state_machine.go +++ b/service/history/workflow/workflow_task_state_machine.go @@ -104,9 +104,8 @@ func (m *workflowTaskStateMachine) ReplicateWorkflowTaskScheduledEvent( StartedTime: nil, OriginalScheduledTime: originalScheduledTimestamp, Type: workflowTaskType, - // preserve these across attempts: - SuggestContinueAsNew: m.ms.executionInfo.WorkflowTaskSuggestContinueAsNew, - HistorySizeBytes: m.ms.executionInfo.WorkflowTaskHistorySizeBytes, + SuggestContinueAsNew: false, // reset, will be recomputed on workflow task started + HistorySizeBytes: 0, // reset, will be recomputed on workflow task started } m.UpdateWorkflowTask(workflowTask) @@ -145,16 +144,13 @@ func (m *workflowTaskStateMachine) ReplicateTransientWorkflowTaskScheduled() (*W WorkflowTaskTimeout: m.ms.GetExecutionInfo().DefaultWorkflowTaskTimeout, // Task queue is always of kind NORMAL because transient workflow task is created only for // failed/timed out workflow task and fail/timeout clears stickiness. - TaskQueue: m.ms.TaskQueue(), - Attempt: m.ms.GetExecutionInfo().WorkflowTaskAttempt, - ScheduledTime: timestamp.TimePtr(m.ms.timeSource.Now()), - StartedTime: timestamp.UnixOrZeroTimePtr(0), - Type: enumsspb.WORKFLOW_TASK_TYPE_NORMAL, - // QUESTION: should we preserve these here? this is used by mutable state rebuilder. it - // seems like the same logic as case 1 above applies: if a failover happens right after - // this, then AddWorkflowTaskStartedEvent will rewrite these anyway. is that correct? - SuggestContinueAsNew: false, - HistorySizeBytes: 0, + TaskQueue: m.ms.TaskQueue(), + Attempt: m.ms.GetExecutionInfo().WorkflowTaskAttempt, + ScheduledTime: timestamp.TimePtr(m.ms.timeSource.Now()), + StartedTime: timestamp.UnixOrZeroTimePtr(0), + Type: enumsspb.WORKFLOW_TASK_TYPE_NORMAL, + SuggestContinueAsNew: false, // reset, will be recomputed on workflow task started + HistorySizeBytes: 0, // reset, will be recomputed on workflow task started } m.UpdateWorkflowTask(workflowTask) @@ -425,6 +421,13 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskStartedEvent( scheduledEventID = workflowTask.ScheduledEventID startedEventID := scheduledEventID + 1 startTime := m.ms.timeSource.Now() + + // The history size computed here might not include this workflow task scheduled or started + // events. That's okay, it doesn't have to be 100% accurate. It just has to be kept + // consistent between the started event in history and the event that was sent to the SDK + // that resulted in the successful completion. + suggestContinueAsNew, historySizeBytes := m.getHistorySizeInfo() + workflowTaskScheduledEventCreated := !m.ms.IsTransientWorkflowTask() && workflowTask.Type != enumsspb.WORKFLOW_TASK_TYPE_SPECULATIVE // If new events came since transient/speculative WT was scheduled @@ -450,15 +453,13 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskStartedEvent( // (it wasn't created for transient/speculative WT). var startedEvent *historypb.HistoryEvent if workflowTaskScheduledEventCreated { - workflowTask.SuggestContinueAsNew, workflowTask.HistorySizeBytes = m.getHistorySizeInfo() - startedEvent = m.ms.hBuilder.AddWorkflowTaskStartedEvent( scheduledEventID, requestID, identity, startTime, - workflowTask.SuggestContinueAsNew, - workflowTask.HistorySizeBytes, + suggestContinueAsNew, + historySizeBytes, ) m.ms.hBuilder.FlushAndCreateNewBatch() startedEventID = startedEvent.GetEventId() @@ -466,7 +467,7 @@ func (m *workflowTaskStateMachine) AddWorkflowTaskStartedEvent( workflowTask, err := m.ReplicateWorkflowTaskStartedEvent( workflowTask, m.ms.GetCurrentVersion(), scheduledEventID, startedEventID, requestID, startTime, - workflowTask.SuggestContinueAsNew, workflowTask.HistorySizeBytes, + suggestContinueAsNew, historySizeBytes, ) m.emitWorkflowTaskAttemptStats(workflowTask.Attempt) @@ -650,9 +651,8 @@ func (m *workflowTaskStateMachine) FailWorkflowTask( OriginalScheduledTime: timestamp.UnixOrZeroTimePtr(0), Attempt: 1, Type: enumsspb.WORKFLOW_TASK_TYPE_UNSPECIFIED, - // preserve these across attempts: - SuggestContinueAsNew: m.ms.executionInfo.WorkflowTaskSuggestContinueAsNew, - HistorySizeBytes: m.ms.executionInfo.WorkflowTaskHistorySizeBytes, + SuggestContinueAsNew: false, + HistorySizeBytes: 0, } if incrementAttempt { failWorkflowTaskInfo.Attempt = m.ms.executionInfo.WorkflowTaskAttempt + 1 @@ -922,8 +922,9 @@ func (m *workflowTaskStateMachine) getHistorySizeInfo() (bool, int64) { if stats == nil { return false, 0 } - // QUESTION: in some cases we might have history events in memory that we haven't written - // out yet, so they won't show up here. should we try to include them? + // This only includes events that have actually been written to persistence, so it won't + // include the workflow task started event that we're currently writing. That's okay, it + // doesn't have to be 100% accurate. historySize := stats.HistorySize // This is called right before AddWorkflowTaskStartedEvent, so at this point, nextEventID // is the ID of the workflow task started event. From 40e1e430ad42a86f9440ff0c9db954a02668500a Mon Sep 17 00:00:00 2001 From: David Reiss Date: Wed, 8 Feb 2023 22:44:02 -0800 Subject: [PATCH 3/4] comment --- service/history/workflow/mutable_state.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/service/history/workflow/mutable_state.go b/service/history/workflow/mutable_state.go index 9cfc0ed73fd..ae4b1ec8792 100644 --- a/service/history/workflow/mutable_state.go +++ b/service/history/workflow/mutable_state.go @@ -91,9 +91,10 @@ type ( Type enumsspb.WorkflowTaskType // These two fields are sent to workers in the WorkflowTaskStarted event. We need to save a - // copy here to ensure that we send the same values with every transient WorkflowTaskStarted - // event, otherwise a dynamic config change of the suggestion threshold could cause the - // event that the worker used to not match the event we saved in history. + // copy in mutable state to know the last values we sent (which might have been in a + // transient event), otherwise a dynamic config change of the suggestion threshold could + // cause the WorkflowTaskStarted event that the worker used to not match the event we saved + // in history. SuggestContinueAsNew bool HistorySizeBytes int64 } From 61b74a8159ed045f7c4f6b0122e3a94146e953d0 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Wed, 8 Feb 2023 23:56:06 -0800 Subject: [PATCH 4/4] rearrange test to work with recompute per attempt, and check history --- tests/transient_task_test.go | 49 +++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/tests/transient_task_test.go b/tests/transient_task_test.go index 8aea75ca66c..da41317e2e6 100644 --- a/tests/transient_task_test.go +++ b/tests/transient_task_test.go @@ -168,7 +168,14 @@ func (s *integrationSuite) TestTransientWorkflowTaskHistorySize() { stage := 0 workflowComplete := false largeValue := make([]byte, 1024*1024) - var sawHistorySize int64 + // record the values that we see for completed tasks here + type fields struct { + size int64 + suggest bool + } + var sawFields []fields + // record value for failed wft + var failedTaskSawSize int64 wtHandler := func(execution *commonpb.WorkflowExecution, wt *commonpb.WorkflowType, previousStartedEventID, startedEventID int64, history *historypb.History) ([]*commandpb.Command, error) { @@ -184,6 +191,7 @@ func (s *integrationSuite) TestTransientWorkflowTaskHistorySize() { s.Less(attrs.HistorySizeBytes, int64(1024*1024)) s.False(attrs.SuggestContinueAsNew) // record a large marker + sawFields = append(sawFields, fields{size: attrs.HistorySizeBytes, suggest: attrs.SuggestContinueAsNew}) return []*commandpb.Command{{ CommandType: enumspb.COMMAND_TYPE_RECORD_MARKER, Attributes: &commandpb.Command_RecordMarkerCommandAttributes{RecordMarkerCommandAttributes: &commandpb.RecordMarkerCommandAttributes{ @@ -196,6 +204,7 @@ func (s *integrationSuite) TestTransientWorkflowTaskHistorySize() { s.Greater(attrs.HistorySizeBytes, int64(1024*1024)) s.False(attrs.SuggestContinueAsNew) // record another large marker + sawFields = append(sawFields, fields{size: attrs.HistorySizeBytes, suggest: attrs.SuggestContinueAsNew}) return []*commandpb.Command{{ CommandType: enumspb.COMMAND_TYPE_RECORD_MARKER, Attributes: &commandpb.Command_RecordMarkerCommandAttributes{RecordMarkerCommandAttributes: &commandpb.RecordMarkerCommandAttributes{ @@ -207,25 +216,27 @@ func (s *integrationSuite) TestTransientWorkflowTaskHistorySize() { case 3: s.Greater(attrs.HistorySizeBytes, int64(2048*1024)) s.True(attrs.SuggestContinueAsNew) - sawHistorySize = attrs.HistorySizeBytes + failedTaskSawSize = attrs.HistorySizeBytes // fail workflow task and we'll get a transient one return nil, errors.New("oops") case 4: - // we should get the exact same value - s.Equal(sawHistorySize, attrs.HistorySizeBytes) - s.True(attrs.SuggestContinueAsNew) - - workflowComplete = true + // we might not get the same value but it shouldn't be smaller, and not too much larger + s.GreaterOrEqual(attrs.HistorySizeBytes, failedTaskSawSize) + s.Less(attrs.HistorySizeBytes, failedTaskSawSize+10000) + s.False(attrs.SuggestContinueAsNew) + sawFields = append(sawFields, fields{size: attrs.HistorySizeBytes, suggest: attrs.SuggestContinueAsNew}) return nil, nil case 5: // we should get just a little larger - s.Greater(attrs.HistorySizeBytes, sawHistorySize) - s.Less(attrs.HistorySizeBytes, sawHistorySize+10000) + prevSize := sawFields[len(sawFields)-1].size + s.Greater(attrs.HistorySizeBytes, prevSize) + s.Less(attrs.HistorySizeBytes, prevSize+10000) s.False(attrs.SuggestContinueAsNew) // now false workflowComplete = true + sawFields = append(sawFields, fields{size: attrs.HistorySizeBytes, suggest: attrs.SuggestContinueAsNew}) return []*commandpb.Command{{ CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION, Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{ @@ -292,6 +303,26 @@ func (s *integrationSuite) TestTransientWorkflowTaskHistorySize() { s.NoError(err) s.True(workflowComplete) + + // check history + // we should have 4 workflow task completed events + allEvents := s.getHistory(s.namespace, workflowExecution) + var completedEvents []*historypb.HistoryEvent + for _, event := range allEvents { + if event.EventType == enumspb.EVENT_TYPE_WORKFLOW_TASK_COMPLETED { + completedEvents = append(completedEvents, event) + } + } + s.Equal(4, len(completedEvents)) + for i, event := range completedEvents { + // find the corresponding started event, and make sure it matches the values we + // recorded in the workflow + completedAttrs := event.GetWorkflowTaskCompletedEventAttributes() + startedEvent := allEvents[completedAttrs.StartedEventId-1] + startedAttrs := startedEvent.GetWorkflowTaskStartedEventAttributes() + s.Equal(sawFields[i].size, startedAttrs.HistorySizeBytes) + s.Equal(sawFields[i].suggest, startedAttrs.SuggestContinueAsNew) + } } func (s *integrationSuite) TestNoTransientWorkflowTaskAfterFlushBufferedEvents() {