Refactor to use new protos and persistence (#4194)

Note: This commit came from a feature branch and is not expected to build.
This commit is contained in:
Roey Berman
2023-04-21 16:15:19 -07:00
committed by David Reiss
parent c2fdc9f2b8
commit 0a9785a15a
56 changed files with 4124 additions and 1521 deletions

View File

@@ -108,8 +108,76 @@ func (m *VectorClock) GetClusterId() int64 {
return 0
}
// A Hybrid Logical Clock timestamp.
// Guarantees strict total ordering for conflict resolution purposes.
type HybridLogicalClock struct {
// Wall clock - A single time source MUST guarantee that 2 consecutive timestamps are monotonically non-decreasing.
// e.g. by storing the last wall clock and returning max(gettimeofday(), lastWallClock).
WallClock int64 `protobuf:"varint,1,opt,name=wall_clock,json=wallClock,proto3" json:"wall_clock,omitempty"`
// Incremental sequence that is reset every time the system's wallclock moves forward.
// Ensures the clock generates monotonically increasing timestamps.
Version int32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
// The cluster version ID as described in the XDC docs - used as a tie breaker.
// See: https://github.com/uber/cadence/blob/master/docs/design/2290-cadence-ndc.md
ClusterId int64 `protobuf:"varint,3,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"`
}
func (m *HybridLogicalClock) Reset() { *m = HybridLogicalClock{} }
func (*HybridLogicalClock) ProtoMessage() {}
func (*HybridLogicalClock) Descriptor() ([]byte, []int) {
return fileDescriptor_86d20c4676353367, []int{1}
}
func (m *HybridLogicalClock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *HybridLogicalClock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_HybridLogicalClock.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *HybridLogicalClock) XXX_Merge(src proto.Message) {
xxx_messageInfo_HybridLogicalClock.Merge(m, src)
}
func (m *HybridLogicalClock) XXX_Size() int {
return m.Size()
}
func (m *HybridLogicalClock) XXX_DiscardUnknown() {
xxx_messageInfo_HybridLogicalClock.DiscardUnknown(m)
}
var xxx_messageInfo_HybridLogicalClock proto.InternalMessageInfo
func (m *HybridLogicalClock) GetWallClock() int64 {
if m != nil {
return m.WallClock
}
return 0
}
func (m *HybridLogicalClock) GetVersion() int32 {
if m != nil {
return m.Version
}
return 0
}
func (m *HybridLogicalClock) GetClusterId() int64 {
if m != nil {
return m.ClusterId
}
return 0
}
func init() {
proto.RegisterType((*VectorClock)(nil), "temporal.server.api.clock.v1.VectorClock")
proto.RegisterType((*HybridLogicalClock)(nil), "temporal.server.api.clock.v1.HybridLogicalClock")
}
func init() {
@@ -117,22 +185,25 @@ func init() {
}
var fileDescriptor_86d20c4676353367 = []byte{
// 234 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2a, 0x49, 0xcd, 0x2d,
0xc8, 0x2f, 0x4a, 0xcc, 0xd1, 0x2f, 0x4e, 0x2d, 0x2a, 0x4b, 0x2d, 0xd2, 0x4f, 0x2c, 0xc8, 0xd4,
0x4f, 0xce, 0xc9, 0x4f, 0xce, 0xd6, 0x2f, 0x33, 0xd4, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f,
0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x81, 0xa9, 0xd5, 0x83, 0xa8, 0xd5, 0x4b, 0x2c,
0xc8, 0xd4, 0x03, 0xab, 0xd5, 0x2b, 0x33, 0x54, 0x8a, 0xe5, 0xe2, 0x0e, 0x4b, 0x4d, 0x2e, 0xc9,
0x2f, 0x72, 0x06, 0x89, 0x08, 0x49, 0x72, 0x71, 0x14, 0x67, 0x24, 0x16, 0xa5, 0xc4, 0x67, 0xa6,
0x48, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x06, 0xb1, 0x83, 0xf9, 0x9e, 0x29, 0x42, 0x22, 0x5c, 0xac,
0x60, 0x5d, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x10, 0x8e, 0x90, 0x2c, 0x17, 0x57, 0x72,
0x4e, 0x69, 0x71, 0x49, 0x6a, 0x11, 0x48, 0x0b, 0x33, 0x58, 0x8a, 0x13, 0x2a, 0xe2, 0x99, 0xe2,
0x14, 0x77, 0xe1, 0xa1, 0x1c, 0xc3, 0x8d, 0x87, 0x72, 0x0c, 0x1f, 0x1e, 0xca, 0x31, 0x36, 0x3c,
0x92, 0x63, 0x5c, 0xf1, 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f,
0x3c, 0x92, 0x63, 0x7c, 0xf1, 0x48, 0x8e, 0xe1, 0xc3, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18,
0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, 0x23, 0x3d, 0x5f, 0x0f, 0xee, 0xea,
0xcc, 0x7c, 0x6c, 0x9e, 0xb4, 0x06, 0x33, 0x92, 0xd8, 0xc0, 0x7e, 0x34, 0x06, 0x04, 0x00, 0x00,
0xff, 0xff, 0xc4, 0x11, 0xe0, 0xe1, 0x11, 0x01, 0x00, 0x00,
// 284 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0xb1, 0x4e, 0xc3, 0x30,
0x18, 0x84, 0xfd, 0x53, 0x95, 0x82, 0xd9, 0x22, 0x86, 0x22, 0xc1, 0xaf, 0xaa, 0x53, 0xc4, 0xe0,
0xa8, 0x62, 0x64, 0xa3, 0x0b, 0x95, 0x98, 0x32, 0x30, 0x20, 0x41, 0xe5, 0x26, 0x56, 0xb0, 0x70,
0x71, 0x64, 0x87, 0x20, 0x36, 0x1e, 0x81, 0xc7, 0xe0, 0x51, 0x18, 0x33, 0x76, 0x24, 0xce, 0xc2,
0xd8, 0x47, 0x40, 0x71, 0x08, 0x13, 0x12, 0x9b, 0xef, 0xfe, 0xfb, 0x7c, 0xd2, 0xd1, 0xd3, 0x42,
0xac, 0x73, 0x6d, 0xb8, 0x8a, 0xac, 0x30, 0xa5, 0x30, 0x11, 0xcf, 0x65, 0x94, 0x28, 0x9d, 0x3c,
0x44, 0xe5, 0x2c, 0x5a, 0x0b, 0x6b, 0x79, 0x26, 0x58, 0x6e, 0x74, 0xa1, 0x83, 0xe3, 0x3e, 0xcb,
0xba, 0x2c, 0xe3, 0xb9, 0x64, 0x3e, 0xcb, 0xca, 0xd9, 0xf4, 0x96, 0x1e, 0x5c, 0x8b, 0xa4, 0xd0,
0x66, 0xde, 0x3a, 0xc1, 0x11, 0xdd, 0xb3, 0xf7, 0xdc, 0xa4, 0x4b, 0x99, 0x8e, 0x61, 0x02, 0xe1,
0x30, 0x1e, 0x79, 0xbd, 0x48, 0x83, 0x43, 0x3a, 0xf4, 0xd4, 0x78, 0x67, 0x02, 0xe1, 0x20, 0xee,
0x44, 0x70, 0x42, 0x69, 0xa2, 0x9e, 0x6c, 0x21, 0x4c, 0x8b, 0x0c, 0xfc, 0x69, 0xff, 0xc7, 0x59,
0xa4, 0x53, 0x45, 0x83, 0xcb, 0x97, 0x95, 0x91, 0xe9, 0x95, 0xce, 0x64, 0xc2, 0xd5, 0xbc, 0x87,
0x9e, 0xb9, 0x52, 0xcb, 0xee, 0x3f, 0xe8, 0xa0, 0xd6, 0xe9, 0xce, 0x63, 0x3a, 0x2a, 0x85, 0xb1,
0x52, 0x3f, 0xfa, 0xae, 0x61, 0xdc, 0xcb, 0x7f, 0xda, 0x2e, 0xee, 0xaa, 0x1a, 0xc9, 0xa6, 0x46,
0xb2, 0xad, 0x11, 0x5e, 0x1d, 0xc2, 0xbb, 0x43, 0xf8, 0x70, 0x08, 0x95, 0x43, 0xf8, 0x74, 0x08,
0x5f, 0x0e, 0xc9, 0xd6, 0x21, 0xbc, 0x35, 0x48, 0xaa, 0x06, 0xc9, 0xa6, 0x41, 0x72, 0x13, 0x66,
0x9a, 0xfd, 0x6e, 0x24, 0xf5, 0x5f, 0x93, 0x9e, 0xfb, 0xc7, 0x6a, 0xd7, 0x2f, 0x7a, 0xf6, 0x1d,
0x00, 0x00, 0xff, 0xff, 0xfe, 0x8b, 0xe4, 0xcb, 0x7f, 0x01, 0x00, 0x00,
}
func (this *VectorClock) Equal(that interface{}) bool {
@@ -165,6 +236,36 @@ func (this *VectorClock) Equal(that interface{}) bool {
}
return true
}
func (this *HybridLogicalClock) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*HybridLogicalClock)
if !ok {
that2, ok := that.(HybridLogicalClock)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if this.WallClock != that1.WallClock {
return false
}
if this.Version != that1.Version {
return false
}
if this.ClusterId != that1.ClusterId {
return false
}
return true
}
func (this *VectorClock) GoString() string {
if this == nil {
return "nil"
@@ -177,6 +278,18 @@ func (this *VectorClock) GoString() string {
s = append(s, "}")
return strings.Join(s, "")
}
func (this *HybridLogicalClock) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 7)
s = append(s, "&clock.HybridLogicalClock{")
s = append(s, "WallClock: "+fmt.Sprintf("%#v", this.WallClock)+",\n")
s = append(s, "Version: "+fmt.Sprintf("%#v", this.Version)+",\n")
s = append(s, "ClusterId: "+fmt.Sprintf("%#v", this.ClusterId)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringMessage(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@@ -223,6 +336,44 @@ func (m *VectorClock) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *HybridLogicalClock) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *HybridLogicalClock) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *HybridLogicalClock) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.ClusterId != 0 {
i = encodeVarintMessage(dAtA, i, uint64(m.ClusterId))
i--
dAtA[i] = 0x18
}
if m.Version != 0 {
i = encodeVarintMessage(dAtA, i, uint64(m.Version))
i--
dAtA[i] = 0x10
}
if m.WallClock != 0 {
i = encodeVarintMessage(dAtA, i, uint64(m.WallClock))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintMessage(dAtA []byte, offset int, v uint64) int {
offset -= sovMessage(v)
base := offset
@@ -252,6 +403,24 @@ func (m *VectorClock) Size() (n int) {
return n
}
func (m *HybridLogicalClock) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.WallClock != 0 {
n += 1 + sovMessage(uint64(m.WallClock))
}
if m.Version != 0 {
n += 1 + sovMessage(uint64(m.Version))
}
if m.ClusterId != 0 {
n += 1 + sovMessage(uint64(m.ClusterId))
}
return n
}
func sovMessage(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -270,6 +439,18 @@ func (this *VectorClock) String() string {
}, "")
return s
}
func (this *HybridLogicalClock) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&HybridLogicalClock{`,
`WallClock:` + fmt.Sprintf("%v", this.WallClock) + `,`,
`Version:` + fmt.Sprintf("%v", this.Version) + `,`,
`ClusterId:` + fmt.Sprintf("%v", this.ClusterId) + `,`,
`}`,
}, "")
return s
}
func valueToStringMessage(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@@ -388,6 +569,116 @@ func (m *VectorClock) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *HybridLogicalClock) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: HybridLogicalClock: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: HybridLogicalClock: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field WallClock", wireType)
}
m.WallClock = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.WallClock |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
}
m.Version = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Version |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ClusterId", wireType)
}
m.ClusterId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowMessage
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ClusterId |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipMessage(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthMessage
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthMessage
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipMessage(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0

File diff suppressed because it is too large Load Diff

View File

@@ -55,42 +55,42 @@ func init() {
var fileDescriptor_1a5c83076e651916 = []byte{
// 566 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x3d, 0x6f, 0xd3, 0x40,
0x18, 0xc7, 0x7d, 0x0b, 0xc3, 0x49, 0xa8, 0xaa, 0x05, 0x42, 0x14, 0x71, 0x42, 0x0c, 0x8c, 0x8e,
0x0a, 0x6c, 0xb4, 0x40, 0x9a, 0x40, 0x08, 0x34, 0x6a, 0xca, 0x8b, 0x90, 0x58, 0xd0, 0x25, 0x7e,
0x08, 0xa7, 0x3a, 0x3e, 0x73, 0x3e, 0x1b, 0x65, 0xe3, 0x13, 0x20, 0x06, 0x26, 0x56, 0x24, 0xc4,
0xc0, 0xc4, 0xd4, 0x89, 0x15, 0xc6, 0x8c, 0x1d, 0x89, 0xb3, 0x30, 0xf6, 0x23, 0x20, 0xd7, 0xb9,
0x6b, 0xde, 0x7b, 0x71, 0xb2, 0x25, 0xce, 0xfd, 0x7f, 0xcf, 0xef, 0x1f, 0xdf, 0x49, 0x87, 0x6f,
0x4b, 0x68, 0x07, 0x5c, 0x50, 0xaf, 0x10, 0x82, 0x88, 0x41, 0x14, 0x68, 0xc0, 0x0a, 0x6d, 0x2a,
0x9b, 0x6f, 0x99, 0xdf, 0x4a, 0x1f, 0xb1, 0x26, 0x14, 0xe2, 0xcd, 0xc2, 0xe0, 0xa3, 0x13, 0x08,
0x2e, 0xb9, 0x7d, 0x43, 0xa5, 0x9c, 0x2c, 0xe5, 0xd0, 0x80, 0x39, 0x63, 0x29, 0x27, 0xde, 0xdc,
0xd8, 0x36, 0xa4, 0x0b, 0x78, 0x17, 0x41, 0x28, 0x5f, 0x0b, 0x08, 0x03, 0xee, 0x87, 0x83, 0x31,
0x37, 0x0f, 0xd7, 0xf1, 0x5a, 0x6d, 0xb0, 0xfa, 0x59, 0xb6, 0xda, 0xfe, 0x86, 0xf0, 0xc5, 0x3a,
0xf7, 0xbc, 0x97, 0x5c, 0x1c, 0xbc, 0xf1, 0xf8, 0xfb, 0xe7, 0x34, 0x3c, 0xd8, 0x8f, 0x20, 0x02,
0xbb, 0xec, 0x98, 0x59, 0x39, 0x53, 0xe3, 0x4f, 0x33, 0x85, 0x8d, 0x07, 0x4b, 0x52, 0xb2, 0x02,
0xd7, 0x2d, 0x2d, 0x5a, 0x6c, 0x4a, 0x16, 0x33, 0xd9, 0xc9, 0x29, 0x3a, 0x11, 0xcf, 0x25, 0x3a,
0x85, 0xa2, 0x45, 0x3f, 0x23, 0xbc, 0x56, 0x74, 0xdd, 0xe1, 0x2e, 0xf6, 0x5d, 0x53, 0xf8, 0x58,
0x50, 0xc9, 0xdd, 0xcb, 0x9d, 0x1f, 0xd7, 0x1a, 0x36, 0x5f, 0x48, 0x6b, 0x38, 0x98, 0x47, 0x6b,
0x34, 0xaf, 0xb5, 0x3e, 0x22, 0x7c, 0x7e, 0x3f, 0x02, 0xd1, 0x51, 0xda, 0xf6, 0x96, 0x29, 0x74,
0x24, 0xa6, 0x94, 0xb6, 0x73, 0xa6, 0xb5, 0xd0, 0x4f, 0x84, 0x2f, 0x67, 0x5f, 0xdd, 0x93, 0x25,
0xa9, 0x6f, 0x89, 0xb7, 0x03, 0x0f, 0x24, 0xb8, 0xf6, 0x23, 0x53, 0xfc, 0x4c, 0x84, 0x12, 0xad,
0xae, 0x80, 0x34, 0x72, 0x38, 0x4a, 0xd4, 0x6f, 0x82, 0xb7, 0x17, 0xc9, 0x50, 0x52, 0xdf, 0x65,
0x7e, 0x2b, 0xdd, 0xa8, 0xe6, 0x87, 0x63, 0x6a, 0x7c, 0xe1, 0xc3, 0x31, 0x83, 0xa2, 0x45, 0xbf,
0x20, 0xbc, 0x5e, 0x86, 0xb0, 0x29, 0x58, 0x03, 0x4e, 0x4f, 0xf0, 0x7d, 0x53, 0xfc, 0x44, 0x54,
0x09, 0x16, 0x97, 0x20, 0x68, 0xb9, 0x1f, 0x08, 0x5f, 0xda, 0x65, 0xa1, 0xd4, 0xbf, 0xd5, 0xa9,
0x90, 0x4c, 0x32, 0xee, 0x87, 0xf6, 0x43, 0xd3, 0x01, 0x33, 0x00, 0x4a, 0xb4, 0xb2, 0x34, 0x47,
0xeb, 0xfe, 0x46, 0xf8, 0xda, 0x8b, 0xc0, 0xa5, 0x12, 0xd2, 0x6d, 0x0c, 0x62, 0x27, 0x62, 0x9e,
0x5b, 0x75, 0xd3, 0xfd, 0x41, 0x25, 0x6b, 0x30, 0x8f, 0xc9, 0x8e, 0xbd, 0x67, 0x3a, 0xef, 0x2c,
0x92, 0x2a, 0x50, 0x5f, 0x1d, 0x50, 0x37, 0xf9, 0x85, 0xf0, 0xd5, 0x0a, 0xc8, 0x39, 0x35, 0x76,
0x4d, 0xa7, 0xce, 0xc5, 0xa8, 0x0e, 0xb5, 0x15, 0xd1, 0x74, 0x81, 0x43, 0x84, 0xaf, 0x54, 0xfd,
0x98, 0x7a, 0x2c, 0xed, 0xac, 0x5f, 0x5b, 0x0d, 0x24, 0x75, 0xa9, 0xa4, 0xf6, 0x63, 0xd3, 0x81,
0x73, 0x20, 0x4a, 0xfe, 0xc9, 0x4a, 0x58, 0x5a, 0xfd, 0x2b, 0xc2, 0x17, 0x2a, 0x20, 0x27, 0x9d,
0x4b, 0x0b, 0xfc, 0x49, 0x33, 0x65, 0xcb, 0xcb, 0x41, 0x94, 0xe5, 0x8e, 0xe8, 0xf6, 0x88, 0x75,
0xd4, 0x23, 0xd6, 0x71, 0x8f, 0xa0, 0x0f, 0x09, 0x41, 0xdf, 0x13, 0x82, 0xfe, 0x24, 0x04, 0x75,
0x13, 0x82, 0xfe, 0x26, 0x04, 0xfd, 0x4b, 0x88, 0x75, 0x9c, 0x10, 0xf4, 0xa9, 0x4f, 0xac, 0x6e,
0x9f, 0x58, 0x47, 0x7d, 0x62, 0xbd, 0xda, 0x6a, 0xf1, 0xd3, 0xf9, 0x8c, 0xcf, 0xbf, 0x35, 0xdd,
0x19, 0x7b, 0xd4, 0x38, 0x77, 0x72, 0x6b, 0xba, 0xf5, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x39,
0x89, 0x97, 0xd4, 0x09, 0x00, 0x00,
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x3f, 0x6f, 0x13, 0x31,
0x18, 0xc6, 0xcf, 0x0b, 0x83, 0x25, 0x54, 0xf5, 0x04, 0x42, 0x14, 0x61, 0x21, 0x06, 0xc6, 0x8b,
0x0a, 0x6c, 0xb4, 0x40, 0x9b, 0x40, 0x08, 0xb4, 0x6a, 0x0a, 0x54, 0x48, 0x2c, 0xc8, 0xc9, 0xbd,
0x04, 0xab, 0x97, 0xf3, 0x61, 0xfb, 0x82, 0xb2, 0xf1, 0x09, 0x10, 0x03, 0x13, 0x2b, 0x12, 0x62,
0x60, 0x62, 0xea, 0xc4, 0x0a, 0x63, 0xc6, 0x8e, 0xe4, 0xb2, 0x30, 0xf6, 0x23, 0xa0, 0xeb, 0xc5,
0x6e, 0xfe, 0xe3, 0x5c, 0xb2, 0x25, 0x17, 0x3f, 0xbf, 0xf7, 0xf7, 0xe4, 0x6c, 0xc9, 0xf8, 0xb6,
0x82, 0x66, 0xc4, 0x05, 0x0d, 0x0a, 0x12, 0x44, 0x0b, 0x44, 0x81, 0x46, 0xac, 0xd0, 0xa4, 0xaa,
0xfe, 0x86, 0x85, 0x8d, 0xf4, 0x11, 0xab, 0x43, 0xa1, 0xb5, 0x5e, 0xe8, 0x7f, 0xf4, 0x22, 0xc1,
0x15, 0x77, 0x6f, 0xe8, 0x94, 0x97, 0xa5, 0x3c, 0x1a, 0x31, 0x6f, 0x24, 0xe5, 0xb5, 0xd6, 0xd7,
0x36, 0x2d, 0xe9, 0x02, 0xde, 0xc6, 0x20, 0xd5, 0x2b, 0x01, 0x32, 0xe2, 0xa1, 0xec, 0x8f, 0xb9,
0x79, 0xb4, 0x8a, 0x57, 0x76, 0xfb, 0xab, 0x9f, 0x65, 0xab, 0xdd, 0xaf, 0x08, 0x5f, 0xac, 0xf2,
0x20, 0x78, 0xc1, 0xc5, 0xe1, 0xeb, 0x80, 0xbf, 0x7b, 0x4e, 0xe5, 0xe1, 0x7e, 0x0c, 0x31, 0xb8,
0x25, 0xcf, 0xce, 0xca, 0x9b, 0x18, 0x7f, 0x9a, 0x29, 0xac, 0x3d, 0x58, 0x90, 0x92, 0x15, 0xb8,
0xee, 0x18, 0xd1, 0xad, 0xba, 0x62, 0x2d, 0xa6, 0xda, 0x39, 0x45, 0xc7, 0xe2, 0xb9, 0x44, 0x27,
0x50, 0x8c, 0xe8, 0x27, 0x84, 0x57, 0xb6, 0x7c, 0x7f, 0xb0, 0x8b, 0x7b, 0xd7, 0x16, 0x3e, 0x12,
0xd4, 0x72, 0xf7, 0x72, 0xe7, 0x47, 0xb5, 0x06, 0xcd, 0xe7, 0xd2, 0x1a, 0x0c, 0xe6, 0xd1, 0x1a,
0xce, 0x1b, 0xad, 0x0f, 0x08, 0x9f, 0xdf, 0x8f, 0x41, 0xb4, 0xb5, 0xb6, 0xbb, 0x61, 0x0b, 0x1d,
0x8a, 0x69, 0xa5, 0xcd, 0x9c, 0x69, 0x23, 0xf4, 0x03, 0xe1, 0xcb, 0xd9, 0x57, 0xff, 0x74, 0x49,
0xea, 0x5b, 0xe4, 0xcd, 0x28, 0x00, 0x05, 0xbe, 0xfb, 0xc8, 0x16, 0x3f, 0x15, 0xa1, 0x45, 0x2b,
0x4b, 0x20, 0x0d, 0x1d, 0x8e, 0x22, 0x0d, 0xeb, 0x10, 0xec, 0xc5, 0x4a, 0x2a, 0x1a, 0xfa, 0x2c,
0x6c, 0xa4, 0x1b, 0xd5, 0xfe, 0x70, 0x4c, 0x8c, 0xcf, 0x7d, 0x38, 0xa6, 0x50, 0x8c, 0xe8, 0x67,
0x84, 0x57, 0x4b, 0x20, 0xeb, 0x82, 0xd5, 0xe0, 0xec, 0x04, 0xdf, 0xb7, 0xc5, 0x8f, 0x45, 0xb5,
0xe0, 0xd6, 0x02, 0x04, 0x23, 0xf7, 0x1d, 0xe1, 0x4b, 0x3b, 0x4c, 0x2a, 0xf3, 0x5b, 0x95, 0x0a,
0xc5, 0x14, 0xe3, 0xa1, 0x74, 0x1f, 0xda, 0x0e, 0x98, 0x02, 0xd0, 0xa2, 0xe5, 0x85, 0x39, 0x46,
0xf7, 0x17, 0xc2, 0xd7, 0x0e, 0x22, 0x9f, 0x2a, 0x48, 0xb7, 0x31, 0x88, 0xed, 0x98, 0x05, 0x7e,
0xc5, 0x4f, 0xf7, 0x07, 0x55, 0xac, 0xc6, 0x02, 0xa6, 0xda, 0xee, 0x9e, 0xed, 0xbc, 0xff, 0x91,
0x74, 0x81, 0xea, 0xf2, 0x80, 0xa6, 0xc9, 0x4f, 0x84, 0xaf, 0x96, 0x41, 0xcd, 0xa8, 0xb1, 0x63,
0x3b, 0x75, 0x26, 0x46, 0x77, 0xd8, 0x5d, 0x12, 0xcd, 0x14, 0x38, 0x42, 0xf8, 0x4a, 0x25, 0x6c,
0xd1, 0x80, 0xa5, 0x9d, 0xcd, 0x6b, 0x3b, 0x90, 0x20, 0x4a, 0x54, 0x51, 0xf7, 0xb1, 0xed, 0xc0,
0x19, 0x10, 0x2d, 0xff, 0x64, 0x29, 0x2c, 0xa3, 0xfe, 0x05, 0xe1, 0x0b, 0x65, 0x50, 0xe3, 0xce,
0xc5, 0x39, 0xfe, 0xa4, 0xa9, 0xb2, 0xa5, 0xc5, 0x20, 0xda, 0x72, 0x5b, 0x74, 0xba, 0xc4, 0x39,
0xee, 0x12, 0xe7, 0xa4, 0x4b, 0xd0, 0xfb, 0x84, 0xa0, 0x6f, 0x09, 0x41, 0xbf, 0x13, 0x82, 0x3a,
0x09, 0x41, 0x7f, 0x12, 0x82, 0xfe, 0x26, 0xc4, 0x39, 0x49, 0x08, 0xfa, 0xd8, 0x23, 0x4e, 0xa7,
0x47, 0x9c, 0xe3, 0x1e, 0x71, 0x5e, 0x6e, 0x34, 0xf8, 0xd9, 0x7c, 0xc6, 0x67, 0xdf, 0x9a, 0xee,
0x8c, 0x3c, 0xaa, 0x9d, 0x3b, 0xbd, 0x35, 0xdd, 0xfa, 0x17, 0x00, 0x00, 0xff, 0xff, 0xf4, 0x6f,
0x28, 0x89, 0xd4, 0x09, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -140,10 +140,10 @@ type MatchingServiceClient interface {
// aip.dev/not-precedent: UpdateWorkerBuildIdOrdering RPC doesn't follow Google API format. --)
UpdateWorkerBuildIdCompatibility(ctx context.Context, in *UpdateWorkerBuildIdCompatibilityRequest, opts ...grpc.CallOption) (*UpdateWorkerBuildIdCompatibilityResponse, error)
GetWorkerBuildIdCompatibility(ctx context.Context, in *GetWorkerBuildIdCompatibilityRequest, opts ...grpc.CallOption) (*GetWorkerBuildIdCompatibilityResponse, error)
// Tell a task queue that some metadata has changed.
InvalidateTaskQueueMetadata(ctx context.Context, in *InvalidateTaskQueueMetadataRequest, opts ...grpc.CallOption) (*InvalidateTaskQueueMetadataResponse, error)
// Fetch some metadata about a task queue.
GetTaskQueueMetadata(ctx context.Context, in *GetTaskQueueMetadataRequest, opts ...grpc.CallOption) (*GetTaskQueueMetadataResponse, error)
// Tell a task queue that the associated user data has changed.
InvalidateTaskQueueUserData(ctx context.Context, in *InvalidateTaskQueueUserDataRequest, opts ...grpc.CallOption) (*InvalidateTaskQueueUserDataResponse, error)
// Fetch user data for a task queue, this request should always be routed to the node holding the task queue's root partition.
GetTaskQueueUserData(ctx context.Context, in *GetTaskQueueUserDataRequest, opts ...grpc.CallOption) (*GetTaskQueueUserDataResponse, error)
}
type matchingServiceClient struct {
@@ -253,18 +253,18 @@ func (c *matchingServiceClient) GetWorkerBuildIdCompatibility(ctx context.Contex
return out, nil
}
func (c *matchingServiceClient) InvalidateTaskQueueMetadata(ctx context.Context, in *InvalidateTaskQueueMetadataRequest, opts ...grpc.CallOption) (*InvalidateTaskQueueMetadataResponse, error) {
out := new(InvalidateTaskQueueMetadataResponse)
err := c.cc.Invoke(ctx, "/temporal.server.api.matchingservice.v1.MatchingService/InvalidateTaskQueueMetadata", in, out, opts...)
func (c *matchingServiceClient) InvalidateTaskQueueUserData(ctx context.Context, in *InvalidateTaskQueueUserDataRequest, opts ...grpc.CallOption) (*InvalidateTaskQueueUserDataResponse, error) {
out := new(InvalidateTaskQueueUserDataResponse)
err := c.cc.Invoke(ctx, "/temporal.server.api.matchingservice.v1.MatchingService/InvalidateTaskQueueUserData", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *matchingServiceClient) GetTaskQueueMetadata(ctx context.Context, in *GetTaskQueueMetadataRequest, opts ...grpc.CallOption) (*GetTaskQueueMetadataResponse, error) {
out := new(GetTaskQueueMetadataResponse)
err := c.cc.Invoke(ctx, "/temporal.server.api.matchingservice.v1.MatchingService/GetTaskQueueMetadata", in, out, opts...)
func (c *matchingServiceClient) GetTaskQueueUserData(ctx context.Context, in *GetTaskQueueUserDataRequest, opts ...grpc.CallOption) (*GetTaskQueueUserDataResponse, error) {
out := new(GetTaskQueueUserDataResponse)
err := c.cc.Invoke(ctx, "/temporal.server.api.matchingservice.v1.MatchingService/GetTaskQueueUserData", in, out, opts...)
if err != nil {
return nil, err
}
@@ -308,10 +308,10 @@ type MatchingServiceServer interface {
// aip.dev/not-precedent: UpdateWorkerBuildIdOrdering RPC doesn't follow Google API format. --)
UpdateWorkerBuildIdCompatibility(context.Context, *UpdateWorkerBuildIdCompatibilityRequest) (*UpdateWorkerBuildIdCompatibilityResponse, error)
GetWorkerBuildIdCompatibility(context.Context, *GetWorkerBuildIdCompatibilityRequest) (*GetWorkerBuildIdCompatibilityResponse, error)
// Tell a task queue that some metadata has changed.
InvalidateTaskQueueMetadata(context.Context, *InvalidateTaskQueueMetadataRequest) (*InvalidateTaskQueueMetadataResponse, error)
// Fetch some metadata about a task queue.
GetTaskQueueMetadata(context.Context, *GetTaskQueueMetadataRequest) (*GetTaskQueueMetadataResponse, error)
// Tell a task queue that the associated user data has changed.
InvalidateTaskQueueUserData(context.Context, *InvalidateTaskQueueUserDataRequest) (*InvalidateTaskQueueUserDataResponse, error)
// Fetch user data for a task queue, this request should always be routed to the node holding the task queue's root partition.
GetTaskQueueUserData(context.Context, *GetTaskQueueUserDataRequest) (*GetTaskQueueUserDataResponse, error)
}
// UnimplementedMatchingServiceServer can be embedded to have forward compatible implementations.
@@ -351,11 +351,11 @@ func (*UnimplementedMatchingServiceServer) UpdateWorkerBuildIdCompatibility(ctx
func (*UnimplementedMatchingServiceServer) GetWorkerBuildIdCompatibility(ctx context.Context, req *GetWorkerBuildIdCompatibilityRequest) (*GetWorkerBuildIdCompatibilityResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetWorkerBuildIdCompatibility not implemented")
}
func (*UnimplementedMatchingServiceServer) InvalidateTaskQueueMetadata(ctx context.Context, req *InvalidateTaskQueueMetadataRequest) (*InvalidateTaskQueueMetadataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method InvalidateTaskQueueMetadata not implemented")
func (*UnimplementedMatchingServiceServer) InvalidateTaskQueueUserData(ctx context.Context, req *InvalidateTaskQueueUserDataRequest) (*InvalidateTaskQueueUserDataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method InvalidateTaskQueueUserData not implemented")
}
func (*UnimplementedMatchingServiceServer) GetTaskQueueMetadata(ctx context.Context, req *GetTaskQueueMetadataRequest) (*GetTaskQueueMetadataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetTaskQueueMetadata not implemented")
func (*UnimplementedMatchingServiceServer) GetTaskQueueUserData(ctx context.Context, req *GetTaskQueueUserDataRequest) (*GetTaskQueueUserDataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetTaskQueueUserData not implemented")
}
func RegisterMatchingServiceServer(s *grpc.Server, srv MatchingServiceServer) {
@@ -560,38 +560,38 @@ func _MatchingService_GetWorkerBuildIdCompatibility_Handler(srv interface{}, ctx
return interceptor(ctx, in, info, handler)
}
func _MatchingService_InvalidateTaskQueueMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(InvalidateTaskQueueMetadataRequest)
func _MatchingService_InvalidateTaskQueueUserData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(InvalidateTaskQueueUserDataRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MatchingServiceServer).InvalidateTaskQueueMetadata(ctx, in)
return srv.(MatchingServiceServer).InvalidateTaskQueueUserData(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/temporal.server.api.matchingservice.v1.MatchingService/InvalidateTaskQueueMetadata",
FullMethod: "/temporal.server.api.matchingservice.v1.MatchingService/InvalidateTaskQueueUserData",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MatchingServiceServer).InvalidateTaskQueueMetadata(ctx, req.(*InvalidateTaskQueueMetadataRequest))
return srv.(MatchingServiceServer).InvalidateTaskQueueUserData(ctx, req.(*InvalidateTaskQueueUserDataRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MatchingService_GetTaskQueueMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetTaskQueueMetadataRequest)
func _MatchingService_GetTaskQueueUserData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetTaskQueueUserDataRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MatchingServiceServer).GetTaskQueueMetadata(ctx, in)
return srv.(MatchingServiceServer).GetTaskQueueUserData(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/temporal.server.api.matchingservice.v1.MatchingService/GetTaskQueueMetadata",
FullMethod: "/temporal.server.api.matchingservice.v1.MatchingService/GetTaskQueueUserData",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MatchingServiceServer).GetTaskQueueMetadata(ctx, req.(*GetTaskQueueMetadataRequest))
return srv.(MatchingServiceServer).GetTaskQueueUserData(ctx, req.(*GetTaskQueueUserDataRequest))
}
return interceptor(ctx, in, info, handler)
}
@@ -645,12 +645,12 @@ var _MatchingService_serviceDesc = grpc.ServiceDesc{
Handler: _MatchingService_GetWorkerBuildIdCompatibility_Handler,
},
{
MethodName: "InvalidateTaskQueueMetadata",
Handler: _MatchingService_InvalidateTaskQueueMetadata_Handler,
MethodName: "InvalidateTaskQueueUserData",
Handler: _MatchingService_InvalidateTaskQueueUserData_Handler,
},
{
MethodName: "GetTaskQueueMetadata",
Handler: _MatchingService_GetTaskQueueMetadata_Handler,
MethodName: "GetTaskQueueUserData",
Handler: _MatchingService_GetTaskQueueUserData_Handler,
},
},
Streams: []grpc.StreamDesc{},

View File

@@ -140,24 +140,24 @@ func (mr *MockMatchingServiceClientMockRecorder) DescribeTaskQueue(ctx, in inter
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTaskQueue", reflect.TypeOf((*MockMatchingServiceClient)(nil).DescribeTaskQueue), varargs...)
}
// GetTaskQueueMetadata mocks base method.
func (m *MockMatchingServiceClient) GetTaskQueueMetadata(ctx context.Context, in *matchingservice.GetTaskQueueMetadataRequest, opts ...grpc.CallOption) (*matchingservice.GetTaskQueueMetadataResponse, error) {
// GetTaskQueueUserData mocks base method.
func (m *MockMatchingServiceClient) GetTaskQueueUserData(ctx context.Context, in *matchingservice.GetTaskQueueUserDataRequest, opts ...grpc.CallOption) (*matchingservice.GetTaskQueueUserDataResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetTaskQueueMetadata", varargs...)
ret0, _ := ret[0].(*matchingservice.GetTaskQueueMetadataResponse)
ret := m.ctrl.Call(m, "GetTaskQueueUserData", varargs...)
ret0, _ := ret[0].(*matchingservice.GetTaskQueueUserDataResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTaskQueueMetadata indicates an expected call of GetTaskQueueMetadata.
func (mr *MockMatchingServiceClientMockRecorder) GetTaskQueueMetadata(ctx, in interface{}, opts ...interface{}) *gomock.Call {
// GetTaskQueueUserData indicates an expected call of GetTaskQueueUserData.
func (mr *MockMatchingServiceClientMockRecorder) GetTaskQueueUserData(ctx, in interface{}, opts ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueMetadata", reflect.TypeOf((*MockMatchingServiceClient)(nil).GetTaskQueueMetadata), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceClient)(nil).GetTaskQueueUserData), varargs...)
}
// GetWorkerBuildIdCompatibility mocks base method.
@@ -180,24 +180,24 @@ func (mr *MockMatchingServiceClientMockRecorder) GetWorkerBuildIdCompatibility(c
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerBuildIdCompatibility", reflect.TypeOf((*MockMatchingServiceClient)(nil).GetWorkerBuildIdCompatibility), varargs...)
}
// InvalidateTaskQueueMetadata mocks base method.
func (m *MockMatchingServiceClient) InvalidateTaskQueueMetadata(ctx context.Context, in *matchingservice.InvalidateTaskQueueMetadataRequest, opts ...grpc.CallOption) (*matchingservice.InvalidateTaskQueueMetadataResponse, error) {
// InvalidateTaskQueueUserData mocks base method.
func (m *MockMatchingServiceClient) InvalidateTaskQueueUserData(ctx context.Context, in *matchingservice.InvalidateTaskQueueUserDataRequest, opts ...grpc.CallOption) (*matchingservice.InvalidateTaskQueueUserDataResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "InvalidateTaskQueueMetadata", varargs...)
ret0, _ := ret[0].(*matchingservice.InvalidateTaskQueueMetadataResponse)
ret := m.ctrl.Call(m, "InvalidateTaskQueueUserData", varargs...)
ret0, _ := ret[0].(*matchingservice.InvalidateTaskQueueUserDataResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InvalidateTaskQueueMetadata indicates an expected call of InvalidateTaskQueueMetadata.
func (mr *MockMatchingServiceClientMockRecorder) InvalidateTaskQueueMetadata(ctx, in interface{}, opts ...interface{}) *gomock.Call {
// InvalidateTaskQueueUserData indicates an expected call of InvalidateTaskQueueUserData.
func (mr *MockMatchingServiceClientMockRecorder) InvalidateTaskQueueUserData(ctx, in interface{}, opts ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvalidateTaskQueueMetadata", reflect.TypeOf((*MockMatchingServiceClient)(nil).InvalidateTaskQueueMetadata), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvalidateTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceClient)(nil).InvalidateTaskQueueUserData), varargs...)
}
// ListTaskQueuePartitions mocks base method.
@@ -403,19 +403,19 @@ func (mr *MockMatchingServiceServerMockRecorder) DescribeTaskQueue(arg0, arg1 in
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DescribeTaskQueue", reflect.TypeOf((*MockMatchingServiceServer)(nil).DescribeTaskQueue), arg0, arg1)
}
// GetTaskQueueMetadata mocks base method.
func (m *MockMatchingServiceServer) GetTaskQueueMetadata(arg0 context.Context, arg1 *matchingservice.GetTaskQueueMetadataRequest) (*matchingservice.GetTaskQueueMetadataResponse, error) {
// GetTaskQueueUserData mocks base method.
func (m *MockMatchingServiceServer) GetTaskQueueUserData(arg0 context.Context, arg1 *matchingservice.GetTaskQueueUserDataRequest) (*matchingservice.GetTaskQueueUserDataResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTaskQueueMetadata", arg0, arg1)
ret0, _ := ret[0].(*matchingservice.GetTaskQueueMetadataResponse)
ret := m.ctrl.Call(m, "GetTaskQueueUserData", arg0, arg1)
ret0, _ := ret[0].(*matchingservice.GetTaskQueueUserDataResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTaskQueueMetadata indicates an expected call of GetTaskQueueMetadata.
func (mr *MockMatchingServiceServerMockRecorder) GetTaskQueueMetadata(arg0, arg1 interface{}) *gomock.Call {
// GetTaskQueueUserData indicates an expected call of GetTaskQueueUserData.
func (mr *MockMatchingServiceServerMockRecorder) GetTaskQueueUserData(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueMetadata", reflect.TypeOf((*MockMatchingServiceServer)(nil).GetTaskQueueMetadata), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceServer)(nil).GetTaskQueueUserData), arg0, arg1)
}
// GetWorkerBuildIdCompatibility mocks base method.
@@ -433,19 +433,19 @@ func (mr *MockMatchingServiceServerMockRecorder) GetWorkerBuildIdCompatibility(a
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkerBuildIdCompatibility", reflect.TypeOf((*MockMatchingServiceServer)(nil).GetWorkerBuildIdCompatibility), arg0, arg1)
}
// InvalidateTaskQueueMetadata mocks base method.
func (m *MockMatchingServiceServer) InvalidateTaskQueueMetadata(arg0 context.Context, arg1 *matchingservice.InvalidateTaskQueueMetadataRequest) (*matchingservice.InvalidateTaskQueueMetadataResponse, error) {
// InvalidateTaskQueueUserData mocks base method.
func (m *MockMatchingServiceServer) InvalidateTaskQueueUserData(arg0 context.Context, arg1 *matchingservice.InvalidateTaskQueueUserDataRequest) (*matchingservice.InvalidateTaskQueueUserDataResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InvalidateTaskQueueMetadata", arg0, arg1)
ret0, _ := ret[0].(*matchingservice.InvalidateTaskQueueMetadataResponse)
ret := m.ctrl.Call(m, "InvalidateTaskQueueUserData", arg0, arg1)
ret0, _ := ret[0].(*matchingservice.InvalidateTaskQueueUserDataResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InvalidateTaskQueueMetadata indicates an expected call of InvalidateTaskQueueMetadata.
func (mr *MockMatchingServiceServerMockRecorder) InvalidateTaskQueueMetadata(arg0, arg1 interface{}) *gomock.Call {
// InvalidateTaskQueueUserData indicates an expected call of InvalidateTaskQueueUserData.
func (mr *MockMatchingServiceServerMockRecorder) InvalidateTaskQueueUserData(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvalidateTaskQueueMetadata", reflect.TypeOf((*MockMatchingServiceServer)(nil).InvalidateTaskQueueMetadata), arg0, arg1)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvalidateTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceServer)(nil).InvalidateTaskQueueUserData), arg0, arg1)
}
// ListTaskQueuePartitions mocks base method.

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,6 @@ import (
_ "github.com/gogo/protobuf/types"
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
v11 "go.temporal.io/api/enums/v1"
v12 "go.temporal.io/api/taskqueue/v1"
v1 "go.temporal.io/server/api/clock/v1"
)
@@ -209,7 +208,6 @@ type TaskQueueInfo struct {
AckLevel int64 `protobuf:"varint,5,opt,name=ack_level,json=ackLevel,proto3" json:"ack_level,omitempty"`
ExpiryTime *time.Time `protobuf:"bytes,6,opt,name=expiry_time,json=expiryTime,proto3,stdtime" json:"expiry_time,omitempty"`
LastUpdateTime *time.Time `protobuf:"bytes,7,opt,name=last_update_time,json=lastUpdateTime,proto3,stdtime" json:"last_update_time,omitempty"`
VersioningData *VersioningData `protobuf:"bytes,8,opt,name=versioning_data,json=versioningData,proto3" json:"versioning_data,omitempty"`
}
func (m *TaskQueueInfo) Reset() { *m = TaskQueueInfo{} }
@@ -293,58 +291,6 @@ func (m *TaskQueueInfo) GetLastUpdateTime() *time.Time {
return nil
}
func (m *TaskQueueInfo) GetVersioningData() *VersioningData {
if m != nil {
return m.VersioningData
}
return nil
}
// Holds all the data related to worker versioning for a task queue.
// Backwards-incompatible changes cannot be made, as this would make existing stored data unreadable
type VersioningData struct {
VersionSets []*v12.CompatibleVersionSet `protobuf:"bytes,1,rep,name=version_sets,json=versionSets,proto3" json:"version_sets,omitempty"`
}
func (m *VersioningData) Reset() { *m = VersioningData{} }
func (*VersioningData) ProtoMessage() {}
func (*VersioningData) Descriptor() ([]byte, []int) {
return fileDescriptor_f9c734e3b35cf986, []int{3}
}
func (m *VersioningData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *VersioningData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_VersioningData.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *VersioningData) XXX_Merge(src proto.Message) {
xxx_messageInfo_VersioningData.Merge(m, src)
}
func (m *VersioningData) XXX_Size() int {
return m.Size()
}
func (m *VersioningData) XXX_DiscardUnknown() {
xxx_messageInfo_VersioningData.DiscardUnknown(m)
}
var xxx_messageInfo_VersioningData proto.InternalMessageInfo
func (m *VersioningData) GetVersionSets() []*v12.CompatibleVersionSet {
if m != nil {
return m.VersionSets
}
return nil
}
type TaskKey struct {
FireTime *time.Time `protobuf:"bytes,1,opt,name=fire_time,json=fireTime,proto3,stdtime" json:"fire_time,omitempty"`
TaskId int64 `protobuf:"varint,2,opt,name=task_id,json=taskId,proto3" json:"task_id,omitempty"`
@@ -353,7 +299,7 @@ type TaskKey struct {
func (m *TaskKey) Reset() { *m = TaskKey{} }
func (*TaskKey) ProtoMessage() {}
func (*TaskKey) Descriptor() ([]byte, []int) {
return fileDescriptor_f9c734e3b35cf986, []int{4}
return fileDescriptor_f9c734e3b35cf986, []int{3}
}
func (m *TaskKey) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -400,7 +346,6 @@ func init() {
proto.RegisterType((*AllocatedTaskInfo)(nil), "temporal.server.api.persistence.v1.AllocatedTaskInfo")
proto.RegisterType((*TaskInfo)(nil), "temporal.server.api.persistence.v1.TaskInfo")
proto.RegisterType((*TaskQueueInfo)(nil), "temporal.server.api.persistence.v1.TaskQueueInfo")
proto.RegisterType((*VersioningData)(nil), "temporal.server.api.persistence.v1.VersioningData")
proto.RegisterType((*TaskKey)(nil), "temporal.server.api.persistence.v1.TaskKey")
}
@@ -409,52 +354,46 @@ func init() {
}
var fileDescriptor_f9c734e3b35cf986 = []byte{
// 705 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6e, 0xd3, 0x4c,
0x14, 0x8d, 0x9b, 0x34, 0x3f, 0x93, 0x7e, 0xf9, 0xca, 0x48, 0x88, 0xa8, 0x48, 0x6e, 0x1b, 0x21,
0x28, 0xa8, 0xb2, 0xd5, 0xc0, 0x02, 0x09, 0x21, 0x68, 0x0b, 0x8b, 0x50, 0x36, 0x98, 0xd2, 0x05,
0x2c, 0xa2, 0xa9, 0xe7, 0x26, 0x98, 0xd8, 0x33, 0xc6, 0x33, 0x76, 0xc9, 0x8e, 0x47, 0xe8, 0x63,
0xf0, 0x28, 0x2c, 0x58, 0x74, 0x59, 0xb1, 0x81, 0xba, 0x1b, 0x96, 0x7d, 0x04, 0x34, 0xe3, 0xd8,
0x6d, 0x44, 0x2b, 0xb2, 0x60, 0x37, 0x77, 0xee, 0x39, 0x67, 0xee, 0x9c, 0xe3, 0x31, 0xb2, 0x24,
0x04, 0x21, 0x8f, 0x88, 0x6f, 0x0b, 0x88, 0x12, 0x88, 0x6c, 0x12, 0x7a, 0x76, 0x08, 0x91, 0xf0,
0x84, 0x04, 0xe6, 0x82, 0x9d, 0x6c, 0xd8, 0x92, 0x88, 0x91, 0xb0, 0xc2, 0x88, 0x4b, 0x8e, 0x3b,
0x39, 0xde, 0xca, 0xf0, 0x16, 0x09, 0x3d, 0xeb, 0x02, 0xde, 0x4a, 0x36, 0x96, 0x96, 0x87, 0x9c,
0x0f, 0x7d, 0xb0, 0x35, 0x63, 0x3f, 0x1e, 0xd8, 0xd2, 0x0b, 0x40, 0x48, 0x12, 0x84, 0x99, 0xc8,
0xd2, 0x2a, 0x85, 0x10, 0x18, 0x05, 0xe6, 0x7a, 0x20, 0xec, 0x21, 0x1f, 0x72, 0xbd, 0xaf, 0x57,
0x13, 0xc8, 0xed, 0x62, 0x2e, 0x35, 0x10, 0xb0, 0x38, 0x10, 0xf9, 0x28, 0xfd, 0x8f, 0x31, 0xc4,
0x30, 0xc1, 0xdd, 0x99, 0xc2, 0xa9, 0xb6, 0xee, 0x2a, 0x6c, 0x00, 0x42, 0x90, 0x61, 0x0e, 0xbc,
0x77, 0xd9, 0x45, 0x5d, 0x9f, 0xbb, 0xa3, 0x3f, 0xb0, 0x1d, 0x86, 0xae, 0x6d, 0xfa, 0x3e, 0x77,
0x89, 0x04, 0xba, 0x4b, 0xc4, 0xa8, 0xc7, 0x06, 0x1c, 0x3f, 0x45, 0x15, 0x4a, 0x24, 0x69, 0x1b,
0x2b, 0xc6, 0x5a, 0xb3, 0xbb, 0x6e, 0xfd, 0xdd, 0x08, 0x2b, 0xe7, 0x3a, 0x9a, 0x89, 0x6f, 0xa0,
0x9a, 0x9e, 0xdf, 0xa3, 0xed, 0xb9, 0x15, 0x63, 0xad, 0xec, 0x54, 0x55, 0xd9, 0xa3, 0x9d, 0xef,
0x73, 0xa8, 0x5e, 0x9c, 0xb3, 0x8a, 0x16, 0x18, 0x09, 0x40, 0x84, 0xc4, 0x05, 0x05, 0x55, 0xe7,
0x35, 0x9c, 0x66, 0xb1, 0xd7, 0xa3, 0x78, 0x19, 0x35, 0x0f, 0x78, 0x34, 0x1a, 0xf8, 0xfc, 0x20,
0x17, 0x6b, 0x38, 0x28, 0xdf, 0xea, 0x51, 0x7c, 0x1d, 0x55, 0xa3, 0x98, 0xa9, 0x5e, 0x59, 0xf7,
0xe6, 0xa3, 0x98, 0xf5, 0x28, 0x5e, 0x47, 0x58, 0xb8, 0xef, 0x81, 0xc6, 0x3e, 0xd0, 0x3e, 0x24,
0xc0, 0xa4, 0x82, 0x54, 0xf4, 0x2c, 0x8b, 0x45, 0xe7, 0xb9, 0x6a, 0xf4, 0x28, 0xde, 0x44, 0x4d,
0x37, 0x02, 0x22, 0xa1, 0xaf, 0xf2, 0x6b, 0xcf, 0xeb, 0x7b, 0x2f, 0x59, 0x59, 0xb8, 0x56, 0x1e,
0xae, 0xb5, 0x9b, 0x87, 0xbb, 0x55, 0x39, 0xfc, 0xb1, 0x6c, 0x38, 0x28, 0x23, 0xa9, 0x6d, 0x25,
0x01, 0x9f, 0x42, 0x2f, 0x1a, 0x67, 0x12, 0xd5, 0x59, 0x25, 0x32, 0x92, 0x96, 0x78, 0x82, 0xe6,
0x75, 0x4a, 0xed, 0x9a, 0x26, 0xdf, 0xbd, 0xd4, 0x77, 0x8d, 0x50, 0x8e, 0xef, 0x81, 0x2b, 0x79,
0xb4, 0xad, 0x4a, 0x27, 0xe3, 0x75, 0xbe, 0x95, 0xd1, 0x7f, 0xca, 0xdc, 0x57, 0xea, 0xbb, 0x98,
0xd5, 0x61, 0x8c, 0x2a, 0xaa, 0x9c, 0x58, 0xab, 0xd7, 0x78, 0x13, 0x35, 0x74, 0x7c, 0x72, 0x1c,
0x82, 0xf6, 0xb5, 0xd5, 0xbd, 0x75, 0x3e, 0x8d, 0x1a, 0x43, 0x7f, 0xa6, 0x79, 0xf0, 0xfa, 0xbc,
0xdd, 0x71, 0x08, 0x4e, 0x5d, 0xd1, 0xd4, 0x0a, 0x3f, 0x44, 0x95, 0x91, 0xc7, 0x32, 0xcb, 0x67,
0x60, 0xef, 0x78, 0x8c, 0x3a, 0x9a, 0x81, 0x6f, 0xa2, 0x06, 0x71, 0x47, 0x7d, 0x1f, 0x12, 0xf0,
0x75, 0x14, 0x65, 0xa7, 0x4e, 0xdc, 0xd1, 0x4b, 0x55, 0xff, 0x0b, 0x9b, 0x5f, 0xa0, 0x45, 0x9f,
0x08, 0xd9, 0x8f, 0x43, 0x5a, 0x24, 0x5e, 0x9b, 0x51, 0xa7, 0xa5, 0x98, 0x6f, 0x34, 0x51, 0x6b,
0xbd, 0x43, 0xff, 0x27, 0xea, 0x21, 0x70, 0xe6, 0xb1, 0x61, 0x5f, 0x3f, 0x9a, 0xba, 0x96, 0xea,
0xce, 0xf2, 0x68, 0xf6, 0x0a, 0xea, 0x33, 0x22, 0x89, 0xd3, 0x4a, 0xa6, 0xea, 0x0e, 0x45, 0xad,
0x69, 0x04, 0x76, 0xd0, 0xc2, 0x04, 0xd3, 0x17, 0x20, 0x45, 0xdb, 0x58, 0x29, 0xaf, 0x35, 0xbb,
0xf6, 0xb4, 0xb9, 0xc5, 0x9f, 0x41, 0x1d, 0xb1, 0xcd, 0x83, 0x90, 0x48, 0x6f, 0xdf, 0x87, 0x89,
0xd4, 0x6b, 0x90, 0x4e, 0x33, 0x29, 0xd6, 0xa2, 0x43, 0x50, 0x4d, 0xa5, 0xb0, 0x03, 0x63, 0xfc,
0x18, 0x35, 0x06, 0x5e, 0x34, 0xb1, 0xc4, 0x98, 0xd1, 0x92, 0xba, 0xa2, 0x68, 0x33, 0xae, 0x7a,
0xf4, 0x5b, 0x1f, 0x8e, 0x4e, 0xcc, 0xd2, 0xf1, 0x89, 0x59, 0x3a, 0x3b, 0x31, 0x8d, 0xcf, 0xa9,
0x69, 0x7c, 0x49, 0x4d, 0xe3, 0x6b, 0x6a, 0x1a, 0x47, 0xa9, 0x69, 0xfc, 0x4c, 0x4d, 0xe3, 0x57,
0x6a, 0x96, 0xce, 0x52, 0xd3, 0x38, 0x3c, 0x35, 0x4b, 0x47, 0xa7, 0x66, 0xe9, 0xf8, 0xd4, 0x2c,
0xbd, 0x7d, 0x30, 0xe4, 0xe7, 0x17, 0xf3, 0xf8, 0xd5, 0x7f, 0xed, 0x47, 0x17, 0xca, 0xfd, 0xaa,
0x1e, 0xf4, 0xfe, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xac, 0xd4, 0xe2, 0x22, 0xee, 0x05, 0x00,
0x00,
// 619 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4f, 0x6f, 0xd3, 0x30,
0x1c, 0x6d, 0xb6, 0xae, 0x7f, 0x5c, 0x98, 0x86, 0x25, 0x44, 0x35, 0x24, 0x6f, 0xab, 0x10, 0x1a,
0x68, 0x4a, 0xb4, 0xc1, 0x01, 0x09, 0x21, 0xd8, 0x10, 0x87, 0x32, 0x2e, 0x44, 0x83, 0x03, 0x97,
0xca, 0x8b, 0x7f, 0x2d, 0x21, 0x69, 0x1c, 0x6c, 0xa7, 0xa3, 0x37, 0x3e, 0xc2, 0x3e, 0x06, 0x1f,
0x85, 0xe3, 0x8e, 0x13, 0x17, 0x58, 0x7a, 0xe1, 0xc6, 0x3e, 0x02, 0xfa, 0x39, 0x4d, 0xb7, 0xc3,
0x26, 0x7a, 0xe0, 0x66, 0xfb, 0xf7, 0xde, 0xf3, 0xf3, 0x7b, 0x69, 0x89, 0x6b, 0x60, 0x98, 0x4a,
0xc5, 0x63, 0x4f, 0x83, 0x1a, 0x81, 0xf2, 0x78, 0x1a, 0x7a, 0x29, 0x28, 0x1d, 0x6a, 0x03, 0x49,
0x00, 0xde, 0x68, 0xdb, 0x33, 0x5c, 0x47, 0xda, 0x4d, 0x95, 0x34, 0x92, 0x76, 0x4a, 0xbc, 0x5b,
0xe0, 0x5d, 0x9e, 0x86, 0xee, 0x25, 0xbc, 0x3b, 0xda, 0x5e, 0x5d, 0x1b, 0x48, 0x39, 0x88, 0xc1,
0xb3, 0x8c, 0xc3, 0xac, 0xef, 0x99, 0x70, 0x08, 0xda, 0xf0, 0x61, 0x5a, 0x88, 0xac, 0x6e, 0x08,
0x48, 0x21, 0x11, 0x90, 0x04, 0x21, 0x68, 0x6f, 0x20, 0x07, 0xd2, 0x9e, 0xdb, 0xd5, 0x14, 0x72,
0x7f, 0xe6, 0x0b, 0x0d, 0x41, 0x92, 0x0d, 0x75, 0x69, 0xa5, 0xf7, 0x39, 0x83, 0x0c, 0xa6, 0xb8,
0x87, 0x57, 0xf9, 0x0f, 0x62, 0x19, 0x44, 0x08, 0x1f, 0x82, 0xd6, 0x7c, 0x30, 0xc5, 0x76, 0x12,
0x72, 0x6b, 0x37, 0x8e, 0x65, 0xc0, 0x0d, 0x88, 0x03, 0xae, 0xa3, 0x6e, 0xd2, 0x97, 0xf4, 0x05,
0xa9, 0x0a, 0x6e, 0x78, 0xdb, 0x59, 0x77, 0x36, 0x5b, 0x3b, 0x5b, 0xee, 0xbf, 0xdf, 0xe7, 0x96,
0x5c, 0xdf, 0x32, 0xe9, 0x1d, 0x52, 0xb7, 0xb6, 0x42, 0xd1, 0x5e, 0x58, 0x77, 0x36, 0x17, 0xfd,
0x1a, 0x6e, 0xbb, 0xa2, 0xf3, 0x63, 0x81, 0x34, 0x66, 0xf7, 0x6c, 0x90, 0x1b, 0x09, 0x1f, 0x82,
0x4e, 0x79, 0x00, 0x08, 0xc5, 0xfb, 0x9a, 0x7e, 0x6b, 0x76, 0xd6, 0x15, 0x74, 0x8d, 0xb4, 0x8e,
0xa4, 0x8a, 0xfa, 0xb1, 0x3c, 0x2a, 0xc5, 0x9a, 0x3e, 0x29, 0x8f, 0xba, 0x82, 0xde, 0x26, 0x35,
0x95, 0x25, 0x38, 0x5b, 0xb4, 0xb3, 0x25, 0x95, 0x25, 0x5d, 0x41, 0xb7, 0x08, 0xd5, 0xc1, 0x47,
0x10, 0x59, 0x0c, 0xa2, 0x07, 0x23, 0x48, 0x0c, 0x42, 0xaa, 0xd6, 0xcb, 0xca, 0x6c, 0xf2, 0x0a,
0x07, 0x5d, 0x41, 0x77, 0x49, 0x2b, 0x50, 0xc0, 0x0d, 0xf4, 0xb0, 0x96, 0xf6, 0x92, 0x7d, 0xf7,
0xaa, 0x5b, 0x74, 0xe6, 0x96, 0x9d, 0xb9, 0x07, 0x65, 0x67, 0x7b, 0xd5, 0xe3, 0x9f, 0x6b, 0x8e,
0x4f, 0x0a, 0x12, 0x1e, 0xa3, 0x04, 0x7c, 0x49, 0x43, 0x35, 0x2e, 0x24, 0x6a, 0xf3, 0x4a, 0x14,
0x24, 0x2b, 0xf1, 0x9c, 0x2c, 0xd9, 0x96, 0xda, 0x75, 0x4b, 0x7e, 0x70, 0x65, 0xee, 0x16, 0x81,
0x89, 0xbf, 0x87, 0xc0, 0x48, 0xf5, 0x12, 0xb7, 0x7e, 0xc1, 0xeb, 0xfc, 0x59, 0x20, 0x37, 0x31,
0xdc, 0xb7, 0xf8, 0x31, 0xcc, 0x9b, 0x30, 0x25, 0x55, 0xdc, 0x4e, 0xa3, 0xb5, 0x6b, 0xba, 0x4b,
0x9a, 0xb6, 0x3e, 0x33, 0x4e, 0xc1, 0xe6, 0xba, 0xbc, 0x73, 0xef, 0xc2, 0x0d, 0xda, 0xb0, 0x5f,
0x5f, 0x59, 0xbc, 0xbd, 0xef, 0x60, 0x9c, 0x82, 0xdf, 0x40, 0x1a, 0xae, 0xe8, 0x13, 0x52, 0x8d,
0xc2, 0xa4, 0x88, 0x7c, 0x0e, 0xf6, 0x7e, 0x98, 0x08, 0xdf, 0x32, 0xe8, 0x5d, 0xd2, 0xe4, 0x41,
0xd4, 0x8b, 0x61, 0x04, 0xb1, 0xad, 0x62, 0xd1, 0x6f, 0xf0, 0x20, 0x7a, 0x83, 0xfb, 0xff, 0x11,
0xf3, 0x6b, 0xb2, 0x12, 0x73, 0x6d, 0x7a, 0x59, 0x2a, 0x66, 0x8d, 0xd7, 0xe7, 0xd4, 0x59, 0x46,
0xe6, 0x3b, 0x4b, 0xc4, 0x51, 0x87, 0x93, 0x3a, 0x3e, 0x61, 0x1f, 0xc6, 0xf4, 0x19, 0x69, 0xf6,
0x43, 0x35, 0xd5, 0x73, 0xe6, 0xd4, 0x6b, 0x20, 0xc5, 0xba, 0xba, 0xee, 0x17, 0xb3, 0xf7, 0xe9,
0xe4, 0x8c, 0x55, 0x4e, 0xcf, 0x58, 0xe5, 0xfc, 0x8c, 0x39, 0x5f, 0x73, 0xe6, 0x7c, 0xcb, 0x99,
0xf3, 0x3d, 0x67, 0xce, 0x49, 0xce, 0x9c, 0x5f, 0x39, 0x73, 0x7e, 0xe7, 0xac, 0x72, 0x9e, 0x33,
0xe7, 0x78, 0xc2, 0x2a, 0x27, 0x13, 0x56, 0x39, 0x9d, 0xb0, 0xca, 0x87, 0xc7, 0x03, 0x79, 0x11,
0x79, 0x28, 0xaf, 0xff, 0x27, 0x7b, 0x7a, 0x69, 0x7b, 0x58, 0xb3, 0x46, 0x1f, 0xfd, 0x0d, 0x00,
0x00, 0xff, 0xff, 0x86, 0xf6, 0x0e, 0x01, 0x02, 0x05, 0x00, 0x00,
}
func (this *AllocatedTaskInfo) Equal(that interface{}) bool {
@@ -582,38 +521,6 @@ func (this *TaskQueueInfo) Equal(that interface{}) bool {
} else if !this.LastUpdateTime.Equal(*that1.LastUpdateTime) {
return false
}
if !this.VersioningData.Equal(that1.VersioningData) {
return false
}
return true
}
func (this *VersioningData) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*VersioningData)
if !ok {
that2, ok := that.(VersioningData)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if len(this.VersionSets) != len(that1.VersionSets) {
return false
}
for i := range this.VersionSets {
if !this.VersionSets[i].Equal(that1.VersionSets[i]) {
return false
}
}
return true
}
func (this *TaskKey) Equal(that interface{}) bool {
@@ -682,7 +589,7 @@ func (this *TaskQueueInfo) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 12)
s := make([]string, 0, 11)
s = append(s, "&persistence.TaskQueueInfo{")
s = append(s, "NamespaceId: "+fmt.Sprintf("%#v", this.NamespaceId)+",\n")
s = append(s, "Name: "+fmt.Sprintf("%#v", this.Name)+",\n")
@@ -691,21 +598,6 @@ func (this *TaskQueueInfo) GoString() string {
s = append(s, "AckLevel: "+fmt.Sprintf("%#v", this.AckLevel)+",\n")
s = append(s, "ExpiryTime: "+fmt.Sprintf("%#v", this.ExpiryTime)+",\n")
s = append(s, "LastUpdateTime: "+fmt.Sprintf("%#v", this.LastUpdateTime)+",\n")
if this.VersioningData != nil {
s = append(s, "VersioningData: "+fmt.Sprintf("%#v", this.VersioningData)+",\n")
}
s = append(s, "}")
return strings.Join(s, "")
}
func (this *VersioningData) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 5)
s = append(s, "&persistence.VersioningData{")
if this.VersionSets != nil {
s = append(s, "VersionSets: "+fmt.Sprintf("%#v", this.VersionSets)+",\n")
}
s = append(s, "}")
return strings.Join(s, "")
}
@@ -869,36 +761,24 @@ func (m *TaskQueueInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
if m.VersioningData != nil {
{
size, err := m.VersioningData.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTasks(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x42
}
if m.LastUpdateTime != nil {
n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastUpdateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastUpdateTime):])
n5, err5 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastUpdateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastUpdateTime):])
if err5 != nil {
return 0, err5
}
i -= n5
i = encodeVarintTasks(dAtA, i, uint64(n5))
i--
dAtA[i] = 0x3a
}
if m.ExpiryTime != nil {
n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ExpiryTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ExpiryTime):])
if err6 != nil {
return 0, err6
}
i -= n6
i = encodeVarintTasks(dAtA, i, uint64(n6))
i--
dAtA[i] = 0x3a
}
if m.ExpiryTime != nil {
n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ExpiryTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ExpiryTime):])
if err7 != nil {
return 0, err7
}
i -= n7
i = encodeVarintTasks(dAtA, i, uint64(n7))
i--
dAtA[i] = 0x32
}
if m.AckLevel != 0 {
@@ -933,43 +813,6 @@ func (m *TaskQueueInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *VersioningData) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *VersioningData) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *VersioningData) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.VersionSets) > 0 {
for iNdEx := len(m.VersionSets) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.VersionSets[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTasks(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *TaskKey) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -996,12 +839,12 @@ func (m *TaskKey) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x10
}
if m.FireTime != nil {
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.FireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.FireTime):])
if err8 != nil {
return 0, err8
n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.FireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.FireTime):])
if err7 != nil {
return 0, err7
}
i -= n8
i = encodeVarintTasks(dAtA, i, uint64(n8))
i -= n7
i = encodeVarintTasks(dAtA, i, uint64(n7))
i--
dAtA[i] = 0xa
}
@@ -1102,25 +945,6 @@ func (m *TaskQueueInfo) Size() (n int) {
l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastUpdateTime)
n += 1 + l + sovTasks(uint64(l))
}
if m.VersioningData != nil {
l = m.VersioningData.Size()
n += 1 + l + sovTasks(uint64(l))
}
return n
}
func (m *VersioningData) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.VersionSets) > 0 {
for _, e := range m.VersionSets {
l = e.Size()
n += 1 + l + sovTasks(uint64(l))
}
}
return n
}
@@ -1185,22 +1009,6 @@ func (this *TaskQueueInfo) String() string {
`AckLevel:` + fmt.Sprintf("%v", this.AckLevel) + `,`,
`ExpiryTime:` + strings.Replace(fmt.Sprintf("%v", this.ExpiryTime), "Timestamp", "types.Timestamp", 1) + `,`,
`LastUpdateTime:` + strings.Replace(fmt.Sprintf("%v", this.LastUpdateTime), "Timestamp", "types.Timestamp", 1) + `,`,
`VersioningData:` + strings.Replace(this.VersioningData.String(), "VersioningData", "VersioningData", 1) + `,`,
`}`,
}, "")
return s
}
func (this *VersioningData) String() string {
if this == nil {
return "nil"
}
repeatedStringForVersionSets := "[]*CompatibleVersionSet{"
for _, f := range this.VersionSets {
repeatedStringForVersionSets += strings.Replace(fmt.Sprintf("%v", f), "CompatibleVersionSet", "v12.CompatibleVersionSet", 1) + ","
}
repeatedStringForVersionSets += "}"
s := strings.Join([]string{`&VersioningData{`,
`VersionSets:` + repeatedStringForVersionSets + `,`,
`}`,
}, "")
return s
@@ -1830,129 +1638,6 @@ func (m *TaskQueueInfo) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VersioningData", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTasks
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.VersioningData == nil {
m.VersioningData = &VersioningData{}
}
if err := m.VersioningData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTasks(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTasks
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthTasks
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *VersioningData) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: VersioningData: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: VersioningData: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field VersionSets", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTasks
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTasks
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTasks
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.VersionSets = append(m.VersionSets, &v12.CompatibleVersionSet{})
if err := m.VersionSets[len(m.VersionSets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTasks(dAtA[iNdEx:])

View File

@@ -65,11 +65,11 @@ func (c *clientImpl) DescribeTaskQueue(
return client.DescribeTaskQueue(ctx, request, opts...)
}
func (c *clientImpl) GetTaskQueueMetadata(
func (c *clientImpl) GetTaskQueueUserData(
ctx context.Context,
request *matchingservice.GetTaskQueueMetadataRequest,
request *matchingservice.GetTaskQueueUserDataRequest,
opts ...grpc.CallOption,
) (*matchingservice.GetTaskQueueMetadataResponse, error) {
) (*matchingservice.GetTaskQueueUserDataResponse, error) {
client, err := c.getClientForTaskqueue(request.GetNamespaceId(), &taskqueuepb.TaskQueue{Name: request.GetTaskQueue()}, enumspb.TASK_QUEUE_TYPE_WORKFLOW)
if err != nil {
@@ -77,7 +77,7 @@ func (c *clientImpl) GetTaskQueueMetadata(
}
ctx, cancel := c.createContext(ctx)
defer cancel()
return client.GetTaskQueueMetadata(ctx, request, opts...)
return client.GetTaskQueueUserData(ctx, request, opts...)
}
func (c *clientImpl) GetWorkerBuildIdCompatibility(
@@ -95,11 +95,11 @@ func (c *clientImpl) GetWorkerBuildIdCompatibility(
return client.GetWorkerBuildIdCompatibility(ctx, request, opts...)
}
func (c *clientImpl) InvalidateTaskQueueMetadata(
func (c *clientImpl) InvalidateTaskQueueUserData(
ctx context.Context,
request *matchingservice.InvalidateTaskQueueMetadataRequest,
request *matchingservice.InvalidateTaskQueueUserDataRequest,
opts ...grpc.CallOption,
) (*matchingservice.InvalidateTaskQueueMetadataResponse, error) {
) (*matchingservice.InvalidateTaskQueueUserDataResponse, error) {
client, err := c.getClientForTaskqueue(request.GetNamespaceId(), &taskqueuepb.TaskQueue{Name: request.GetTaskQueue()}, request.GetTaskQueueType())
if err != nil {
@@ -107,7 +107,7 @@ func (c *clientImpl) InvalidateTaskQueueMetadata(
}
ctx, cancel := c.createContext(ctx)
defer cancel()
return client.InvalidateTaskQueueMetadata(ctx, request, opts...)
return client.InvalidateTaskQueueUserData(ctx, request, opts...)
}
func (c *clientImpl) ListTaskQueuePartitions(

View File

@@ -63,18 +63,18 @@ func (c *metricClient) DescribeTaskQueue(
return c.client.DescribeTaskQueue(ctx, request, opts...)
}
func (c *metricClient) GetTaskQueueMetadata(
func (c *metricClient) GetTaskQueueUserData(
ctx context.Context,
request *matchingservice.GetTaskQueueMetadataRequest,
request *matchingservice.GetTaskQueueUserDataRequest,
opts ...grpc.CallOption,
) (_ *matchingservice.GetTaskQueueMetadataResponse, retError error) {
) (_ *matchingservice.GetTaskQueueUserDataResponse, retError error) {
metricsHandler, startTime := c.startMetricsRecording(ctx, metrics.MatchingClientGetTaskQueueMetadataScope)
metricsHandler, startTime := c.startMetricsRecording(ctx, metrics.MatchingClientGetTaskQueueUserDataScope)
defer func() {
c.finishMetricsRecording(metricsHandler, startTime, retError)
}()
return c.client.GetTaskQueueMetadata(ctx, request, opts...)
return c.client.GetTaskQueueUserData(ctx, request, opts...)
}
func (c *metricClient) GetWorkerBuildIdCompatibility(
@@ -91,18 +91,18 @@ func (c *metricClient) GetWorkerBuildIdCompatibility(
return c.client.GetWorkerBuildIdCompatibility(ctx, request, opts...)
}
func (c *metricClient) InvalidateTaskQueueMetadata(
func (c *metricClient) InvalidateTaskQueueUserData(
ctx context.Context,
request *matchingservice.InvalidateTaskQueueMetadataRequest,
request *matchingservice.InvalidateTaskQueueUserDataRequest,
opts ...grpc.CallOption,
) (_ *matchingservice.InvalidateTaskQueueMetadataResponse, retError error) {
) (_ *matchingservice.InvalidateTaskQueueUserDataResponse, retError error) {
metricsHandler, startTime := c.startMetricsRecording(ctx, metrics.MatchingClientInvalidateTaskQueueMetadataScope)
metricsHandler, startTime := c.startMetricsRecording(ctx, metrics.MatchingClientInvalidateTaskQueueUserDataScope)
defer func() {
c.finishMetricsRecording(metricsHandler, startTime, retError)
}()
return c.client.InvalidateTaskQueueMetadata(ctx, request, opts...)
return c.client.InvalidateTaskQueueUserData(ctx, request, opts...)
}
func (c *metricClient) ListTaskQueuePartitions(

View File

@@ -95,15 +95,15 @@ func (c *retryableClient) DescribeTaskQueue(
return resp, err
}
func (c *retryableClient) GetTaskQueueMetadata(
func (c *retryableClient) GetTaskQueueUserData(
ctx context.Context,
request *matchingservice.GetTaskQueueMetadataRequest,
request *matchingservice.GetTaskQueueUserDataRequest,
opts ...grpc.CallOption,
) (*matchingservice.GetTaskQueueMetadataResponse, error) {
var resp *matchingservice.GetTaskQueueMetadataResponse
) (*matchingservice.GetTaskQueueUserDataResponse, error) {
var resp *matchingservice.GetTaskQueueUserDataResponse
op := func(ctx context.Context) error {
var err error
resp, err = c.client.GetTaskQueueMetadata(ctx, request, opts...)
resp, err = c.client.GetTaskQueueUserData(ctx, request, opts...)
return err
}
err := backoff.ThrottleRetryContext(ctx, op, c.policy, c.isRetryable)
@@ -125,15 +125,15 @@ func (c *retryableClient) GetWorkerBuildIdCompatibility(
return resp, err
}
func (c *retryableClient) InvalidateTaskQueueMetadata(
func (c *retryableClient) InvalidateTaskQueueUserData(
ctx context.Context,
request *matchingservice.InvalidateTaskQueueMetadataRequest,
request *matchingservice.InvalidateTaskQueueUserDataRequest,
opts ...grpc.CallOption,
) (*matchingservice.InvalidateTaskQueueMetadataResponse, error) {
var resp *matchingservice.InvalidateTaskQueueMetadataResponse
) (*matchingservice.InvalidateTaskQueueUserDataResponse, error) {
var resp *matchingservice.InvalidateTaskQueueUserDataResponse
op := func(ctx context.Context) error {
var err error
resp, err = c.client.InvalidateTaskQueueMetadata(ctx, request, opts...)
resp, err = c.client.InvalidateTaskQueueUserData(ctx, request, opts...)
return err
}
err := backoff.ThrottleRetryContext(ctx, op, c.policy, c.isRetryable)

View File

@@ -188,7 +188,7 @@ func makeGetMatchingClient(reqType reflect.Type) string {
"UpdateWorkerBuildIdCompatibilityRequest",
"RespondQueryTaskCompletedRequest",
"ListTaskQueuePartitionsRequest",
"GetTaskQueueMetadataRequest":
"GetTaskQueueUserDataRequest":
tqtPath = "enumspb.TASK_QUEUE_TYPE_WORKFLOW"
default:
tqtPath = pathToField(t, "TaskQueueType", "request", 2)

View File

@@ -177,9 +177,14 @@ const (
// WorkerBuildIdSizeLimit is the byte length limit for a worker build id as used in the rpc methods for updating
// the version graph for a task queue
WorkerBuildIdSizeLimit = "limit.workerBuildIdSize"
// VersionGraphNodeLimit is the max number of nodes allowed in the version graph for a task queue. Update requests
// which would cause the graph size to exceed this number will result in the oldest versions being dropped.
VersionGraphNodeLimit = "limit.versionGraphNodeSize"
// VersionCompatibleSetLimitPerQueue is the max number of compatible sets allowed in the versioning data for a task
// queue. Update requests which would cause the versioning data to exceed this number will fail with a
// FailedPrecondition error.
VersionCompatibleSetLimitPerQueue = "limit.versionCompatibleSetLimitPerQueue"
// VersionBuildIDLimitPerQueue is the max number of build IDs allowed to be defined in the versioning data for a
// task queue. Update requests which would cause the versioning data to exceed this number will fail with a
// FailedPrecondition error.
VersionBuildIDLimitPerQueue = "limit.versionBuildIDLimitPerQueue"
// keys for frontend
@@ -366,8 +371,8 @@ const (
MatchingForwarderMaxChildrenPerNode = "matching.forwarderMaxChildrenPerNode"
// MatchingShutdownDrainDuration is the duration of traffic drain during shutdown
MatchingShutdownDrainDuration = "matching.shutdownDrainDuration"
// MatchingMetadataPollFrequency is how often non-root partitions will poll the root partition for fresh metadata
MatchingMetadataPollFrequency = "matching.metadataPollFrequency"
// MatchingUserDataPollFrequency is how often non-root partitions will poll the root partition for fresh metadata
MatchingUserDataPollFrequency = "matching.userDataPollFrequency"
// keys for history

View File

@@ -467,10 +467,10 @@ const (
MatchingClientUpdateWorkerBuildIdCompatibilityScope = "MatchingClientUpdateWorkerBuildIdCompatibility"
// MatchingClientGetWorkerBuildIdCompatibilityScope tracks RPC calls to matching service
MatchingClientGetWorkerBuildIdCompatibilityScope = "MatchingClientGetWorkerBuildIdCompatibility"
// MatchingClientInvalidateTaskQueueMetadataScope tracks RPC calls to matching service
MatchingClientInvalidateTaskQueueMetadataScope = "MatchingClientInvalidateTaskQueueMetadata"
// MatchingClientGetTaskQueueMetadataScope tracks RPC calls to matching service
MatchingClientGetTaskQueueMetadataScope = "MatchingClientGetTaskQueueMetadata"
// MatchingClientInvalidateTaskQueueUserDataScope tracks RPC calls to matching service
MatchingClientInvalidateTaskQueueUserDataScope = "MatchingClientInvalidateTaskQueueUserData"
// MatchingClientGetTaskQueueUserDataScope tracks RPC calls to matching service
MatchingClientGetTaskQueueUserDataScope = "MatchingClientGetTaskQueueUserData"
)
// Worker
@@ -630,6 +630,10 @@ const (
PersistenceListTaskQueueScope = "ListTaskQueue"
// PersistenceDeleteTaskQueueScope is the metric scope for persistence.TaskManager.DeleteTaskQueue API
PersistenceDeleteTaskQueueScope = "DeleteTaskQueue"
// PersistenceGetTaskQueueUserDataScope is the metric scope for persistence.TaskManager.GetTaskQueueUserData API
PersistenceGetTaskQueueUserDataScope = "GetTaskQueueUserData"
// PersistenceUpdateTaskQueueUserDataScope is the metric scope for persistence.TaskManager.UpdateTaskQueueUserData API
PersistenceUpdateTaskQueueUserDataScope = "UpdateTaskQueueUserData"
// PersistenceAppendHistoryEventsScope tracks AppendHistoryEvents calls made by service to persistence layer
PersistenceAppendHistoryEventsScope = "AppendHistoryEvents"
// PersistenceGetWorkflowExecutionHistoryScope tracks GetWorkflowExecutionHistory calls made by service to persistence layer
@@ -1098,10 +1102,10 @@ const (
MatchingUpdateWorkerBuildIdCompatibilityScope = "UpdateWorkerBuildIdCompatibility"
// MatchingGetWorkerBuildIdCompatibilityScope tracks GetWorkerBuildIdCompatibility API calls received by service
MatchingGetWorkerBuildIdCompatibilityScope = "GetWorkerBuildIdCompatibility"
// MatchingInvalidateTaskQueueMetadataScope tracks GetWorkerBuildIdCompatibility API calls received by service
MatchingInvalidateTaskQueueMetadataScope = "InvalidateTaskQueueMetadata"
// MatchingGetTaskQueueMetadataScope tracks GetWorkerBuildIdCompatibility API calls received by service
MatchingGetTaskQueueMetadataScope = "GetTaskQueueMetadata"
// MatchingInvalidateTaskQueueUserDataScope tracks InvalidateTaskQueueUserData API calls received by service
MatchingInvalidateTaskQueueUserDataScope = "InvalidateTaskQueueUserData"
// MatchingGetTaskQueueUserDataScope tracks GetTaskQueueUserData API calls received by service
MatchingGetTaskQueueUserDataScope = "GetTaskQueueUserData"
)
// Worker Scope

View File

@@ -131,6 +131,22 @@ const (
`AND type = ? ` +
`AND task_id = ? ` +
`IF range_id = ?`
templateGetTaskQueueUserDataQuery = `SELECT data, data_encoding, version FROM task_queue_user_data ` +
`WHERE namespace_id = ? ` +
`AND task_queue_name = ? `
templateUpdateTaskQueueUserDataQuery = `UPDATE task_queue_user_data SET ` +
`data = ?, ` +
`data_encoding = ?, ` +
`version = ? ` +
`WHERE namespace_id = ? ` +
`AND task_queue_name = ? ` +
`IF version = ?`
templateInsertTaskQueueUserDataQuery = `INSERT INTO task_queue_user_data` +
`(namespace_id, task_queue_name, data, data_encoding, version) ` +
`VALUES (?, ?, ?, ?, 1) IF NOT EXISTS`
)
type (
@@ -494,6 +510,72 @@ func (d *MatchingTaskStore) CompleteTasksLessThan(
return p.UnknownNumRowsAffected, nil
}
func (d *MatchingTaskStore) GetTaskQueueUserData(
ctx context.Context,
request *p.GetTaskQueueUserDataRequest,
) (*p.InternalGetTaskQueueUserDataResponse, error) {
query := d.Session.Query(templateGetTaskQueueUserDataQuery,
request.NamespaceID,
request.TaskQueue,
).WithContext(ctx)
var version int64
var userDataBytes []byte
var encoding string
if err := query.Scan(&userDataBytes, &encoding, &version); err != nil {
return nil, gocql.ConvertError("GetTaskQueueData", err)
}
return &p.InternalGetTaskQueueUserDataResponse{
Version: version,
UserData: p.NewDataBlob(userDataBytes, encoding),
}, nil
}
func (d *MatchingTaskStore) UpdateTaskQueueUserData(
ctx context.Context,
request *p.InternalUpdateTaskQueueUserDataRequest,
) error {
var query gocql.Query
if request.Version == 0 {
query = d.Session.Query(templateInsertTaskQueueUserDataQuery,
request.NamespaceID,
request.TaskQueue,
request.UserData.Data,
request.UserData.EncodingType.String(),
).WithContext(ctx)
} else {
query = d.Session.Query(templateUpdateTaskQueueUserDataQuery,
request.UserData.Data,
request.UserData.EncodingType.String(),
request.Version+1,
request.NamespaceID,
request.TaskQueue,
request.Version,
).WithContext(ctx)
}
previous := make(map[string]interface{})
applied, err := query.MapScanCAS(previous)
if err != nil {
return gocql.ConvertError("UpdateTaskQueueData", err)
}
if !applied {
var columns []string
for k, v := range previous {
columns = append(columns, fmt.Sprintf("%s=%v", k, v))
}
return &p.ConditionFailedError{
Msg: fmt.Sprintf("Failed to update task queue. name: %v, version: %v, columns: (%v)",
request.TaskQueue, request.Version, strings.Join(columns, ",")),
}
}
return nil
}
func (d *MatchingTaskStore) GetName() string {
return cassandraPersistenceName
}

View File

@@ -1044,6 +1044,20 @@ func (t *FaultInjectionTaskStore) CompleteTasksLessThan(
return t.baseTaskStore.CompleteTasksLessThan(ctx, request)
}
func (t *FaultInjectionTaskStore) GetTaskQueueUserData(ctx context.Context, request *persistence.GetTaskQueueUserDataRequest) (*persistence.InternalGetTaskQueueUserDataResponse, error) {
if err := t.ErrorGenerator.Generate(); err != nil {
return nil, err
}
return t.baseTaskStore.GetTaskQueueUserData(ctx, request)
}
func (t *FaultInjectionTaskStore) UpdateTaskQueueUserData(ctx context.Context, request *persistence.InternalUpdateTaskQueueUserDataRequest) error {
if err := t.ErrorGenerator.Generate(); err != nil {
return err
}
return t.baseTaskStore.UpdateTaskQueueUserData(ctx, request)
}
func (t *FaultInjectionTaskStore) UpdateRate(rate float64) {
t.ErrorGenerator.UpdateRate(rate)
}

View File

@@ -544,6 +544,24 @@ type (
TaskQueueInfo *persistencespb.TaskQueueInfo
}
// GetTaskQueueUserDataRequest is the input type for the GetTaskQueueUserData API
GetTaskQueueUserDataRequest struct {
NamespaceID string
TaskQueue string
}
// GetTaskQueueUserDataResponse is the output type for the GetTaskQueueUserData API
GetTaskQueueUserDataResponse struct {
UserData *persistencespb.VersionedTaskQueueUserData
}
// UpdateTaskQueueUserDataRequest is the input type for the UpdateTaskQueueUserData API
UpdateTaskQueueUserDataRequest struct {
NamespaceID string
TaskQueue string
UserData *persistencespb.VersionedTaskQueueUserData
}
// ListTaskQueueRequest contains the request params needed to invoke ListTaskQueue API
ListTaskQueueRequest struct {
PageSize int
@@ -1120,6 +1138,16 @@ type (
// - UnknownNumRowsAffected (this means all rows below value are deleted)
// - number of rows deleted, which may be equal to limit
CompleteTasksLessThan(ctx context.Context, request *CompleteTasksLessThanRequest) (int, error)
// GetTaskQueueUserData gets versioned user data.
// This data would only exist if a user uses APIs that generate it, such as the worker versioning related APIs.
// The caller should be prepared to gracefully handle the "NotFound" service error.
GetTaskQueueUserData(ctx context.Context, request *GetTaskQueueUserDataRequest) (*GetTaskQueueUserDataResponse, error)
// UpdateTaskQueueUserData updates the user data for a given task queue.
// The request takes the _current_ known version along with the data to update.
// The caller should +1 increment the cached version number if this call succeeds.
// Fails with ConditionFailedError if the user data was updated concurrently.
UpdateTaskQueueUserData(ctx context.Context, request *UpdateTaskQueueUserDataRequest) error
}
// MetadataManager is used to manage metadata CRUD for namespace entities

View File

@@ -826,6 +826,21 @@ func (mr *MockTaskManagerMockRecorder) GetTaskQueue(ctx, request interface{}) *g
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueue", reflect.TypeOf((*MockTaskManager)(nil).GetTaskQueue), ctx, request)
}
// GetTaskQueueUserData mocks base method.
func (m *MockTaskManager) GetTaskQueueUserData(ctx context.Context, request *GetTaskQueueUserDataRequest) (*GetTaskQueueUserDataResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTaskQueueUserData", ctx, request)
ret0, _ := ret[0].(*GetTaskQueueUserDataResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTaskQueueUserData indicates an expected call of GetTaskQueueUserData.
func (mr *MockTaskManagerMockRecorder) GetTaskQueueUserData(ctx, request interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueUserData", reflect.TypeOf((*MockTaskManager)(nil).GetTaskQueueUserData), ctx, request)
}
// GetTasks mocks base method.
func (m *MockTaskManager) GetTasks(ctx context.Context, request *GetTasksRequest) (*GetTasksResponse, error) {
m.ctrl.T.Helper()
@@ -871,6 +886,20 @@ func (mr *MockTaskManagerMockRecorder) UpdateTaskQueue(ctx, request interface{})
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTaskQueue", reflect.TypeOf((*MockTaskManager)(nil).UpdateTaskQueue), ctx, request)
}
// UpdateTaskQueueUserData mocks base method.
func (m *MockTaskManager) UpdateTaskQueueUserData(ctx context.Context, request *UpdateTaskQueueUserDataRequest) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateTaskQueueUserData", ctx, request)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateTaskQueueUserData indicates an expected call of UpdateTaskQueueUserData.
func (mr *MockTaskManagerMockRecorder) UpdateTaskQueueUserData(ctx, request interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTaskQueueUserData", reflect.TypeOf((*MockTaskManager)(nil).UpdateTaskQueueUserData), ctx, request)
}
// MockMetadataManager is a mock of MetadataManager interface.
type MockMetadataManager struct {
ctrl *gomock.Controller

View File

@@ -279,6 +279,21 @@ func (mr *MockTaskStoreMockRecorder) GetTaskQueue(ctx, request interface{}) *gom
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueue", reflect.TypeOf((*MockTaskStore)(nil).GetTaskQueue), ctx, request)
}
// GetTaskQueueUserData mocks base method.
func (m *MockTaskStore) GetTaskQueueUserData(ctx context.Context, request *persistence.GetTaskQueueUserDataRequest) (*persistence.InternalGetTaskQueueUserDataResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTaskQueueUserData", ctx, request)
ret0, _ := ret[0].(*persistence.InternalGetTaskQueueUserDataResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTaskQueueUserData indicates an expected call of GetTaskQueueUserData.
func (mr *MockTaskStoreMockRecorder) GetTaskQueueUserData(ctx, request interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueUserData", reflect.TypeOf((*MockTaskStore)(nil).GetTaskQueueUserData), ctx, request)
}
// GetTasks mocks base method.
func (m *MockTaskStore) GetTasks(ctx context.Context, request *persistence.GetTasksRequest) (*persistence.InternalGetTasksResponse, error) {
m.ctrl.T.Helper()
@@ -324,6 +339,20 @@ func (mr *MockTaskStoreMockRecorder) UpdateTaskQueue(ctx, request interface{}) *
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTaskQueue", reflect.TypeOf((*MockTaskStore)(nil).UpdateTaskQueue), ctx, request)
}
// UpdateTaskQueueUserData mocks base method.
func (m *MockTaskStore) UpdateTaskQueueUserData(ctx context.Context, request *persistence.InternalUpdateTaskQueueUserDataRequest) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateTaskQueueUserData", ctx, request)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateTaskQueueUserData indicates an expected call of UpdateTaskQueueUserData.
func (mr *MockTaskStoreMockRecorder) UpdateTaskQueueUserData(ctx, request interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTaskQueueUserData", reflect.TypeOf((*MockTaskStore)(nil).UpdateTaskQueueUserData), ctx, request)
}
// MockMetadataStore is a mock of MetadataStore interface.
type MockMetadataStore struct {
ctrl *gomock.Controller

View File

@@ -72,6 +72,8 @@ type (
GetTasks(ctx context.Context, request *GetTasksRequest) (*InternalGetTasksResponse, error)
CompleteTask(ctx context.Context, request *CompleteTaskRequest) error
CompleteTasksLessThan(ctx context.Context, request *CompleteTasksLessThanRequest) (int, error)
GetTaskQueueUserData(ctx context.Context, request *GetTaskQueueUserDataRequest) (*InternalGetTaskQueueUserDataResponse, error)
UpdateTaskQueueUserData(ctx context.Context, request *InternalUpdateTaskQueueUserDataRequest) error
}
// MetadataStore is a lower level of MetadataManager
MetadataStore interface {
@@ -239,6 +241,11 @@ type (
TaskQueueInfo *commonpb.DataBlob
}
InternalGetTaskQueueUserDataResponse struct {
Version int64
UserData *commonpb.DataBlob
}
InternalUpdateTaskQueueRequest struct {
NamespaceID string
TaskQueue string
@@ -252,6 +259,13 @@ type (
PrevRangeID int64
}
InternalUpdateTaskQueueUserDataRequest struct {
NamespaceID string
TaskQueue string
Version int64
UserData *commonpb.DataBlob
}
InternalCreateTasksRequest struct {
NamespaceID string
TaskQueue string

View File

@@ -679,6 +679,34 @@ func (p *taskPersistenceClient) DeleteTaskQueue(
return p.persistence.DeleteTaskQueue(ctx, request)
}
func (p *taskPersistenceClient) GetTaskQueueUserData(
ctx context.Context,
request *GetTaskQueueUserDataRequest,
) (_ *GetTaskQueueUserDataResponse, retErr error) {
caller := headers.GetCallerInfo(ctx).CallerName
startTime := time.Now().UTC()
defer func() {
latency := time.Since(startTime)
p.healthSignals.Record(CallerSegmentMissing, latency, retErr)
p.recordRequestMetrics(metrics.PersistenceGetTaskQueueUserDataScope, caller, latency, retErr)
}()
return p.persistence.GetTaskQueueUserData(ctx, request)
}
func (p *taskPersistenceClient) UpdateTaskQueueUserData(
ctx context.Context,
request *UpdateTaskQueueUserDataRequest,
) (retErr error) {
caller := headers.GetCallerInfo(ctx).CallerName
startTime := time.Now().UTC()
defer func() {
latency := time.Since(startTime)
p.healthSignals.Record(CallerSegmentMissing, latency, retErr)
p.recordRequestMetrics(metrics.PersistenceUpdateTaskQueueUserDataScope, caller, latency, retErr)
}()
return p.persistence.UpdateTaskQueueUserData(ctx, request)
}
func (p *taskPersistenceClient) Close() {
p.persistence.Close()
}

View File

@@ -544,6 +544,26 @@ func (p *taskRateLimitedPersistenceClient) DeleteTaskQueue(
return p.persistence.DeleteTaskQueue(ctx, request)
}
func (p taskRateLimitedPersistenceClient) GetTaskQueueUserData(
ctx context.Context,
request *GetTaskQueueUserDataRequest,
) (*GetTaskQueueUserDataResponse, error) {
if ok := allow(ctx, "GetTaskQueueUserData", p.rateLimiter); !ok {
return nil, ErrPersistenceLimitExceeded
}
return p.persistence.GetTaskQueueUserData(ctx, request)
}
func (p taskRateLimitedPersistenceClient) UpdateTaskQueueUserData(
ctx context.Context,
request *UpdateTaskQueueUserDataRequest,
) error {
if ok := allow(ctx, "UpdateTaskQueueUserData", p.rateLimiter); !ok {
return ErrPersistenceLimitExceeded
}
return p.persistence.UpdateTaskQueueUserData(ctx, request)
}
func (p *taskRateLimitedPersistenceClient) Close() {
p.persistence.Close()
}

View File

@@ -776,6 +776,33 @@ func (p *taskRetryablePersistenceClient) DeleteTaskQueue(
return backoff.ThrottleRetryContext(ctx, op, p.policy, p.isRetryable)
}
func (p *taskRetryablePersistenceClient) GetTaskQueueUserData(
ctx context.Context,
request *GetTaskQueueUserDataRequest,
) (*GetTaskQueueUserDataResponse, error) {
var response *GetTaskQueueUserDataResponse
op := func(ctx context.Context) error {
var err error
response, err = p.persistence.GetTaskQueueUserData(ctx, request)
return err
}
err := backoff.ThrottleRetryContext(ctx, op, p.policy, p.isRetryable)
return response, err
}
func (p *taskRetryablePersistenceClient) UpdateTaskQueueUserData(
ctx context.Context,
request *UpdateTaskQueueUserDataRequest,
) error {
op := func(ctx context.Context) error {
return p.persistence.UpdateTaskQueueUserData(ctx, request)
}
err := backoff.ThrottleRetryContext(ctx, op, p.policy, p.isRetryable)
return err
}
func (p *taskRetryablePersistenceClient) Close() {
p.persistence.Close()
}

View File

@@ -97,6 +97,9 @@ type (
TaskQueueInfoToBlob(info *persistencespb.TaskQueueInfo, encodingType enumspb.EncodingType) (*commonpb.DataBlob, error)
TaskQueueInfoFromBlob(data *commonpb.DataBlob) (*persistencespb.TaskQueueInfo, error)
TaskQueueUserDataToBlob(info *persistencespb.TaskQueueUserData, encodingType enumspb.EncodingType) (*commonpb.DataBlob, error)
TaskQueueUserDataFromBlob(data *commonpb.DataBlob) (*persistencespb.TaskQueueUserData, error)
ChecksumToBlob(checksum *persistencespb.Checksum, encodingType enumspb.EncodingType) (*commonpb.DataBlob, error)
ChecksumFromBlob(data *commonpb.DataBlob) (*persistencespb.Checksum, error)
@@ -485,6 +488,15 @@ func (t *serializerImpl) TaskQueueInfoFromBlob(data *commonpb.DataBlob) (*persis
return result, ProtoDecodeBlob(data, result)
}
func (t *serializerImpl) TaskQueueUserDataToBlob(data *persistencespb.TaskQueueUserData, encodingType enumspb.EncodingType) (*commonpb.DataBlob, error) {
return ProtoEncodeBlob(data, encodingType)
}
func (t *serializerImpl) TaskQueueUserDataFromBlob(data *commonpb.DataBlob) (*persistencespb.TaskQueueUserData, error) {
result := &persistencespb.TaskQueueUserData{}
return result, ProtoDecodeBlob(data, result)
}
func (t *serializerImpl) ChecksumToBlob(checksum *persistencespb.Checksum, encodingType enumspb.EncodingType) (*commonpb.DataBlob, error) {
// nil is replaced with empty object because it is not supported for "checksum" field in DB.
if checksum == nil {

View File

@@ -51,6 +51,25 @@ type (
PageSize *int
}
GetTaskQueueUserDataRequest struct {
NamespaceID []byte
TaskQueueName string
}
UpdateTaskQueueDataRequest struct {
NamespaceID []byte
TaskQueueName string
Version int64
Data []byte
DataEncoding string
}
VersionedBlob struct {
Version int64
Data []byte
DataEncoding string
}
// MatchingTaskQueue is the SQL persistence interface for matching task queues
MatchingTaskQueue interface {
InsertIntoTaskQueues(ctx context.Context, row *TaskQueuesRow) (sql.Result, error)
@@ -62,5 +81,7 @@ type (
SelectFromTaskQueues(ctx context.Context, filter TaskQueuesFilter) ([]TaskQueuesRow, error)
DeleteFromTaskQueues(ctx context.Context, filter TaskQueuesFilter) (sql.Result, error)
LockTaskQueues(ctx context.Context, filter TaskQueuesFilter) (int64, error)
GetTaskQueueUserData(ctx context.Context, request *GetTaskQueueUserDataRequest) (*VersionedBlob, error)
UpdateTaskQueueUserData(ctx context.Context, request *UpdateTaskQueueDataRequest) error
}
)

View File

@@ -31,6 +31,7 @@ import (
"go.temporal.io/api/serviceerror"
"go.temporal.io/server/common/persistence"
"go.temporal.io/server/common/persistence/sql/sqlplugin"
)
@@ -87,6 +88,21 @@ task_queue_id = :task_queue_id
rangeDeleteTaskQry = `DELETE FROM tasks ` +
`WHERE range_hash = ? AND task_queue_id = ? AND task_id < ? ` +
`ORDER BY task_queue_id,task_id LIMIT ?`
getTaskQueueUserDataQry = `SELECT data, data_encoding, version FROM task_queue_user_data ` +
`WHERE namespace_id = ? AND task_queue_name = ?`
updateTaskQueueUserDataQry = `UPDATE task_queue_user_data SET ` +
`data = ?, ` +
`data_encoding = ?, ` +
`version = ? ` +
`WHERE namespace_id = ? ` +
`AND task_queue_name = ? ` +
`AND version = ?`
insertTaskQueueUserDataQry = `INSERT INTO task_queue_user_data` +
`(namespace_id, task_queue_name, data, data_encoding, version) ` +
`VALUES (?, ?, ?, ?, 1)`
)
// InsertIntoTasks inserts one or more rows into tasks table
@@ -278,3 +294,42 @@ func (mdb *db) LockTaskQueues(
)
return rangeID, err
}
func (mdb *db) GetTaskQueueUserData(ctx context.Context, request *sqlplugin.GetTaskQueueUserDataRequest) (*sqlplugin.VersionedBlob, error) {
var row sqlplugin.VersionedBlob
err := mdb.conn.GetContext(ctx, &row, getTaskQueueUserDataQry, request.NamespaceID, request.TaskQueueName)
return &row, err
}
func (mdb *db) UpdateTaskQueueUserData(ctx context.Context, request *sqlplugin.UpdateTaskQueueDataRequest) error {
if request.Version == 0 {
_, err := mdb.conn.ExecContext(
ctx,
insertTaskQueueUserDataQry,
request.NamespaceID,
request.TaskQueueName,
request.Data,
request.DataEncoding)
return err
}
result, err := mdb.conn.ExecContext(
ctx,
updateTaskQueueUserDataQry,
request.Data,
request.DataEncoding,
request.Version+1,
request.NamespaceID,
request.TaskQueueName,
request.Version)
if err != nil {
return err
}
numRows, err := result.RowsAffected()
if err != nil {
return err
}
if numRows != 1 {
return &persistence.ConditionFailedError{Msg: "Expected exactly one row to be updated"}
}
return nil
}

View File

@@ -31,6 +31,7 @@ import (
"go.temporal.io/api/serviceerror"
"go.temporal.io/server/common/persistence"
"go.temporal.io/server/common/persistence/sql/sqlplugin"
)
@@ -88,6 +89,21 @@ task_queue_id = :task_queue_id
`WHERE range_hash = $1 AND task_queue_id = $2 AND task_id IN (SELECT task_id FROM
tasks WHERE range_hash = $1 AND task_queue_id = $2 AND task_id < $3 ` +
`ORDER BY task_queue_id,task_id LIMIT $4 )`
getTaskQueueUserDataQry = `SELECT data, data_encoding, version FROM task_queue_user_data ` +
`WHERE namespace_id = $1 AND task_queue_name = $2`
updateTaskQueueUserDataQry = `UPDATE task_queue_user_data SET ` +
`data = $1, ` +
`data_encoding = $2, ` +
`version = $3 ` +
`WHERE namespace_id = $4 ` +
`AND task_queue_name = $5 ` +
`AND version = $6`
insertTaskQueueUserDataQry = `INSERT INTO task_queue_user_data` +
`(namespace_id, task_queue_name, data, data_encoding, version) ` +
`VALUES ($1, $2, $3, $4, 1)`
)
// InsertIntoTasks inserts one or more rows into tasks table
@@ -278,3 +294,42 @@ func (pdb *db) LockTaskQueues(
)
return rangeID, err
}
func (pdb *db) GetTaskQueueUserData(ctx context.Context, request *sqlplugin.GetTaskQueueUserDataRequest) (*sqlplugin.VersionedBlob, error) {
var row sqlplugin.VersionedBlob
err := pdb.conn.GetContext(ctx, &row, getTaskQueueUserDataQry, request.NamespaceID, request.TaskQueueName)
return &row, err
}
func (pdb *db) UpdateTaskQueueUserData(ctx context.Context, request *sqlplugin.UpdateTaskQueueDataRequest) error {
if request.Version == 0 {
_, err := pdb.conn.ExecContext(
ctx,
insertTaskQueueUserDataQry,
request.NamespaceID,
request.TaskQueueName,
request.Data,
request.DataEncoding)
return err
}
result, err := pdb.conn.ExecContext(
ctx,
updateTaskQueueUserDataQry,
request.Data,
request.DataEncoding,
request.Version+1,
request.NamespaceID,
request.TaskQueueName,
request.Version)
if err != nil {
return err
}
numRows, err := result.RowsAffected()
if err != nil {
return err
}
if numRows != 1 {
return &persistence.ConditionFailedError{Msg: "Expected exactly one row to be updated"}
}
return nil
}

View File

@@ -33,6 +33,7 @@ import (
"go.temporal.io/api/serviceerror"
"go.temporal.io/server/common/persistence"
"go.temporal.io/server/common/persistence/sql/sqlplugin"
)
@@ -90,6 +91,21 @@ task_queue_id = :task_queue_id
`WHERE range_hash = ? AND task_queue_id = ? AND task_id IN (SELECT task_id FROM
tasks WHERE range_hash = ? AND task_queue_id = ? AND task_id < ? ` +
`ORDER BY task_queue_id,task_id LIMIT ? ) `
getTaskQueueUserDataQry = `SELECT data, data_encoding, version FROM task_queue_user_data ` +
`WHERE namespace_id = ? AND task_queue_name = ?`
updateTaskQueueUserDataQry = `UPDATE task_queue_user_data SET ` +
`data = ?, ` +
`data_encoding = ?, ` +
`version = ? ` +
`WHERE namespace_id = ? ` +
`AND task_queue_name = ? ` +
`AND version = ?`
insertTaskQueueUserDataQry = `INSERT INTO task_queue_user_data` +
`(namespace_id, task_queue_name, data, data_encoding, version) ` +
`VALUES (?, ?, ?, ?, 1)`
)
// InsertIntoTasks inserts one or more rows into tasks table
@@ -283,3 +299,42 @@ func (mdb *db) LockTaskQueues(
)
return rangeID, err
}
func (mdb *db) GetTaskQueueUserData(ctx context.Context, request *sqlplugin.GetTaskQueueUserDataRequest) (*sqlplugin.VersionedBlob, error) {
var row sqlplugin.VersionedBlob
err := mdb.conn.GetContext(ctx, &row, getTaskQueueUserDataQry, request.NamespaceID, request.TaskQueueName)
return &row, err
}
func (mdb *db) UpdateTaskQueueUserData(ctx context.Context, request *sqlplugin.UpdateTaskQueueDataRequest) error {
if request.Version == 0 {
_, err := mdb.conn.ExecContext(
ctx,
insertTaskQueueUserDataQry,
request.NamespaceID,
request.TaskQueueName,
request.Data,
request.DataEncoding)
return err
}
result, err := mdb.conn.ExecContext(
ctx,
updateTaskQueueUserDataQry,
request.Data,
request.DataEncoding,
request.Version+1,
request.NamespaceID,
request.TaskQueueName,
request.Version)
if err != nil {
return err
}
numRows, err := result.RowsAffected()
if err != nil {
return err
}
if numRows != 1 {
return &persistence.ConditionFailedError{Msg: "Expected exactly one row to be updated"}
}
return nil
}

View File

@@ -477,6 +477,45 @@ func (m *sqlTaskManager) CompleteTasksLessThan(
return int(nRows), nil
}
func (m *sqlTaskManager) GetTaskQueueUserData(ctx context.Context, request *persistence.GetTaskQueueUserDataRequest) (*persistence.InternalGetTaskQueueUserDataResponse, error) {
namespaceID, err := primitives.ParseUUID(request.NamespaceID)
if err != nil {
return nil, serviceerror.NewInternal(fmt.Sprintf("failed to parse namespace ID as UUID: %v", err))
}
response, err := m.Db.GetTaskQueueUserData(ctx, &sqlplugin.GetTaskQueueUserDataRequest{
NamespaceID: namespaceID,
TaskQueueName: request.TaskQueue,
})
if err != nil {
if err == sql.ErrNoRows {
return nil, serviceerror.NewNotFound(fmt.Sprintf("task queue user data not found for %v.%v", request.NamespaceID, request.TaskQueue))
}
return nil, err
}
return &persistence.InternalGetTaskQueueUserDataResponse{
Version: response.Version,
UserData: persistence.NewDataBlob(response.Data, response.DataEncoding),
}, nil
}
func (m *sqlTaskManager) UpdateTaskQueueUserData(ctx context.Context, request *persistence.InternalUpdateTaskQueueUserDataRequest) error {
namespaceID, err := primitives.ParseUUID(request.NamespaceID)
if err != nil {
return serviceerror.NewInternal(fmt.Sprintf("failed to parse namespace ID as UUID: %v", err))
}
err = m.Db.UpdateTaskQueueUserData(ctx, &sqlplugin.UpdateTaskQueueDataRequest{
NamespaceID: namespaceID,
TaskQueueName: request.TaskQueue,
Data: request.UserData.Data,
DataEncoding: request.UserData.EncodingType.String(),
Version: request.Version,
})
if m.Db.IsDupEntryError(err) {
return &persistence.ConditionFailedError{Msg: err.Error()}
}
return err
}
// Returns uint32 hash for a particular TaskQueue/Task given a Namespace, TaskQueueName and TaskQueueType
func (m *sqlTaskManager) taskQueueIdAndHash(
namespaceID primitives.UUID,

View File

@@ -248,3 +248,31 @@ func (m *taskManagerImpl) CompleteTasksLessThan(
) (int, error) {
return m.taskStore.CompleteTasksLessThan(ctx, request)
}
// GetTaskQueueUserData implements TaskManager
func (m *taskManagerImpl) GetTaskQueueUserData(ctx context.Context, request *GetTaskQueueUserDataRequest) (*GetTaskQueueUserDataResponse, error) {
response, err := m.taskStore.GetTaskQueueUserData(ctx, request)
if err != nil {
return nil, err
}
data, err := m.serializer.TaskQueueUserDataFromBlob(response.UserData)
if err != nil {
return nil, err
}
return &GetTaskQueueUserDataResponse{UserData: &persistencespb.VersionedTaskQueueUserData{Version: response.Version, Data: data}}, nil
}
// UpdateTaskQueueUserData implements TaskManager
func (m *taskManagerImpl) UpdateTaskQueueUserData(ctx context.Context, request *UpdateTaskQueueUserDataRequest) error {
userData, err := m.serializer.TaskQueueUserDataToBlob(request.UserData.Data, enumspb.ENCODING_TYPE_PROTO3)
if err != nil {
return err
}
internalRequest := &InternalUpdateTaskQueueUserDataRequest{
NamespaceID: request.NamespaceID,
TaskQueue: request.TaskQueue,
Version: request.UserData.Version,
UserData: userData,
}
return m.taskStore.UpdateTaskQueueUserData(ctx, internalRequest)
}

View File

@@ -37,7 +37,7 @@ import "temporal/api/protocol/v1/message.proto";
import "temporal/server/api/clock/v1/message.proto";
import "temporal/server/api/enums/v1/task.proto";
import "temporal/server/api/history/v1/message.proto";
import "temporal/server/api/persistence/v1/tasks.proto";
import "temporal/server/api/persistence/v1/task_queues.proto";
import "temporal/api/workflowservice/v1/request_response.proto";
@@ -203,32 +203,29 @@ message GetWorkerBuildIdCompatibilityResponse {
temporal.api.workflowservice.v1.GetWorkerBuildIdCompatibilityResponse response = 1;
}
message InvalidateTaskQueueMetadataRequest {
message InvalidateTaskQueueUserDataRequest {
string namespace_id = 1;
string task_queue = 2;
temporal.api.enums.v1.TaskQueueType task_queue_type = 3;
// The task queue versioning data should be invalidated and replaced with this data, if set.
temporal.server.api.persistence.v1.VersioningData versioning_data = 4;
// The partition's cached user data should be invalidated and replaced with this data, if set.
temporal.server.api.persistence.v1.VersionedTaskQueueUserData user_data = 4;
}
message InvalidateTaskQueueMetadataResponse {}
message InvalidateTaskQueueUserDataResponse {}
message GetTaskQueueMetadataRequest {
message GetTaskQueueUserDataRequest {
string namespace_id = 1;
// The task queue to fetch data from. Is always considered as a workflow queue, since root
// workflow queues own the metadata.
string task_queue = 2;
// If set nonempty, the requester wants the latest versioning data. The value must be the hash
// (using farm hash Fingerprint64) of the latest versioning data. If the requester has no data,
// it can use any invalid value (ex: [0]).
// If the data is up to date, no value will be returned.
bytes want_versioning_data_curhash = 3;
// The value of the last known user data version.
// If the requester has no data, it should set this to 0.
// This value must not be set to a negative number (note that our linter suggests avoiding uint64).
int64 last_known_user_data_version = 3;
}
message GetTaskQueueMetadataResponse {
oneof versioning_data_resp {
// The latest versioning data, if the request's hash did not match. May be null if no
// versioning data exists.
temporal.server.api.persistence.v1.VersioningData versioning_data = 1;
// If the request's hash matched, this variant is set (and will be true).
bool matched_req_hash = 2;
}
message GetTaskQueueUserDataResponse {
// Whether this task queue has any stored user data
bool task_queue_has_user_data = 1;
// Versioned user data, set if the task queue has user data and the request's last_known_user_data_version is less
// than the version cached in the root partition.
temporal.server.api.persistence.v1.VersionedTaskQueueUserData user_data = 2;
}

View File

@@ -85,8 +85,8 @@ service MatchingService {
// aip.dev/not-precedent: UpdateWorkerBuildIdOrdering RPC doesn't follow Google API format. --)
rpc UpdateWorkerBuildIdCompatibility (UpdateWorkerBuildIdCompatibilityRequest) returns (UpdateWorkerBuildIdCompatibilityResponse) {}
rpc GetWorkerBuildIdCompatibility (GetWorkerBuildIdCompatibilityRequest) returns (GetWorkerBuildIdCompatibilityResponse) {}
// Tell a task queue that some metadata has changed.
rpc InvalidateTaskQueueMetadata (InvalidateTaskQueueMetadataRequest) returns (InvalidateTaskQueueMetadataResponse) {}
// Fetch some metadata about a task queue.
rpc GetTaskQueueMetadata (GetTaskQueueMetadataRequest) returns (GetTaskQueueMetadataResponse) {}
// Tell a task queue that the associated user data has changed.
rpc InvalidateTaskQueueUserData (InvalidateTaskQueueUserDataRequest) returns (InvalidateTaskQueueUserDataResponse) {}
// Fetch user data for a task queue, this request should always be routed to the node holding the task queue's root partition.
rpc GetTaskQueueUserData (GetTaskQueueUserDataRequest) returns (GetTaskQueueUserDataResponse) {}
}

View File

@@ -84,3 +84,9 @@ message TaskQueueUserData {
// For future use: description, rate limits, manual partition control, etc...
}
// Simple wrapper that includes a TaskQueueUserData and its storage version.
message VersionedTaskQueueUserData {
TaskQueueUserData data = 1;
int64 version = 2;
}

View File

@@ -0,0 +1,6 @@
{
"CurrVersion": "1.21",
"MinCompatibleVersion": "1.0",
"Description": "create task_queue_user_data table",
"SchemaUpdateCqlFiles": ["task_queue_user_data.cql"]
}

View File

@@ -0,0 +1,15 @@
-- Stores task queue information such as user provided versioning data
CREATE TABLE task_queue_user_data (
namespace_id uuid,
task_queue_name text,
data blob, -- temporal.server.api.persistence.v1.TaskQueueUserData
data_encoding text, -- Encoding type used for serialization, in practice this should always be proto3
version bigint, -- Version of this row, used for optimistic concurrency
-- task_queue_name is not a part of the parititioning key to allow cheaply iterating all task queues in a single
-- namespace. Access to this table should be infrequent enough that a single partition per namespace can be used.
-- Note that this imposes a limit on total task queue user data within one namespace (see the relevant single
-- partition Cassandra limits).
PRIMARY KEY ((namespace_id), task_queue_name)
) WITH COMPACTION = {
'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'
};

View File

@@ -0,0 +1,6 @@
{
"CurrVersion": "1.21",
"MinCompatibleVersion": "1.0",
"Description": "create task_queue_user_data table",
"SchemaUpdateCqlFiles": ["task_queue_user_data.sql"]
}

View File

@@ -0,0 +1,9 @@
-- Stores task queue information such as user provided versioning data
CREATE TABLE task_queue_user_data (
namespace_id BINARY(16) NOT NULL,
task_queue_name VARCHAR(255) NOT NULL,
data MEDIUMBLOB NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
PRIMARY KEY (namespace_id, task_queue_name)
);

View File

@@ -27,7 +27,7 @@ package v57
// NOTE: whenever there is a new database schema update, plz update the following versions
// Version is the MySQL database release version
const Version = "1.10"
const Version = "1.21"
// VisibilityVersion is the MySQL visibility database release version
const VisibilityVersion = "1.1"

View File

@@ -0,0 +1,6 @@
{
"CurrVersion": "1.21",
"MinCompatibleVersion": "1.0",
"Description": "create task_queue_user_data table",
"SchemaUpdateCqlFiles": ["task_queue_user_data.sql"]
}

View File

@@ -0,0 +1,9 @@
-- Stores task queue information such as user provided versioning data
CREATE TABLE task_queue_user_data (
namespace_id BINARY(16) NOT NULL,
task_queue_name VARCHAR(255) NOT NULL,
data MEDIUMBLOB NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
PRIMARY KEY (namespace_id, task_queue_name)
);

View File

@@ -27,7 +27,7 @@ package v8
// NOTE: whenever there is a new database schema update, plz update the following versions
// Version is the MySQL database release version
const Version = "1.10"
const Version = "1.21"
// VisibilityVersion is the MySQL visibility database release version
const VisibilityVersion = "1.3"

View File

@@ -0,0 +1,6 @@
{
"CurrVersion": "1.21",
"MinCompatibleVersion": "1.0",
"Description": "create task_queue_user_data table",
"SchemaUpdateCqlFiles": ["task_queue_user_data.sql"]
}

View File

@@ -0,0 +1,9 @@
-- Stores task queue information such as user provided versioning data
CREATE TABLE task_queue_user_data (
namespace_id BYTEA NOT NULL,
task_queue_name VARCHAR(255) NOT NULL,
data BYTEA NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
PRIMARY KEY (namespace_id, task_queue_name)
);

View File

@@ -0,0 +1,6 @@
{
"CurrVersion": "1.21",
"MinCompatibleVersion": "1.0",
"Description": "create task_queue_user_data table",
"SchemaUpdateCqlFiles": ["task_queue_user_data.sql"]
}

View File

@@ -0,0 +1,9 @@
-- Stores task queue information such as user provided versioning data
CREATE TABLE task_queue_user_data (
namespace_id BYTEA NOT NULL,
task_queue_name VARCHAR(255) NOT NULL,
data BYTEA NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
PRIMARY KEY (namespace_id, task_queue_name)
);

View File

@@ -0,0 +1,6 @@
{
"CurrVersion": "1.21",
"MinCompatibleVersion": "1.0",
"Description": "create task_queue_user_data table",
"SchemaUpdateCqlFiles": ["task_queue_user_data.sql"]
}

View File

@@ -0,0 +1,9 @@
-- Stores task queue information such as user provided versioning data
CREATE TABLE task_queue_user_data (
namespace_id BINARY(16) NOT NULL,
task_queue_name VARCHAR(255) NOT NULL,
data MEDIUMBLOB NOT NULL, -- temporal.server.api.persistence.v1.TaskQueueUserData
data_encoding VARCHAR(16) NOT NULL, -- Encoding type used for serialization, in practice this should always be proto3
version BIGINT NOT NULL, -- Version of this row, used for optimistic concurrency
PRIMARY KEY (namespace_id, task_queue_name)
);

View File

@@ -47,18 +47,19 @@ type (
// taskQueueManager configuration
RangeSize int64
GetTasksBatchSize dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
UpdateAckInterval dynamicconfig.DurationPropertyFnWithTaskQueueInfoFilters
MaxTaskQueueIdleTime dynamicconfig.DurationPropertyFnWithTaskQueueInfoFilters
NumTaskqueueWritePartitions dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
NumTaskqueueReadPartitions dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxOutstandingPolls dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxOutstandingTasks dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxRatePerSecond dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxChildrenPerNode dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
MaxVersionGraphSize dynamicconfig.IntPropertyFn
MetadataPollFrequency dynamicconfig.DurationPropertyFn
RangeSize int64
GetTasksBatchSize dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
UpdateAckInterval dynamicconfig.DurationPropertyFnWithTaskQueueInfoFilters
MaxTaskQueueIdleTime dynamicconfig.DurationPropertyFnWithTaskQueueInfoFilters
NumTaskqueueWritePartitions dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
NumTaskqueueReadPartitions dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxOutstandingPolls dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxOutstandingTasks dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxRatePerSecond dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
ForwarderMaxChildrenPerNode dynamicconfig.IntPropertyFnWithTaskQueueInfoFilters
VersionCompatibleSetLimitPerQueue dynamicconfig.IntPropertyFn
VersionBuildIDLimitPerQueue dynamicconfig.IntPropertyFn
UserDataPollFrequency dynamicconfig.DurationPropertyFn
// Time to hold a poll request before returning an empty response if there are no tasks
LongPollExpirationInterval dynamicconfig.DurationPropertyFnWithTaskQueueInfoFilters
@@ -146,8 +147,9 @@ func NewConfig(dc *dynamicconfig.Collection) *Config {
ForwarderMaxRatePerSecond: dc.GetIntPropertyFilteredByTaskQueueInfo(dynamicconfig.MatchingForwarderMaxRatePerSecond, 10),
ForwarderMaxChildrenPerNode: dc.GetIntPropertyFilteredByTaskQueueInfo(dynamicconfig.MatchingForwarderMaxChildrenPerNode, 20),
ShutdownDrainDuration: dc.GetDurationProperty(dynamicconfig.MatchingShutdownDrainDuration, 0*time.Second),
MaxVersionGraphSize: dc.GetIntProperty(dynamicconfig.VersionGraphNodeLimit, 1000),
MetadataPollFrequency: dc.GetDurationProperty(dynamicconfig.MatchingMetadataPollFrequency, 5*time.Minute),
VersionCompatibleSetLimitPerQueue: dc.GetIntProperty(dynamicconfig.VersionCompatibleSetLimitPerQueue, 10),
VersionBuildIDLimitPerQueue: dc.GetIntProperty(dynamicconfig.VersionBuildIDLimitPerQueue, 1000),
UserDataPollFrequency: dc.GetDurationProperty(dynamicconfig.MatchingUserDataPollFrequency, 5*time.Minute),
AdminNamespaceToPartitionDispatchRate: dc.GetFloatPropertyFilteredByNamespace(dynamicconfig.AdminMatchingNamespaceToPartitionDispatchRate, 10000),
AdminNamespaceTaskqueueToPartitionDispatchRate: dc.GetFloatPropertyFilteredByTaskQueueInfo(dynamicconfig.AdminMatchingNamespaceTaskqueueToPartitionDispatchRate, 1000),

View File

@@ -41,8 +41,8 @@ var (
"RespondQueryTaskCompleted": 0,
"GetWorkerBuildIdCompatibility": 0,
"UpdateWorkerBuildIdCompatibility": 0,
"InvalidateTaskQueueMetadata": 0,
"GetTaskQueueMetadata": 0,
"InvalidateTaskQueueUserData": 0,
"GetTaskQueueUserData": 0,
}
APIPrioritiesOrdered = []int{0}

View File

@@ -50,14 +50,14 @@ const (
type (
taskQueueDB struct {
sync.Mutex
namespaceID namespace.ID
taskQueue *taskQueueID
taskQueueKind enumspb.TaskQueueKind
rangeID int64
ackLevel int64
versioningData *persistencespb.VersioningData
store persistence.TaskManager
logger log.Logger
namespaceID namespace.ID
taskQueue *taskQueueID
taskQueueKind enumspb.TaskQueueKind
rangeID int64
ackLevel int64
userData *persistencespb.VersionedTaskQueueUserData
store persistence.TaskManager
logger log.Logger
}
taskQueueState struct {
rangeID int64
@@ -66,8 +66,8 @@ type (
)
var (
errVersioningDataNotPresentOnPartition = errors.New("versioning data is only present on root workflow partition")
errVersioningDataNoMutateNonRoot = errors.New("can only mutate versioning data on root workflow task queue")
errUserDataNotPresentOnPartition = errors.New("user data is only present on root workflow partition")
errVersioningDataNoMutateNonRoot = errors.New("can only mutate versioning data on root workflow task queue")
)
// newTaskQueueDB returns an instance of an object that represents
@@ -130,7 +130,7 @@ func (db *taskQueueDB) takeOverTaskQueueLocked(
response.TaskQueueInfo.Kind = db.taskQueueKind
response.TaskQueueInfo.ExpiryTime = db.expiryTime()
response.TaskQueueInfo.LastUpdateTime = timestamp.TimeNowPtrUtc()
_, err := db.updateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
_, err := db.store.UpdateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
RangeID: response.RangeID + 1,
TaskQueueInfo: response.TaskQueueInfo,
PrevRangeID: response.RangeID,
@@ -140,8 +140,11 @@ func (db *taskQueueDB) takeOverTaskQueueLocked(
}
db.ackLevel = response.TaskQueueInfo.AckLevel
db.rangeID = response.RangeID + 1
db.versioningData = response.TaskQueueInfo.VersioningData
return nil
_, err = db.getUserDataLocked(ctx)
if errors.Is(err, errUserDataNotPresentOnPartition) {
return nil
}
return err
case *serviceerror.NotFound:
if _, err := db.store.CreateTaskQueue(ctx, &persistence.CreateTaskQueueRequest{
@@ -151,7 +154,11 @@ func (db *taskQueueDB) takeOverTaskQueueLocked(
return err
}
db.rangeID = initialRangeID
return nil
_, err = db.getUserDataLocked(ctx)
if errors.Is(err, errUserDataNotPresentOnPartition) {
return nil
}
return err
default:
return err
@@ -162,7 +169,7 @@ func (db *taskQueueDB) renewTaskQueueLocked(
ctx context.Context,
rangeID int64,
) error {
if _, err := db.updateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
if _, err := db.store.UpdateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
RangeID: rangeID,
TaskQueueInfo: db.cachedQueueInfo(),
PrevRangeID: db.rangeID,
@@ -183,7 +190,7 @@ func (db *taskQueueDB) UpdateState(
defer db.Unlock()
queueInfo := db.cachedQueueInfo()
queueInfo.AckLevel = ackLevel
_, err := db.updateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
_, err := db.store.UpdateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
RangeID: db.rangeID,
TaskQueueInfo: queueInfo,
PrevRangeID: db.rangeID,
@@ -281,99 +288,85 @@ func (db *taskQueueDB) CompleteTasksLessThan(
return n, err
}
// GetVersioningData returns the versioning data for this task queue. Do not mutate the returned pointer, as doing so
// GetUserData returns the versioning data for this task queue. Do not mutate the returned pointer, as doing so
// will cause cache inconsistency.
func (db *taskQueueDB) GetVersioningData(
func (db *taskQueueDB) GetUserData(
ctx context.Context,
) (*persistencespb.VersioningData, error) {
) (*persistencespb.VersionedTaskQueueUserData, error) {
db.Lock()
defer db.Unlock()
return db.getVersioningDataLocked(ctx)
return db.getUserDataLocked(ctx)
}
// db.Lock() must be held before calling
func (db *taskQueueDB) getVersioningDataLocked(
// db.Lock() must be held before calling.
// Returns in-memory cached value or reads from DB and updates the cached value.
func (db *taskQueueDB) getUserDataLocked(
ctx context.Context,
) (*persistencespb.VersioningData, error) {
if db.versioningData != nil {
return db.versioningData, nil
) (*persistencespb.VersionedTaskQueueUserData, error) {
if db.userData == nil {
if !db.taskQueue.IsRoot() || db.taskQueue.taskType != enumspb.TASK_QUEUE_TYPE_WORKFLOW {
return nil, errUserDataNotPresentOnPartition
}
response, err := db.store.GetTaskQueueUserData(ctx, &persistence.GetTaskQueueUserDataRequest{
NamespaceID: db.namespaceID.String(),
TaskQueue: db.taskQueue.BaseNameString(),
})
if err != nil {
var notFoundError *serviceerror.NotFound
if errors.As(err, &notFoundError) {
return nil, nil
}
return nil, err
}
db.userData = response.UserData
}
if !db.taskQueue.IsRoot() || db.taskQueue.taskType != enumspb.TASK_QUEUE_TYPE_WORKFLOW {
return nil, errVersioningDataNotPresentOnPartition
}
tqInfo, err := db.store.GetTaskQueue(ctx, &persistence.GetTaskQueueRequest{
NamespaceID: db.namespaceID.String(),
TaskQueue: db.taskQueue.FullName(),
TaskType: db.taskQueue.taskType,
})
if err != nil {
return nil, err
}
db.versioningData = tqInfo.TaskQueueInfo.GetVersioningData()
return tqInfo.TaskQueueInfo.GetVersioningData(), nil
return db.userData, nil
}
// MutateVersioningData allows callers to update versioning data for this task queue. The pointer passed to the
// mutating function is guaranteed to be non-nil.
// UpdateUserData allows callers to update user data (such as worker build IDs) for this task queue. The pointer passed
// to the update function is guaranteed to be non-nil.
// Note that the user data's clock may be nil and should be initialized externally where there's access to the cluster
// metadata and the cluster ID can be obtained.
//
// On success returns a pointer to the updated data (which must not be mutated).
func (db *taskQueueDB) MutateVersioningData(ctx context.Context, mutator func(*persistencespb.VersioningData) error) (*persistencespb.VersioningData, error) {
// On success returns a pointer to the updated data, which must *not* be mutated.
func (db *taskQueueDB) UpdateUserData(ctx context.Context, updateFn func(*persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error)) (*persistencespb.VersionedTaskQueueUserData, error) {
if !db.taskQueue.IsRoot() || db.taskQueue.taskType != enumspb.TASK_QUEUE_TYPE_WORKFLOW {
return nil, errVersioningDataNoMutateNonRoot
}
db.Lock()
defer db.Unlock()
verDat, err := db.getVersioningDataLocked(ctx)
userData, err := db.getUserDataLocked(ctx)
if err != nil {
return nil, err
}
if verDat == nil {
verDat = &persistencespb.VersioningData{}
preUpdateData := userData.GetData()
if preUpdateData == nil {
preUpdateData = &persistencespb.TaskQueueUserData{}
}
if err := mutator(verDat); err != nil {
updatedUserData, err := updateFn(preUpdateData)
if err != nil {
return nil, err
}
queueInfo := db.cachedQueueInfo()
queueInfo.VersioningData = verDat
_, err = db.updateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{
RangeID: db.rangeID,
TaskQueueInfo: queueInfo,
PrevRangeID: db.rangeID,
err = db.store.UpdateTaskQueueUserData(ctx, &persistence.UpdateTaskQueueUserDataRequest{
NamespaceID: db.namespaceID.String(),
TaskQueue: db.cachedQueueInfo().Name,
UserData: &persistencespb.VersionedTaskQueueUserData{Version: userData.GetVersion(), Data: updatedUserData},
})
if err == nil {
db.versioningData = verDat
db.userData = &persistencespb.VersionedTaskQueueUserData{Version: userData.GetVersion() + 1, Data: updatedUserData}
}
return verDat, err
// TODO: Put a message in the namespace replication queue
return db.userData, err
}
func (db *taskQueueDB) setVersioningDataForNonRootPartition(verDat *persistencespb.VersioningData) {
func (db *taskQueueDB) setUserDataForNonRootPartition(userData *persistencespb.VersionedTaskQueueUserData) {
db.Lock()
defer db.Unlock()
db.versioningData = verDat
}
// Use this rather than calling UpdateTaskQueue directly on the store
func (db *taskQueueDB) updateTaskQueue(
ctx context.Context,
request *persistence.UpdateTaskQueueRequest,
) (*persistence.UpdateTaskQueueResponse, error) {
reqToPersist := request
// Only the root task queue stores versioning information
if !db.taskQueue.IsRoot() {
tqInfoSansVerDat := *request.TaskQueueInfo
tqInfoSansVerDat.VersioningData = nil
reqClone := *request
reqClone.TaskQueueInfo = &tqInfoSansVerDat
reqToPersist = &reqClone
}
return db.store.UpdateTaskQueue(ctx, reqToPersist)
db.userData = userData
}
func (db *taskQueueDB) expiryTime() *time.Time {
@@ -394,7 +387,6 @@ func (db *taskQueueDB) cachedQueueInfo() *persistencespb.TaskQueueInfo {
TaskType: db.taskQueue.taskType,
Kind: db.taskQueueKind,
AckLevel: db.ackLevel,
VersioningData: db.versioningData,
ExpiryTime: db.expiryTime(),
LastUpdateTime: timestamp.TimeNowPtrUtc(),
}

View File

@@ -308,20 +308,20 @@ func (h *Handler) GetWorkerBuildIdCompatibility(
}
// InvalidateTaskQueueMetadata notifies a task queue that some data has changed, and should be invalidated/refreshed
func (h *Handler) InvalidateTaskQueueMetadata(
func (h *Handler) InvalidateTaskQueueUserData(
ctx context.Context,
request *matchingservice.InvalidateTaskQueueMetadataRequest,
) (_ *matchingservice.InvalidateTaskQueueMetadataResponse, retError error) {
request *matchingservice.InvalidateTaskQueueUserDataRequest,
) (_ *matchingservice.InvalidateTaskQueueUserDataResponse, retError error) {
defer log.CapturePanic(h.logger, &retError)
return h.engine.InvalidateTaskQueueMetadata(ctx, request)
return h.engine.InvalidateTaskQueueUserData(ctx, request)
}
func (h *Handler) GetTaskQueueMetadata(
func (h *Handler) GetTaskQueueUserData(
ctx context.Context,
request *matchingservice.GetTaskQueueMetadataRequest,
) (_ *matchingservice.GetTaskQueueMetadataResponse, retError error) {
request *matchingservice.GetTaskQueueUserDataRequest,
) (_ *matchingservice.GetTaskQueueUserDataResponse, retError error) {
defer log.CapturePanic(h.logger, &retError)
return h.engine.GetTaskQueueMetadata(ctx, request)
return h.engine.GetTaskQueueUserData(ctx, request)
}
func (h *Handler) namespaceName(id namespace.ID) namespace.Name {

View File

@@ -723,8 +723,28 @@ func (e *matchingEngineImpl) UpdateWorkerBuildIdCompatibility(
if err != nil {
return nil, err
}
err = tqMgr.MutateVersioningData(ctx, func(data *persistencespb.VersioningData) error {
return UpdateVersionSets(data, req.GetRequest(), e.config.MaxVersionGraphSize())
err = tqMgr.UpdateUserData(ctx, func(data *persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error) {
clock := data.GetClock()
if clock == nil {
tmp := zeroHLC(e.clusterMeta.GetClusterID())
clock = &tmp
}
updatedClock, versioningData, err := UpdateVersionSets(
*clock,
data.GetVersioningData(),
req.GetRequest(),
e.config.VersionCompatibleSetLimitPerQueue(),
e.config.VersionBuildIDLimitPerQueue(),
)
if err != nil {
return nil, err
}
// Avoid mutation
ret := *data
ret.Clock = &updatedClock
ret.VersioningData = versioningData
return &ret, nil
})
if err != nil {
return nil, err
@@ -749,7 +769,7 @@ func (e *matchingEngineImpl) GetWorkerBuildIdCompatibility(
}
return nil, err
}
verDat, err := tqMgr.GetVersioningData(ctx)
userData, err := tqMgr.GetUserData(ctx)
if err != nil {
if _, ok := err.(*serviceerror.NotFound); ok {
return &matchingservice.GetWorkerBuildIdCompatibilityResponse{}, nil
@@ -757,14 +777,14 @@ func (e *matchingEngineImpl) GetWorkerBuildIdCompatibility(
return nil, err
}
return &matchingservice.GetWorkerBuildIdCompatibilityResponse{
Response: ToBuildIdOrderingResponse(verDat, int(req.GetRequest().GetMaxSets())),
Response: ToBuildIdOrderingResponse(userData.GetData().GetVersioningData(), int(req.GetRequest().GetMaxSets())),
}, nil
}
func (e *matchingEngineImpl) InvalidateTaskQueueMetadata(
func (e *matchingEngineImpl) InvalidateTaskQueueUserData(
ctx context.Context,
req *matchingservice.InvalidateTaskQueueMetadataRequest,
) (*matchingservice.InvalidateTaskQueueMetadataResponse, error) {
req *matchingservice.InvalidateTaskQueueUserDataRequest,
) (*matchingservice.InvalidateTaskQueueUserDataResponse, error) {
taskQueue, err := newTaskQueueID(namespace.ID(req.GetNamespaceId()), req.GetTaskQueue(), req.GetTaskQueueType())
if err != nil {
return nil, err
@@ -772,22 +792,22 @@ func (e *matchingEngineImpl) InvalidateTaskQueueMetadata(
tqMgr, err := e.getTaskQueueManager(ctx, taskQueue, enumspb.TASK_QUEUE_KIND_NORMAL, false)
if tqMgr == nil && err == nil {
// Task queue is not currently loaded, so nothing to do here
return &matchingservice.InvalidateTaskQueueMetadataResponse{}, nil
return &matchingservice.InvalidateTaskQueueUserDataResponse{}, nil
}
if err != nil {
return nil, err
}
err = tqMgr.InvalidateMetadata(req)
err = tqMgr.InvalidateUserData(req)
if err != nil {
return nil, err
}
return &matchingservice.InvalidateTaskQueueMetadataResponse{}, nil
return &matchingservice.InvalidateTaskQueueUserDataResponse{}, nil
}
func (e *matchingEngineImpl) GetTaskQueueMetadata(
func (e *matchingEngineImpl) GetTaskQueueUserData(
ctx context.Context,
req *matchingservice.GetTaskQueueMetadataRequest,
) (*matchingservice.GetTaskQueueMetadataResponse, error) {
req *matchingservice.GetTaskQueueUserDataRequest,
) (*matchingservice.GetTaskQueueUserDataResponse, error) {
namespaceID := namespace.ID(req.GetNamespaceId())
taskQueueName := req.GetTaskQueue()
taskQueue, err := newTaskQueueID(namespaceID, taskQueueName, enumspb.TASK_QUEUE_TYPE_WORKFLOW)
@@ -798,19 +818,24 @@ func (e *matchingEngineImpl) GetTaskQueueMetadata(
if err != nil {
return nil, err
}
resp := &matchingservice.GetTaskQueueMetadataResponse{}
verDatHash := req.GetWantVersioningDataCurhash()
// This isn't != nil, because gogoproto will round-trip serialize an empty byte array in a request
// into a nil field.
if len(verDatHash) > 0 {
vDat, err := tqMgr.GetVersioningData(ctx)
if err != nil {
return nil, err
version := req.GetLastKnownUserDataVersion()
if version < 0 {
return nil, serviceerror.NewInvalidArgument("last_known_user_data_version must not be negative")
}
resp := &matchingservice.GetTaskQueueUserDataResponse{}
userData, err := tqMgr.GetUserData(ctx)
if err != nil {
return nil, err
}
if userData != nil {
resp.TaskQueueHasUserData = true
if userData.Version > version {
resp.UserData = userData
}
if !bytes.Equal(HashVersioningData(vDat), verDatHash) {
resp.VersioningDataResp = &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: vDat,
}
if userData.Version < version {
// This is highly unlikely but may happen due to an edge case in during ownership transfer.
// We rely on periodic refresh and client retries in this case to let the system eventually self-heal.
return nil, serviceerror.NewFailedPrecondition("Non-root partition requested task queue user data for version greater than known version")
}
}
return resp, nil

View File

@@ -46,7 +46,7 @@ type (
ListTaskQueuePartitions(ctx context.Context, request *matchingservice.ListTaskQueuePartitionsRequest) (*matchingservice.ListTaskQueuePartitionsResponse, error)
UpdateWorkerBuildIdCompatibility(ctx context.Context, request *matchingservice.UpdateWorkerBuildIdCompatibilityRequest) (*matchingservice.UpdateWorkerBuildIdCompatibilityResponse, error)
GetWorkerBuildIdCompatibility(ctx context.Context, request *matchingservice.GetWorkerBuildIdCompatibilityRequest) (*matchingservice.GetWorkerBuildIdCompatibilityResponse, error)
InvalidateTaskQueueMetadata(ctx context.Context, request *matchingservice.InvalidateTaskQueueMetadataRequest) (*matchingservice.InvalidateTaskQueueMetadataResponse, error)
GetTaskQueueMetadata(ctx context.Context, request *matchingservice.GetTaskQueueMetadataRequest) (*matchingservice.GetTaskQueueMetadataResponse, error)
InvalidateTaskQueueUserData(ctx context.Context, request *matchingservice.InvalidateTaskQueueUserDataRequest) (*matchingservice.InvalidateTaskQueueUserDataResponse, error)
GetTaskQueueUserData(ctx context.Context, request *matchingservice.GetTaskQueueUserDataRequest) (*matchingservice.GetTaskQueueUserDataResponse, error)
}
)

View File

@@ -109,8 +109,8 @@ func (s *matchingEngineSuite) SetupTest() {
s.controller = gomock.NewController(s.T())
s.mockHistoryClient = historyservicemock.NewMockHistoryServiceClient(s.controller)
s.mockMatchingClient = matchingservicemock.NewMockMatchingServiceClient(s.controller)
s.mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
Return(&matchingservice.GetTaskQueueMetadataResponse{}, nil).AnyTimes()
s.mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(&matchingservice.GetTaskQueueUserDataResponse{}, nil).AnyTimes()
s.taskManager = newTestTaskManager(s.logger)
s.mockNamespaceCache = namespace.NewMockRegistry(s.controller)
ns := namespace.NewLocalNamespaceForTest(&persistencespb.NamespaceInfo{Name: matchingTestNamespace}, nil, "")
@@ -1898,7 +1898,7 @@ func (s *matchingEngineSuite) TestTaskExpiryAndCompletion() {
}
func (s *matchingEngineSuite) TestGetVersioningData() {
s.mockMatchingClient.EXPECT().InvalidateTaskQueueMetadata(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
s.mockMatchingClient.EXPECT().InvalidateTaskQueueUserData(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
namespaceID := namespace.ID(uuid.New())
tq := "tupac"
@@ -1915,7 +1915,7 @@ func (s *matchingEngineSuite) TestGetVersioningData() {
s.NotNil(res)
// Set a long list of versions
for i := 0; i < 100; i++ {
for i := 0; i < 10; i++ {
id := fmt.Sprintf("%d", i)
res, err := s.matchingEngine.UpdateWorkerBuildIdCompatibility(context.Background(), &matchingservice.UpdateWorkerBuildIdCompatibilityRequest{
NamespaceId: namespaceID.String(),
@@ -1931,11 +1931,11 @@ func (s *matchingEngineSuite) TestGetVersioningData() {
s.NotNil(res)
}
// Make a long compat-versions chain
for i := 0; i < 10; i++ {
id := fmt.Sprintf("99.%d", i)
prevCompat := fmt.Sprintf("99.%d", i-1)
for i := 0; i < 100; i++ {
id := fmt.Sprintf("9.%d", i)
prevCompat := fmt.Sprintf("9.%d", i-1)
if i == 0 {
prevCompat = "99"
prevCompat = "9"
}
res, err := s.matchingEngine.UpdateWorkerBuildIdCompatibility(context.Background(), &matchingservice.UpdateWorkerBuildIdCompatibilityRequest{
NamespaceId: namespaceID.String(),
@@ -1968,9 +1968,9 @@ func (s *matchingEngineSuite) TestGetVersioningData() {
majorSets := res.GetResponse().GetMajorVersionSets()
curDefault := majorSets[len(majorSets)-1]
s.NotNil(curDefault)
s.Equal("99", curDefault.GetBuildIds()[0])
s.Equal("9", curDefault.GetBuildIds()[0])
lastNode := curDefault.GetBuildIds()[len(curDefault.GetBuildIds())-1]
s.Equal("99.9", lastNode)
s.Equal("9.99", lastNode)
s.Equal("0", majorSets[0].GetBuildIds()[0])
// Ensure depth limiting works
@@ -1985,9 +1985,9 @@ func (s *matchingEngineSuite) TestGetVersioningData() {
s.NoError(err)
majorSets = res.GetResponse().GetMajorVersionSets()
curDefault = majorSets[len(majorSets)-1]
s.Equal("99", curDefault.GetBuildIds()[0])
s.Equal("9", curDefault.GetBuildIds()[0])
lastNode = curDefault.GetBuildIds()[len(curDefault.GetBuildIds())-1]
s.Equal("99.9", lastNode)
s.Equal("9.99", lastNode)
s.Equal(1, len(majorSets))
res, err = s.matchingEngine.GetWorkerBuildIdCompatibility(context.Background(), &matchingservice.GetWorkerBuildIdCompatibilityRequest{
@@ -2000,14 +2000,14 @@ func (s *matchingEngineSuite) TestGetVersioningData() {
})
s.NoError(err)
majorSets = res.GetResponse().GetMajorVersionSets()
s.Equal("95", majorSets[0].GetBuildIds()[0])
s.Equal("5", majorSets[0].GetBuildIds()[0])
}
func (s *matchingEngineSuite) TestActivityQueueMetadataInvalidate() {
// Overwrite the matching mock - we expect one and only one fetch call here, after the activity queue is invalidated
mockMatch := matchingservicemock.NewMockMatchingServiceClient(s.controller)
mockMatch.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
Return(&matchingservice.GetTaskQueueMetadataResponse{}, nil).
mockMatch.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(&matchingservice.GetTaskQueueUserDataResponse{}, nil).
Times(1)
s.matchingEngine.matchingClient = mockMatch
@@ -2031,12 +2031,13 @@ func (s *matchingEngineSuite) TestActivityQueueMetadataInvalidate() {
s.NoError(err)
s.NotNil(ttqm)
_, err = s.matchingEngine.InvalidateTaskQueueMetadata(context.Background(), &matchingservice.InvalidateTaskQueueMetadataRequest{
_, err = s.matchingEngine.InvalidateTaskQueueUserData(context.Background(), &matchingservice.InvalidateTaskQueueUserDataRequest{
NamespaceId: namespaceID.String(),
TaskQueue: tq,
TaskQueueType: enumspb.TASK_QUEUE_TYPE_ACTIVITY,
VersioningData: &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("hi")},
UserData: &persistencespb.VersionedTaskQueueUserData{
Version: 1,
Data: mkUserData(1),
},
})
s.NoError(err)
@@ -2150,6 +2151,7 @@ type testTaskQueueManager struct {
createTaskCount int
getTasksCount int
tasks *treemap.Map
userData *persistencespb.VersionedTaskQueueUserData
}
func (m *testTaskQueueManager) RangeID() int64 {
@@ -2429,6 +2431,21 @@ func (m *testTaskManager) String() string {
return result
}
// GetTaskQueueData implements persistence.TaskManager
func (m *testTaskManager) GetTaskQueueUserData(ctx context.Context, request *persistence.GetTaskQueueUserDataRequest) (*persistence.GetTaskQueueUserDataResponse, error) {
tlm := m.getTaskQueueManager(newTestTaskQueueID(namespace.ID(request.NamespaceID), request.TaskQueue, enumspb.TASK_QUEUE_TYPE_WORKFLOW))
return &persistence.GetTaskQueueUserDataResponse{
UserData: tlm.userData,
}, nil
}
// UpdateTaskQueueUserData implements persistence.TaskManager
func (m *testTaskManager) UpdateTaskQueueUserData(ctx context.Context, request *persistence.UpdateTaskQueueUserDataRequest) error {
tlm := m.getTaskQueueManager(newTestTaskQueueID(namespace.ID(request.NamespaceID), request.TaskQueue, enumspb.TASK_QUEUE_TYPE_WORKFLOW))
tlm.userData = request.UserData
return nil
}
func validateTimeRange(t time.Time, expectedDuration time.Duration) bool {
currentTime := time.Now().UTC()
diff := time.Duration(currentTime.UnixNano() - t.UnixNano())

View File

@@ -114,12 +114,13 @@ type (
// DispatchQueryTask will dispatch query to local or remote poller. If forwarded then result or error is returned,
// if dispatched to local poller then nil and nil is returned.
DispatchQueryTask(ctx context.Context, taskID string, request *matchingservice.QueryWorkflowRequest) (*matchingservice.QueryWorkflowResponse, error)
// GetVersioningData returns the versioning data for this task queue
GetVersioningData(ctx context.Context) (*persistencespb.VersioningData, error)
// MutateVersioningData allows callers to update versioning data for this task queue
MutateVersioningData(ctx context.Context, mutator func(*persistencespb.VersioningData) error) error
// InvalidateMetadata allows callers to invalidate cached data on this task queue
InvalidateMetadata(request *matchingservice.InvalidateTaskQueueMetadataRequest) error
// GetUserData returns the verioned user data for this task queue
GetUserData(ctx context.Context) (*persistencespb.VersionedTaskQueueUserData, error)
// UpdateUserData allows callers to update user data for this task queue
// Extra care should be taken to avoid mutating the existing data in the update function.
UpdateUserData(ctx context.Context, updateFn func(*persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error)) error
// InvalidateUserData allows callers to invalidate cached data on this task queue
InvalidateUserData(request *matchingservice.InvalidateTaskQueueUserDataRequest) error
CancelPoller(pollerID string)
GetAllPollerInfo() []*taskqueuepb.PollerInfo
HasPollerAfter(accessTime time.Time) bool
@@ -161,9 +162,9 @@ type (
outstandingPollsMap map[string]context.CancelFunc
clusterMeta cluster.Metadata
initializedError *future.FutureImpl[struct{}]
// metadataInitialFetch is fulfilled once versioning data is fetched from the root partition. If this TQ is
// userDataInitialFetch is fulfilled once versioning data is fetched from the root partition. If this TQ is
// the root partition, it is fulfilled as soon as it is fetched from db.
metadataInitialFetch *future.FutureImpl[struct{}]
userDataInitialFetch *future.FutureImpl[struct{}]
metadataPoller metadataPoller
}
@@ -232,10 +233,10 @@ func newTaskQueueManager(
namespace: nsName,
taggedMetricsHandler: taggedMetricsHandler,
initializedError: future.NewFuture[struct{}](),
metadataInitialFetch: future.NewFuture[struct{}](),
userDataInitialFetch: future.NewFuture[struct{}](),
metadataPoller: metadataPoller{
running: uberatomic.NewBool(false),
pollIntervalCfgFn: e.config.MetadataPollFrequency,
pollIntervalCfgFn: e.config.UserDataPollFrequency,
stopChan: make(chan struct{}),
},
}
@@ -293,7 +294,7 @@ func (c *taskQueueManagerImpl) Start() {
c.liveness.Start()
c.taskWriter.Start()
c.taskReader.Start()
go c.fetchMetadataFromRootPartitionOnInit(context.TODO())
go c.fetchUserDataFromRootPartitionOnInit(context.TODO())
c.logger.Info("", tag.LifeCycleStarted)
c.taggedMetricsHandler.Counter(metrics.TaskQueueStartedCounter.GetMetricName()).Record(1)
}
@@ -336,7 +337,7 @@ func (c *taskQueueManagerImpl) WaitUntilInitialized(ctx context.Context) error {
}
// We don't really care if the initial fetch worked or not, anything that *requires* a bit of metadata should fail
// that operation if it's never fetched OK. If the initial fetch errored, the metadataPoller will have been started.
_, _ = c.metadataInitialFetch.Get(ctx)
_, _ = c.userDataInitialFetch.Get(ctx)
return err
}
@@ -474,19 +475,19 @@ func (c *taskQueueManagerImpl) DispatchQueryTask(
// GetVersioningData returns the versioning data for the task queue if any. If this task queue is a sub-partition and
// has no cached data, it will explicitly attempt a fetch from the root partition.
func (c *taskQueueManagerImpl) GetVersioningData(ctx context.Context) (*persistencespb.VersioningData, error) {
vd, err := c.db.GetVersioningData(ctx)
if errors.Is(err, errVersioningDataNotPresentOnPartition) {
func (c *taskQueueManagerImpl) GetUserData(ctx context.Context) (*persistencespb.VersionedTaskQueueUserData, error) {
data, err := c.db.GetUserData(ctx)
if errors.Is(err, errUserDataNotPresentOnPartition) {
// If this is a non-root-partition with no versioning data, this call is indicating we might expect to find
// some. Since we may not have started the poller, we want to explicitly attempt to fetch now, because
// it's possible some was added to the root partition, but it failed to invalidate this partition.
return c.fetchMetadataFromRootPartition(ctx)
return c.fetchUserDataFromRootPartition(ctx)
}
return vd, err
return data, err
}
func (c *taskQueueManagerImpl) MutateVersioningData(ctx context.Context, mutator func(*persistencespb.VersioningData) error) error {
newDat, err := c.db.MutateVersioningData(ctx, mutator)
func (c *taskQueueManagerImpl) UpdateUserData(ctx context.Context, updateFn func(*persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error)) error {
newDat, err := c.db.UpdateUserData(ctx, updateFn)
c.signalIfFatal(err)
if err != nil {
return err
@@ -503,12 +504,12 @@ func (c *taskQueueManagerImpl) MutateVersioningData(ctx context.Context, mutator
wg.Add(1)
go func(i int, tqt enumspb.TaskQueueType) {
tq := c.taskQueueID.WithPartition(i).FullName()
_, err := c.matchingClient.InvalidateTaskQueueMetadata(ctx,
&matchingservice.InvalidateTaskQueueMetadataRequest{
NamespaceId: c.taskQueueID.namespaceID.String(),
TaskQueue: tq,
TaskQueueType: tqt,
VersioningData: newDat,
_, err := c.matchingClient.InvalidateTaskQueueUserData(ctx,
&matchingservice.InvalidateTaskQueueUserDataRequest{
NamespaceId: c.taskQueueID.namespaceID.String(),
TaskQueue: tq,
TaskQueueType: tqt,
UserData: newDat,
})
if err != nil {
c.logger.Warn("Failed to notify sub-partition of invalidated versioning data",
@@ -522,14 +523,14 @@ func (c *taskQueueManagerImpl) MutateVersioningData(ctx context.Context, mutator
return nil
}
func (c *taskQueueManagerImpl) InvalidateMetadata(request *matchingservice.InvalidateTaskQueueMetadataRequest) error {
if request.GetVersioningData() != nil {
func (c *taskQueueManagerImpl) InvalidateUserData(request *matchingservice.InvalidateTaskQueueUserDataRequest) error {
if request.GetUserData() != nil {
if c.taskQueueID.IsRoot() && c.taskQueueID.taskType == enumspb.TASK_QUEUE_TYPE_WORKFLOW {
// Should never happen. Root partitions do not get their versioning data invalidated.
c.logger.Warn("A root workflow partition was told to invalidate its versioning data, this should not happen")
return nil
}
c.db.setVersioningDataForNonRootPartition(request.GetVersioningData())
c.db.setUserDataForNonRootPartition(request.GetUserData())
c.metadataPoller.StartIfUnstarted()
}
return nil
@@ -731,54 +732,49 @@ func (c *taskQueueManagerImpl) newIOContext() (context.Context, context.CancelFu
return ctx, cancel
}
func (c *taskQueueManagerImpl) fetchMetadataFromRootPartitionOnInit(ctx context.Context) {
if c.metadataInitialFetch.Ready() {
func (c *taskQueueManagerImpl) fetchUserDataFromRootPartitionOnInit(ctx context.Context) {
if c.userDataInitialFetch.Ready() {
return
}
_, err := c.fetchMetadataFromRootPartition(ctx)
c.metadataInitialFetch.Set(struct{}{}, err)
_, err := c.fetchUserDataFromRootPartition(ctx)
c.userDataInitialFetch.Set(struct{}{}, err)
}
// fetchMetadataFromRootPartition fetches metadata from root partition iff this partition is not a root partition.
// fetchUserDataFromRootPartition fetches user data from root partition iff this partition is not a root partition.
// Returns the fetched data, if fetching was necessary and successful.
func (c *taskQueueManagerImpl) fetchMetadataFromRootPartition(ctx context.Context) (*persistencespb.VersioningData, error) {
func (c *taskQueueManagerImpl) fetchUserDataFromRootPartition(ctx context.Context) (*persistencespb.VersionedTaskQueueUserData, error) {
// Nothing to do if we are the root partition of a workflow queue, since we should own the data.
// (for versioning - any later added metadata may need to not abort so early)
if c.taskQueueID.IsRoot() && c.taskQueueID.taskType == enumspb.TASK_QUEUE_TYPE_WORKFLOW {
return nil, nil
}
curDat, err := c.db.GetVersioningData(ctx)
if err != nil && !errors.Is(err, errVersioningDataNotPresentOnPartition) {
knownUserData, err := c.db.GetUserData(ctx)
if err != nil && !errors.Is(err, errUserDataNotPresentOnPartition) {
return nil, err
}
curHash := HashVersioningData(curDat)
rootTqName := c.taskQueueID.Root().FullName()
if len(curHash) == 0 {
// if we have no data, make sure we send a sigil value, so it's known we desire versioning data
curHash = []byte{0}
}
res, err := c.matchingClient.GetTaskQueueMetadata(ctx, &matchingservice.GetTaskQueueMetadataRequest{
NamespaceId: c.taskQueueID.namespaceID.String(),
TaskQueue: rootTqName,
WantVersioningDataCurhash: curHash,
res, err := c.matchingClient.GetTaskQueueUserData(ctx, &matchingservice.GetTaskQueueUserDataRequest{
NamespaceId: c.taskQueueID.namespaceID.String(),
TaskQueue: rootTqName,
LastKnownUserDataVersion: knownUserData.GetVersion(),
})
// If the root partition returns nil here, then that means our data matched, and we don't need to update.
// If it's nil because it never existed, then we'd never have any data.
// It can't be nil due to removing versions, as that would result in a non-nil container with
// nil inner fields.
if !res.GetMatchedReqHash() {
c.db.setVersioningDataForNonRootPartition(res.GetVersioningData())
if res.GetUserData() != nil {
c.db.setUserDataForNonRootPartition(res.GetUserData())
}
// We want to start the poller as long as the root partition has any kind of data (or fetching hasn't worked)
if res.GetMatchedReqHash() || res.GetVersioningData() != nil || err != nil {
if res.GetUserData() != nil || err != nil {
c.metadataPoller.StartIfUnstarted()
}
if err != nil {
return nil, err
}
return res.GetVersioningData(), nil
return res.GetUserData(), nil
}
// StartIfUnstarted starts the poller if it's not already started. The passed in function is called repeatedly
@@ -803,7 +799,7 @@ func (mp *metadataPoller) pollLoop() {
case <-ticker.C:
// In case the interval has changed
ticker.Reset(mp.pollIntervalCfgFn())
dat, err := mp.tqMgr.fetchMetadataFromRootPartition(context.TODO())
dat, err := mp.tqMgr.fetchUserDataFromRootPartition(context.TODO())
if dat == nil && err == nil {
// Can stop polling since there is no versioning data. Loop will be restarted if we
// are told to invalidate the data, or we attempt to fetch it via GetVersioningData.

View File

@@ -41,7 +41,6 @@ import (
"github.com/stretchr/testify/require"
commonpb "go.temporal.io/api/common/v1"
enumspb "go.temporal.io/api/enums/v1"
taskqueuepb "go.temporal.io/api/taskqueue/v1"
enumsspb "go.temporal.io/server/api/enums/v1"
persistencespb "go.temporal.io/server/api/persistence/v1"
@@ -492,7 +491,7 @@ func TestAddTaskStandby(t *testing.T) {
require.False(t, syncMatch)
}
func TestTaskQueueSubParitionFetchesVersioningInfoFromRootPartitionOnInit(t *testing.T) {
func TestTaskQueueSubParitionFetchesUserDataFromRootPartitionOnInit(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
ctx := context.Background()
@@ -501,37 +500,36 @@ func TestTaskQueueSubParitionFetchesVersioningInfoFromRootPartitionOnInit(t *tes
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
data := &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
data := &persistencespb.VersionedTaskQueueUserData{
Version: 1,
Data: mkUserData(1),
}
asResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: data,
},
asResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: true,
UserData: data,
}
subTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(),
gomock.Eq(&matchingservice.GetTaskQueueMetadataRequest{
NamespaceId: defaultNamespaceId.String(),
TaskQueue: defaultRootTqID,
// Nonsense value since it has nothing on startup
WantVersioningDataCurhash: []byte{0},
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(),
gomock.Eq(&matchingservice.GetTaskQueueUserDataRequest{
NamespaceId: defaultNamespaceId.String(),
TaskQueue: defaultRootTqID,
LastKnownUserDataVersion: 0,
})).
Return(asResp, nil)
tqm.matchingClient = mockMatchingClient
})
subTq.Start()
require.NoError(t, subTq.WaitUntilInitialized(ctx))
verDat, err := subTq.GetVersioningData(ctx)
userData, err := subTq.GetUserData(ctx)
require.NoError(t, err)
require.Equal(t, data, verDat)
require.Equal(t, data, userData)
subTq.Stop()
}
func TestTaskQueueSubParitionSendsCurrentHashOfVersioningDataWhenFetching(t *testing.T) {
func TestTaskQueueSubParitionSendsLastKnownVersionOfUserDataWhenFetching(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
ctx := context.Background()
@@ -540,34 +538,32 @@ func TestTaskQueueSubParitionSendsCurrentHashOfVersioningDataWhenFetching(t *tes
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
data := &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
data := &persistencespb.VersionedTaskQueueUserData{
Version: 2,
Data: mkUserData(1),
}
asResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: data,
},
asResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: true,
UserData: data,
}
dataHash := HashVersioningData(data)
subTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(),
gomock.Eq(&matchingservice.GetTaskQueueMetadataRequest{
NamespaceId: defaultNamespaceId.String(),
TaskQueue: defaultRootTqID,
WantVersioningDataCurhash: dataHash,
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(),
gomock.Eq(&matchingservice.GetTaskQueueUserDataRequest{
NamespaceId: defaultNamespaceId.String(),
TaskQueue: defaultRootTqID,
LastKnownUserDataVersion: 0,
})).
Return(asResp, nil)
tqm.matchingClient = mockMatchingClient
})
// Cram some versioning data in there so it will have something to hash when fetching
subTq.db.versioningData = data
// Don't start it. Just explicitly call fetching function.
res, err := subTq.fetchMetadataFromRootPartition(ctx)
res, err := subTq.fetchUserDataFromRootPartition(ctx)
require.NotNil(t, res)
require.NoError(t, err)
assert.Equal(t, data, subTq.db.userData)
}
type invalidateMatcher struct {
@@ -575,7 +571,7 @@ type invalidateMatcher struct {
}
func (m invalidateMatcher) Matches(x interface{}) bool {
v, ok := x.(*matchingservice.InvalidateTaskQueueMetadataRequest)
v, ok := x.(*matchingservice.InvalidateTaskQueueUserDataRequest)
return ok && v.GetTaskQueueType() == m.matchesTaskQType
}
func (m invalidateMatcher) String() string {
@@ -590,13 +586,13 @@ func TestTaskQueueRootPartitionNotifiesChildrenOfInvalidation(t *testing.T) {
rootTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, defaultTqmTestOpts(controller),
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().InvalidateTaskQueueMetadata(
mockMatchingClient.EXPECT().InvalidateTaskQueueUserData(
gomock.Any(), invalidateMatcher{matchesTaskQType: enumspb.TASK_QUEUE_TYPE_WORKFLOW}).
Return(&matchingservice.InvalidateTaskQueueMetadataResponse{}, nil).
Return(&matchingservice.InvalidateTaskQueueUserDataResponse{}, nil).
Times(tqm.config.NumReadPartitions() - 1)
mockMatchingClient.EXPECT().InvalidateTaskQueueMetadata(
mockMatchingClient.EXPECT().InvalidateTaskQueueUserData(
gomock.Any(), invalidateMatcher{matchesTaskQType: enumspb.TASK_QUEUE_TYPE_ACTIVITY}).
Return(&matchingservice.InvalidateTaskQueueMetadataResponse{}, nil).
Return(&matchingservice.InvalidateTaskQueueUserDataResponse{}, nil).
// Not minus 1 here because root activity partition gets invalidated
Times(tqm.config.NumReadPartitions())
tqm.matchingClient = mockMatchingClient
@@ -605,11 +601,8 @@ func TestTaskQueueRootPartitionNotifiesChildrenOfInvalidation(t *testing.T) {
rootTq.Start()
require.NoError(t, rootTq.WaitUntilInitialized(ctx))
// Make a change, mock verifies children are invalidated
require.NoError(t, rootTq.MutateVersioningData(ctx, func(vd *persistencespb.VersioningData) error {
*vd = persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
}
return nil
require.NoError(t, rootTq.UpdateUserData(ctx, func(vd *persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error) {
return mkUserData(1), nil
}))
rootTq.Stop()
}
@@ -622,26 +615,26 @@ func TestTaskQueueSubPartitionPollsPeriodically(t *testing.T) {
require.NoError(t, err)
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
tqCfg.config.MetadataPollFrequency = func() time.Duration {
tqCfg.config.UserDataPollFrequency = func() time.Duration {
return time.Millisecond * 10
}
asResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
},
asResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: true,
UserData: &persistencespb.VersionedTaskQueueUserData{
Version: 1,
Data: mkUserData(1),
},
}
subTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(asResp, nil).MinTimes(3)
tqm.matchingClient = mockMatchingClient
})
res, err := subTq.fetchMetadataFromRootPartition(ctx)
res, err := subTq.fetchUserDataFromRootPartition(ctx)
require.NotNil(t, res)
require.NoError(t, err)
// Wait a bit to make sure we poll a few times
@@ -657,45 +650,44 @@ func TestTaskQueueSubPartitionDoesNotPollIfNoDataThenPollsWhenInvalidated(t *tes
require.NoError(t, err)
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
tqCfg.config.MetadataPollFrequency = func() time.Duration {
tqCfg.config.UserDataPollFrequency = func() time.Duration {
return time.Millisecond * 10
}
nilDatResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: nil,
},
nilDatResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: false,
}
verDat := &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
userData := mkUserData(1)
verionedUserData := &persistencespb.VersionedTaskQueueUserData{
Version: 1,
Data: userData,
}
hasDatResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: verDat,
},
hasDatResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: true,
UserData: verionedUserData,
}
subTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(nilDatResp, nil).Times(2)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(hasDatResp, nil).MinTimes(1)
tqm.matchingClient = mockMatchingClient
})
res, err := subTq.fetchMetadataFromRootPartition(ctx)
res, err := subTq.fetchUserDataFromRootPartition(ctx)
require.Nil(t, res)
require.NoError(t, err)
// Wait a bit to make sure we *don't* end up polling (if we do, mock will fail with >2 fetches)
time.Sleep(time.Millisecond * 25)
// Explicitly try to get versioning data. Since we don't have any cached, it'll explicitly fetch.
vDat, err := subTq.GetVersioningData(ctx)
existingData, err := subTq.GetUserData(ctx)
require.NoError(t, err)
require.Nil(t, vDat)
require.Nil(t, existingData)
// Now invalidate, the poll loop should be started, so we'll see at least one more mock call
err = subTq.InvalidateMetadata(&matchingservice.InvalidateTaskQueueMetadataRequest{
VersioningData: verDat,
err = subTq.InvalidateUserData(&matchingservice.InvalidateTaskQueueUserDataRequest{
UserData: verionedUserData,
})
require.NoError(t, err)
time.Sleep(time.Millisecond * 20)
@@ -709,31 +701,32 @@ func TestTaskQueueManagerWaitInitFailThenPass(t *testing.T) {
require.NoError(t, err)
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
tqCfg.config.MetadataPollFrequency = func() time.Duration {
tqCfg.config.UserDataPollFrequency = func() time.Duration {
return time.Millisecond * 10
}
data := &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
data := mkUserData(1)
versionedData := &persistencespb.VersionedTaskQueueUserData{
Version: 1,
Data: data,
}
asResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: data,
},
asResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: true,
UserData: versionedData,
}
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
tq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(nil, errors.New("some error")).Times(1)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(asResp, nil).Times(1)
tqm.matchingClient = mockMatchingClient
})
tq.Start()
// This does not error even if initial metadata fetch fails (and it does, here)
// This does not error even if initial user data fetch fails (and it does, here)
require.NoError(t, tq.WaitUntilInitialized(ctx))
// Wait long enough for poller retry to happen
time.Sleep(time.Millisecond * 15)
@@ -741,13 +734,13 @@ func TestTaskQueueManagerWaitInitFailThenPass(t *testing.T) {
// call hasn't happened yet.
controller.Finish()
// Get the data and see it's set
dat, err := tq.GetVersioningData(ctx)
dat, err := tq.GetUserData(ctx)
require.NoError(t, err)
require.Equal(t, data, dat)
require.Equal(t, versionedData, dat)
tq.Stop()
}
func TestFetchingVersioningDataErrorsIfNeverFetchedFromRootSuccessfully(t *testing.T) {
func TestFetchingUserDataErrorsIfNeverFetchedFromRootSuccessfully(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
ctx := context.Background()
@@ -755,38 +748,39 @@ func TestFetchingVersioningDataErrorsIfNeverFetchedFromRootSuccessfully(t *testi
require.NoError(t, err)
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
tqCfg.config.MetadataPollFrequency = func() time.Duration {
tqCfg.config.UserDataPollFrequency = func() time.Duration {
return time.Millisecond * 10
}
subTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(nil, errors.New("fetching broken!")).AnyTimes()
tqm.matchingClient = mockMatchingClient
})
subTq.Start()
require.NoError(t, subTq.WaitUntilInitialized(ctx))
for i := 0; i < 10; i++ {
_, err := subTq.GetVersioningData(ctx)
_, err := subTq.GetUserData(ctx)
require.Error(t, err)
time.Sleep(time.Millisecond * 2)
}
}
func TestActivityQueueGetsVersioningDataFromWorkflowQueue(t *testing.T) {
func TestActivityQueueGetsUserDataFromWorkflowQueue(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
ctx := context.Background()
data := &persistencespb.VersioningData{
VersionSets: []*taskqueuepb.CompatibleVersionSet{mkNewSet("0")},
data := mkUserData(1)
versionedData := &persistencespb.VersionedTaskQueueUserData{
Version: 1,
Data: data,
}
asResp := &matchingservice.GetTaskQueueMetadataResponse{
VersioningDataResp: &matchingservice.GetTaskQueueMetadataResponse_VersioningData{
VersioningData: data,
},
asResp := &matchingservice.GetTaskQueueUserDataResponse{
TaskQueueHasUserData: true,
UserData: versionedData,
}
tqCfg := defaultTqmTestOpts(controller)
@@ -794,7 +788,7 @@ func TestActivityQueueGetsVersioningDataFromWorkflowQueue(t *testing.T) {
actTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(asResp, nil).Times(1)
tqm.matchingClient = mockMatchingClient
})
@@ -808,25 +802,25 @@ func TestActivityQueueGetsVersioningDataFromWorkflowQueue(t *testing.T) {
actTqPart := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg,
func(tqm *taskQueueManagerImpl) {
mockMatchingClient := matchingservicemock.NewMockMatchingServiceClient(controller)
mockMatchingClient.EXPECT().GetTaskQueueMetadata(gomock.Any(), gomock.Any()).
mockMatchingClient.EXPECT().GetTaskQueueUserData(gomock.Any(), gomock.Any()).
Return(asResp, nil).Times(1)
tqm.matchingClient = mockMatchingClient
})
actTqPart.Start()
require.NoError(t, actTqPart.WaitUntilInitialized(ctx))
verDat, err := actTq.GetVersioningData(ctx)
actTqData, err := actTq.GetUserData(ctx)
require.NoError(t, err)
require.Equal(t, data, verDat)
verDat, err = actTqPart.GetVersioningData(ctx)
require.Equal(t, versionedData, actTqData)
actTqData, err = actTqPart.GetUserData(ctx)
require.NoError(t, err)
require.Equal(t, data, verDat)
require.Equal(t, versionedData, actTqData)
actTq.Stop()
actTqPart.Stop()
}
func TestMutateOnNonRootFails(t *testing.T) {
func TestUpdateOnNonRootFails(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
ctx := context.Background()
@@ -836,7 +830,9 @@ func TestMutateOnNonRootFails(t *testing.T) {
tqCfg := defaultTqmTestOpts(controller)
tqCfg.tqId = subTqId
subTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, tqCfg)
err = subTq.MutateVersioningData(ctx, func(data *persistencespb.VersioningData) error { return nil })
err = subTq.UpdateUserData(ctx, func(data *persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error) {
return data, nil
})
require.Error(t, err)
require.ErrorIs(t, err, errVersioningDataNoMutateNonRoot)
@@ -845,7 +841,9 @@ func TestMutateOnNonRootFails(t *testing.T) {
actTqCfg := defaultTqmTestOpts(controller)
actTqCfg.tqId = actTqId
actTq := mustCreateTestTaskQueueManagerWithConfig(t, controller, actTqCfg)
err = actTq.MutateVersioningData(ctx, func(data *persistencespb.VersioningData) error { return nil })
err = actTq.UpdateUserData(ctx, func(data *persistencespb.TaskQueueUserData) (*persistencespb.TaskQueueUserData, error) {
return data, nil
})
require.Error(t, err)
require.ErrorIs(t, err, errVersioningDataNoMutateNonRoot)
}

View File

@@ -27,17 +27,34 @@ package matching
import (
"encoding/binary"
"fmt"
"time"
"github.com/dgryski/go-farm"
"go.temporal.io/api/serviceerror"
taskqueuepb "go.temporal.io/api/taskqueue/v1"
"go.temporal.io/api/taskqueue/v1"
"go.temporal.io/api/workflowservice/v1"
clockpb "go.temporal.io/server/api/clock/v1"
"go.temporal.io/server/api/persistence/v1"
"go.temporal.io/server/common/util"
)
func ToBuildIdOrderingResponse(g *persistence.VersioningData, maxDepth int) *workflowservice.GetWorkerBuildIdCompatibilityResponse {
return depthLimiter(g, maxDepth)
// ToBuildIdOrderingResponse transforms the internal VersioningData representation to public representation.
// If maxSets is given, the last sets up to maxSets will be returned.
func ToBuildIdOrderingResponse(data *persistence.VersioningData, maxSets int) *workflowservice.GetWorkerBuildIdCompatibilityResponse {
lenSets := len(data.GetVersionSets())
numSets := lenSets
if maxSets > 0 && numSets > maxSets {
numSets = maxSets
}
versionSets := make([]*taskqueue.CompatibleVersionSet, numSets)
for i := range versionSets {
set := data.GetVersionSets()[i+lenSets-numSets]
buildIds := make([]string, len(set.GetBuildIds()))
for j, version := range set.GetBuildIds() {
buildIds[j] = version.Id
}
versionSets[i] = &taskqueue.CompatibleVersionSet{BuildIds: buildIds}
}
return &workflowservice.GetWorkerBuildIdCompatibilityResponse{MajorVersionSets: versionSets}
}
// HashVersioningData returns a farm.Fingerprint64 hash of the versioning data as bytes. If the data is nonexistent or
@@ -55,15 +72,25 @@ func HashVersioningData(data *persistence.VersioningData) []byte {
return b
}
func depthLimiter(g *persistence.VersioningData, maxDepth int) *workflowservice.GetWorkerBuildIdCompatibilityResponse {
func checkLimits(g *persistence.VersioningData, maxSets, maxBuildIDs int) error {
sets := g.GetVersionSets()
if maxDepth > 0 {
sets = util.SliceTail(sets, maxDepth)
if maxSets > 0 && len(sets) > maxSets {
return serviceerror.NewFailedPrecondition(fmt.Sprintf("update would exceed number of compatible version sets permitted in namespace dynamic config (%v/%v)", len(sets), maxSets))
}
return &workflowservice.GetWorkerBuildIdCompatibilityResponse{MajorVersionSets: sets}
if maxBuildIDs == 0 {
return nil
}
numBuildIDs := 0
for _, set := range sets {
numBuildIDs += len(set.GetBuildIds())
}
if numBuildIDs > maxBuildIDs {
return serviceerror.NewFailedPrecondition(fmt.Sprintf("update would exceed number of build IDs permitted in namespace dynamic config (%v/%v)", numBuildIDs, maxBuildIDs))
}
return nil
}
// Given existing versioning data and an update request, update the version sets appropriately. The request is expected
// UpdateVersionSets updates version sets given existing versioning data and an update request. The request is expected
// to have already been validated.
//
// See the API docs for more detail. In short, the versioning data representation consists of a sequence of sequences of
@@ -87,68 +114,86 @@ func depthLimiter(g *persistence.VersioningData, maxDepth int) *workflowservice.
// default for that set.
// 3. Target some existing version, marking it (and thus its set) as the default set.
//
// Deletions are not permitted, as inserting new versions can accomplish the same goals with less complexity. However,
// sets may be dropped when the number of sets limit is reached. They are dropped oldest first - the current default set
// is never dropped, instead dropping the next oldest set.
func UpdateVersionSets(existingData *persistence.VersioningData, req *workflowservice.UpdateWorkerBuildIdCompatibilityRequest, maxSize int) error {
err := updateImpl(existingData, req)
// Deletions are performed by a background process which verifies build IDs are no longer in use and safe to delete (not yet implemented).
//
// Update may fail with FailedPrecondition if it would cause exceeding the supplied limits.
func UpdateVersionSets(clock clockpb.HybridLogicalClock, data *persistence.VersioningData, req *workflowservice.UpdateWorkerBuildIdCompatibilityRequest, maxSets, maxBuildIDs int) (clockpb.HybridLogicalClock, *persistence.VersioningData, error) {
clock = generateHLCTimestamp(clock)
data, err := updateImpl(clock, data, req)
if err != nil {
return err
return clock, nil, err
}
// Limit graph size if it's grown too large
newResp := depthLimiter(existingData, maxSize)
existingData.VersionSets = newResp.GetMajorVersionSets()
return nil
if err := checkLimits(data, maxSets, maxBuildIDs); err != nil {
return clock, nil, err
}
return clock, data, nil
}
//nolint:revive // cyclomatic complexity
func updateImpl(existingData *persistence.VersioningData, req *workflowservice.UpdateWorkerBuildIdCompatibilityRequest) error {
func updateImpl(timestamp clockpb.HybridLogicalClock, existingData *persistence.VersioningData, req *workflowservice.UpdateWorkerBuildIdCompatibilityRequest) (*persistence.VersioningData, error) {
// First find if the targeted version is already in the sets
targetedVersion := extractTargetedVersion(req)
findRes := findVersion(existingData, targetedVersion)
targetSetIdx, versionInSetIdx := findRes.setIdx, findRes.indexInSet
modifiedData := persistence.VersioningData{
VersionSets: make([]*persistence.CompatibleVersionSet, len(existingData.GetVersionSets())),
DefaultUpdateTimestamp: existingData.GetDefaultUpdateTimestamp(),
}
copy(modifiedData.VersionSets, existingData.GetVersionSets())
if req.GetAddNewBuildIdInNewDefaultSet() != "" {
// If it's not already in the sets, add it as the new default set
if targetSetIdx != -1 {
return serviceerror.NewInvalidArgument(fmt.Sprintf("version %s already exists", targetedVersion))
return nil, serviceerror.NewInvalidArgument(fmt.Sprintf("version %s already exists", targetedVersion))
}
existingData.VersionSets = append(existingData.GetVersionSets(), &taskqueuepb.CompatibleVersionSet{
BuildIds: []string{targetedVersion},
modifiedData.VersionSets = append(modifiedData.VersionSets, &persistence.CompatibleVersionSet{
SetIds: []string{targetedVersion},
BuildIds: []*persistence.BuildID{{Id: targetedVersion, State: persistence.STATE_ACTIVE, StateUpdateTimestamp: &timestamp}},
})
makeVersionInSetDefault(&modifiedData, len(modifiedData.VersionSets)-1, 0, &timestamp)
makeDefaultSet(&modifiedData, len(modifiedData.VersionSets)-1, &timestamp)
} else if addNew := req.GetAddNewCompatibleBuildId(); addNew != nil {
compatVer := addNew.GetExistingCompatibleBuildId()
compatSetIdx := findVersion(existingData, compatVer).setIdx
compatSetIdx := findVersion(&modifiedData, compatVer).setIdx
if compatSetIdx == -1 {
return serviceerror.NewNotFound(
return nil, serviceerror.NewNotFound(
fmt.Sprintf("targeted compatible_version %v not found", compatVer))
}
if targetSetIdx != -1 {
// If the version does exist, this operation can't do anything meaningful, but we can fail if the user
// says the version is now compatible with some different set.
return serviceerror.NewInvalidArgument(fmt.Sprintf("version %s already exists", targetedVersion))
return nil, serviceerror.NewInvalidArgument(fmt.Sprintf("version %s already exists", targetedVersion))
}
// First duplicate the build IDs to avoid mutation
lastIdx := len(existingData.VersionSets[compatSetIdx].BuildIds)
modifiedData.VersionSets[compatSetIdx] = &persistence.CompatibleVersionSet{
SetIds: existingData.VersionSets[compatSetIdx].SetIds,
BuildIds: make([]*persistence.BuildID, lastIdx+1),
}
copy(modifiedData.VersionSets[compatSetIdx].BuildIds, existingData.VersionSets[compatSetIdx].BuildIds)
// If the version doesn't exist, add it to the compatible set
existingData.VersionSets[compatSetIdx].BuildIds =
append(existingData.VersionSets[compatSetIdx].BuildIds, targetedVersion)
modifiedData.VersionSets[compatSetIdx].BuildIds[lastIdx] =
&persistence.BuildID{Id: targetedVersion, State: persistence.STATE_ACTIVE, StateUpdateTimestamp: &timestamp}
makeVersionInSetDefault(&modifiedData, compatSetIdx, lastIdx, &timestamp)
if addNew.GetMakeSetDefault() {
makeDefaultSet(existingData, compatSetIdx)
makeDefaultSet(&modifiedData, compatSetIdx, &timestamp)
}
} else if req.GetPromoteSetByBuildId() != "" {
if targetSetIdx == -1 {
return serviceerror.NewNotFound(fmt.Sprintf("targeted version %v not found", targetedVersion))
return nil, serviceerror.NewNotFound(fmt.Sprintf("targeted version %v not found", targetedVersion))
}
makeDefaultSet(existingData, targetSetIdx)
makeDefaultSet(&modifiedData, targetSetIdx, &timestamp)
} else if req.GetPromoteBuildIdWithinSet() != "" {
if targetSetIdx == -1 {
return serviceerror.NewNotFound(fmt.Sprintf("targeted version %v not found", targetedVersion))
return nil, serviceerror.NewNotFound(fmt.Sprintf("targeted version %v not found", targetedVersion))
}
makeVersionInSetDefault(existingData, targetSetIdx, versionInSetIdx)
makeVersionInSetDefault(&modifiedData, targetSetIdx, versionInSetIdx, &timestamp)
}
return nil
return &modifiedData, nil
}
func extractTargetedVersion(req *workflowservice.UpdateWorkerBuildIdCompatibilityRequest) string {
@@ -172,7 +217,7 @@ type findVersionRes struct {
func findVersion(data *persistence.VersioningData, buildID string) findVersionRes {
for setIx, set := range data.GetVersionSets() {
for versionIx, version := range set.GetBuildIds() {
if version == buildID {
if version.Id == buildID {
return findVersionRes{
setIdx: setIx,
indexInSet: versionIx,
@@ -186,22 +231,50 @@ func findVersion(data *persistence.VersioningData, buildID string) findVersionRe
}
}
func makeDefaultSet(data *persistence.VersioningData, setIx int) {
func makeDefaultSet(data *persistence.VersioningData, setIx int, timestamp *clockpb.HybridLogicalClock) {
data.DefaultUpdateTimestamp = timestamp
if len(data.VersionSets) <= 1 {
return
}
// Move the set to the end and shift all the others down
moveMe := data.VersionSets[setIx]
copy(data.VersionSets[setIx:], data.VersionSets[setIx+1:])
data.VersionSets[len(data.VersionSets)-1] = moveMe
if setIx < len(data.VersionSets)-1 {
// Move the set to the end and shift all the others down
moveMe := data.VersionSets[setIx]
copy(data.VersionSets[setIx:], data.VersionSets[setIx+1:])
data.VersionSets[len(data.VersionSets)-1] = moveMe
}
}
func makeVersionInSetDefault(data *persistence.VersioningData, setIx, versionIx int) {
func makeVersionInSetDefault(data *persistence.VersioningData, setIx, versionIx int, timestamp *clockpb.HybridLogicalClock) {
data.VersionSets[setIx].DefaultUpdateTimestamp = timestamp
setVersions := data.VersionSets[setIx].BuildIds
if len(setVersions) <= 1 {
return
}
moveMe := setVersions[versionIx]
copy(setVersions[versionIx:], setVersions[versionIx+1:])
setVersions[len(setVersions)-1] = moveMe
if versionIx < len(setVersions)-1 {
// Move the build ID to the end and shift all the others down
moveMe := setVersions[versionIx]
copy(setVersions[versionIx:], setVersions[versionIx+1:])
setVersions[len(setVersions)-1] = moveMe
}
}
func generateHLCTimestamp(clock clockpb.HybridLogicalClock) clockpb.HybridLogicalClock {
wallclock := time.Now().UnixMilli()
// Ensure time does not move backwards
if wallclock < clock.GetWallClock() {
wallclock = clock.GetWallClock()
}
// Ensure timestamp is monotonically increasing
if wallclock == clock.GetWallClock() {
clock.Version = clock.GetVersion() + 1
} else {
clock.Version = 0
clock.WallClock = wallclock
}
return clockpb.HybridLogicalClock{WallClock: wallclock, Version: clock.Version, ClusterId: clock.ClusterId}
}
func zeroHLC(clusterID int64) clockpb.HybridLogicalClock {
return clockpb.HybridLogicalClock{WallClock: 0, Version: 0, ClusterId: clusterID}
}

View File

@@ -33,22 +33,34 @@ import (
"go.temporal.io/api/serviceerror"
taskqueuepb "go.temporal.io/api/taskqueue/v1"
"go.temporal.io/api/workflowservice/v1"
clockpb "go.temporal.io/server/api/clock/v1"
persistencepb "go.temporal.io/server/api/persistence/v1"
)
func mkNewSet(id string) *taskqueuepb.CompatibleVersionSet {
return &taskqueuepb.CompatibleVersionSet{
BuildIds: []string{id},
func mkNewSet(id string, clock clockpb.HybridLogicalClock) *persistencepb.CompatibleVersionSet {
return &persistencepb.CompatibleVersionSet{
SetIds: []string{id},
BuildIds: []*persistencepb.BuildID{{Id: id, State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock}},
DefaultUpdateTimestamp: &clock,
}
}
func mkInitialData(numSets int) *persistencepb.VersioningData {
sets := make([]*taskqueuepb.CompatibleVersionSet, numSets)
func mkInitialData(numSets int, clock clockpb.HybridLogicalClock) *persistencepb.VersioningData {
sets := make([]*persistencepb.CompatibleVersionSet, numSets)
for i := 0; i < numSets; i++ {
sets[i] = mkNewSet(fmt.Sprintf("%v", i))
sets[i] = mkNewSet(fmt.Sprintf("%v", i), clock)
}
return &persistencepb.VersioningData{
VersionSets: sets,
VersionSets: sets,
DefaultUpdateTimestamp: &clock,
}
}
func mkUserData(numSets int) *persistencepb.TaskQueueUserData {
clock := zeroHLC(1)
return &persistencepb.TaskQueueUserData{
Clock: &clock,
VersioningData: mkInitialData(numSets, clock),
}
}
@@ -85,215 +97,422 @@ func mkPromoteInSet(id string) *workflowservice.UpdateWorkerBuildIdCompatibility
}
}
func assertClockGreater(t *testing.T, clock1 clockpb.HybridLogicalClock, clock2 clockpb.HybridLogicalClock) {
if clock1.Version == clock2.Version {
assert.GreaterOrEqual(t, clock1.WallClock, clock2.WallClock)
} else {
assert.Equal(t, clock1.WallClock, clock2.WallClock)
}
assert.Equal(t, clock1.ClusterId, clock2.ClusterId)
}
func TestNewDefaultUpdate(t *testing.T) {
data := mkInitialData(2)
clock := zeroHLC(1)
initialData := mkInitialData(2, clock)
req := mkNewDefReq("2")
err := UpdateVersionSets(data, req, 0)
nextClock, updatedData, err := UpdateVersionSets(clock, initialData, req, 0, 0)
assert.NoError(t, err)
assertClockGreater(t, nextClock, clock)
assert.Equal(t, mkInitialData(2, clock), initialData)
curd := data.VersionSets[len(data.VersionSets)-1]
assert.Equal(t, "2", curd.BuildIds[0])
assert.Equal(t, "1", data.VersionSets[1].BuildIds[0])
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &nextClock,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock}},
DefaultUpdateTimestamp: &clock,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock}},
DefaultUpdateTimestamp: &clock,
},
{
SetIds: []string{"2"},
BuildIds: []*persistencepb.BuildID{{Id: "2", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &nextClock}},
DefaultUpdateTimestamp: &nextClock,
},
},
}
assert.Equal(t, expected, updatedData)
asResp := ToBuildIdOrderingResponse(data, 0)
asResp := ToBuildIdOrderingResponse(updatedData, 0)
assert.Equal(t, "2", asResp.MajorVersionSets[2].BuildIds[0])
}
func TestNewDefaultGraphUpdateOfEmptyGraph(t *testing.T) {
data := &persistencepb.VersioningData{}
func TestNewDefaultSetUpdateOfEmptyData(t *testing.T) {
clock := zeroHLC(1)
initialData := mkInitialData(0, clock)
req := mkNewDefReq("1")
err := UpdateVersionSets(data, req, 0)
nextClock, updatedData, err := UpdateVersionSets(clock, initialData, req, 0, 0)
assert.NoError(t, err)
assertClockGreater(t, nextClock, clock)
assert.Equal(t, mkInitialData(0, clock), initialData)
curd := data.VersionSets[len(data.VersionSets)-1]
assert.Equal(t, "1", curd.BuildIds[0])
assert.Equal(t, 1, len(data.VersionSets))
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &nextClock,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &nextClock}},
DefaultUpdateTimestamp: &nextClock,
},
},
}
assert.Equal(t, expected, updatedData)
}
func TestNewDefaultGraphUpdateCompatWithCurDefault(t *testing.T) {
data := mkInitialData(2)
func TestNewDefaultSetUpdateCompatWithCurDefault(t *testing.T) {
clock := zeroHLC(1)
initialData := mkInitialData(2, clock)
req := mkNewCompatReq("1.1", "1", true)
err := UpdateVersionSets(data, req, 0)
nextClock, updatedData, err := UpdateVersionSets(clock, initialData, req, 0, 0)
assert.NoError(t, err)
assertClockGreater(t, nextClock, clock)
assert.Equal(t, mkInitialData(2, clock), initialData)
curd := data.VersionSets[len(data.VersionSets)-1]
assert.Equal(t, "1.1", curd.BuildIds[1])
assert.Equal(t, "1", curd.BuildIds[0])
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &nextClock,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock}},
DefaultUpdateTimestamp: &clock,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{
{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock},
{Id: "1.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &nextClock},
},
DefaultUpdateTimestamp: &nextClock,
},
},
}
assert.Equal(t, expected, updatedData)
}
func TestNewDefaultGraphUpdateCompatWithNonDefaultSet(t *testing.T) {
data := mkInitialData(2)
func TestNewDefaultSetUpdateCompatWithNonDefaultSet(t *testing.T) {
clock := zeroHLC(1)
initialData := mkInitialData(2, clock)
req := mkNewCompatReq("0.1", "0", true)
err := UpdateVersionSets(data, req, 0)
nextClock, updatedData, err := UpdateVersionSets(clock, initialData, req, 0, 0)
assert.NoError(t, err)
assertClockGreater(t, nextClock, clock)
assert.Equal(t, mkInitialData(2, clock), initialData)
curd := data.VersionSets[len(data.VersionSets)-1]
assert.Equal(t, "0.1", curd.BuildIds[1])
assert.Equal(t, "0", curd.BuildIds[0])
assert.Equal(t, "1", data.VersionSets[0].BuildIds[0])
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &nextClock,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock}},
DefaultUpdateTimestamp: &clock,
},
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock},
{Id: "0.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &nextClock},
},
DefaultUpdateTimestamp: &nextClock,
},
},
}
assert.Equal(t, expected, updatedData)
}
func TestNewCompatibleWithVerInOlderSet(t *testing.T) {
data := mkInitialData(3)
clock := zeroHLC(1)
initialData := mkInitialData(2, clock)
req := mkNewCompatReq("0.1", "0", false)
err := UpdateVersionSets(data, req, 0)
nextClock, updatedData, err := UpdateVersionSets(clock, initialData, req, 0, 0)
assert.NoError(t, err)
assertClockGreater(t, nextClock, clock)
assert.Equal(t, mkInitialData(2, clock), initialData)
curd := data.VersionSets[len(data.VersionSets)-1]
assert.Equal(t, "2", curd.BuildIds[0])
assert.Equal(t, "0.1", data.VersionSets[0].BuildIds[1])
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &clock,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock},
{Id: "0.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &nextClock},
},
DefaultUpdateTimestamp: &nextClock,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock}},
DefaultUpdateTimestamp: &clock,
},
},
}
asResp := ToBuildIdOrderingResponse(data, 0)
assert.Equal(t, expected, updatedData)
asResp := ToBuildIdOrderingResponse(updatedData, 0)
assert.Equal(t, "0.1", asResp.MajorVersionSets[0].BuildIds[1])
}
func TestNewCompatibleWithNonDefaultGraphUpdate(t *testing.T) {
data := mkInitialData(2)
func TestNewCompatibleWithNonDefaultSetUpdate(t *testing.T) {
clock0 := zeroHLC(1)
data := mkInitialData(2, clock0)
req := mkNewCompatReq("0.1", "0", false)
err := UpdateVersionSets(data, req, 0)
clock1, data, err := UpdateVersionSets(clock0, data, req, 0, 0)
assert.NoError(t, err)
req = mkNewCompatReq("0.2", "0.1", false)
err = UpdateVersionSets(data, req, 0)
clock2, data, err := UpdateVersionSets(clock1, data, req, 0, 0)
assert.NoError(t, err)
curd := data.VersionSets[len(data.VersionSets)-1]
assert.Equal(t, "1", curd.BuildIds[0])
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
assert.Equal(t, "0.1", data.VersionSets[0].BuildIds[1])
assert.Equal(t, "0.2", data.VersionSets[0].BuildIds[2])
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &clock0,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0},
{Id: "0.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock1},
{Id: "0.2", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock2},
},
DefaultUpdateTimestamp: &clock2,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
},
}
assert.Equal(t, expected, data)
// Ensure setting a compatible version which targets a non-leaf compat version ends up without a branch
req = mkNewCompatReq("0.3", "0.1", false)
err = UpdateVersionSets(data, req, 0)
clock3, data, err := UpdateVersionSets(clock2, data, req, 0, 0)
assert.NoError(t, err)
assert.Equal(t, "1", curd.BuildIds[0])
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
assert.Equal(t, "0.1", data.VersionSets[0].BuildIds[1])
assert.Equal(t, "0.2", data.VersionSets[0].BuildIds[2])
assert.Equal(t, "0.3", data.VersionSets[0].BuildIds[3])
expected = &persistencepb.VersioningData{
DefaultUpdateTimestamp: &clock0,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0},
{Id: "0.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock1},
{Id: "0.2", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock2},
{Id: "0.3", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock3},
},
DefaultUpdateTimestamp: &clock3,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
},
}
assert.Equal(t, expected, data)
}
func TestCompatibleTargetsNotFound(t *testing.T) {
data := mkInitialData(1)
clock := zeroHLC(1)
data := mkInitialData(1, clock)
req := mkNewCompatReq("1.1", "1", false)
err := UpdateVersionSets(data, req, 0)
_, _, err := UpdateVersionSets(clock, data, req, 0, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.NotFound{}, err)
}
func TestMakeExistingSetDefault(t *testing.T) {
data := mkInitialData(4)
req := mkExistingDefault("2")
err := UpdateVersionSets(data, req, 0)
clock0 := zeroHLC(1)
data := mkInitialData(3, clock0)
req := mkExistingDefault("1")
clock1, data, err := UpdateVersionSets(clock0, data, req, 0, 0)
assert.NoError(t, err)
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
assert.Equal(t, "1", data.VersionSets[1].BuildIds[0])
assert.Equal(t, "3", data.VersionSets[2].BuildIds[0])
assert.Equal(t, "2", data.VersionSets[3].BuildIds[0])
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &clock1,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0},
},
DefaultUpdateTimestamp: &clock0,
},
{
SetIds: []string{"2"},
BuildIds: []*persistencepb.BuildID{{Id: "2", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
},
}
assert.Equal(t, expected, data)
// Add a compatible version to a set and then make that set the default via the compatible version
req = mkNewCompatReq("1.1", "1", true)
req = mkNewCompatReq("0.1", "0", true)
err = UpdateVersionSets(data, req, 0)
clock2, data, err := UpdateVersionSets(clock1, data, req, 0, 0)
assert.NoError(t, err)
assert.Equal(t, "0", data.VersionSets[0].BuildIds[0])
assert.Equal(t, "3", data.VersionSets[1].BuildIds[0])
assert.Equal(t, "2", data.VersionSets[2].BuildIds[0])
assert.Equal(t, "1", data.VersionSets[3].BuildIds[0])
expected = &persistencepb.VersioningData{
DefaultUpdateTimestamp: &clock2,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"2"},
BuildIds: []*persistencepb.BuildID{{Id: "2", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0},
{Id: "0.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock2},
},
DefaultUpdateTimestamp: &clock2,
},
},
}
assert.Equal(t, expected, data)
}
func TestSayVersionIsCompatWithDifferentSetThanItsAlreadyCompatWithNotAllowed(t *testing.T) {
data := mkInitialData(3)
clock := zeroHLC(1)
data := mkInitialData(3, clock)
req := mkNewCompatReq("0.1", "0", false)
err := UpdateVersionSets(data, req, 0)
_, data, err := UpdateVersionSets(clock, data, req, 0, 0)
assert.NoError(t, err)
req = mkNewCompatReq("0.1", "1", false)
err = UpdateVersionSets(data, req, 0)
_, _, err = UpdateVersionSets(clock, data, req, 0, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.InvalidArgument{}, err)
}
func TestLimitsMaxSize(t *testing.T) {
data := &persistencepb.VersioningData{}
maxSize := 10
func TestLimitsMaxSets(t *testing.T) {
clock := zeroHLC(1)
maxSets := 10
data := mkInitialData(maxSets, clock)
for i := 0; i < 20; i++ {
id := fmt.Sprintf("%d", i)
req := mkNewDefReq(id)
err := UpdateVersionSets(data, req, maxSize)
assert.NoError(t, err)
}
req := mkNewDefReq("10")
_, _, err := UpdateVersionSets(clock, data, req, maxSets, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.FailedPrecondition{}, err)
}
for i := 0; i < len(data.VersionSets); i++ {
assert.Equal(t, fmt.Sprintf("%d", i+10), data.VersionSets[i].BuildIds[0])
}
func TestLimitsMaxBuildIDs(t *testing.T) {
clock := zeroHLC(1)
maxBuildIDs := 10
data := mkInitialData(maxBuildIDs, clock)
req := mkNewDefReq("10")
_, _, err := UpdateVersionSets(clock, data, req, 0, maxBuildIDs)
assert.Error(t, err)
assert.IsType(t, &serviceerror.FailedPrecondition{}, err)
}
func TestPromoteWithinVersion(t *testing.T) {
data := mkInitialData(3)
clock0 := zeroHLC(1)
data := mkInitialData(2, clock0)
for i := 1; i <= 5; i++ {
req := mkNewCompatReq(fmt.Sprintf("0.%d", i), "0", false)
err := UpdateVersionSets(data, req, 0)
assert.NoError(t, err)
}
req := mkPromoteInSet("0.1")
err := UpdateVersionSets(data, req, 0)
req := mkNewCompatReq("0.1", "0", false)
clock1, data, err := UpdateVersionSets(clock0, data, req, 0, 0)
assert.NoError(t, err)
req = mkNewCompatReq("0.2", "0", false)
clock2, data, err := UpdateVersionSets(clock1, data, req, 0, 0)
assert.NoError(t, err)
req = mkPromoteInSet("0.1")
clock3, data, err := UpdateVersionSets(clock2, data, req, 0, 0)
assert.NoError(t, err)
curd := data.VersionSets[0].BuildIds[len(data.VersionSets[0].BuildIds)-1]
assert.Equal(t, "0.1", curd)
expected := &persistencepb.VersioningData{
DefaultUpdateTimestamp: &clock0,
VersionSets: []*persistencepb.CompatibleVersionSet{
{
SetIds: []string{"0"},
BuildIds: []*persistencepb.BuildID{
{Id: "0", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0},
{Id: "0.2", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock2},
{Id: "0.1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock1},
},
DefaultUpdateTimestamp: &clock3,
},
{
SetIds: []string{"1"},
BuildIds: []*persistencepb.BuildID{{Id: "1", State: persistencepb.STATE_ACTIVE, StateUpdateTimestamp: &clock0}},
DefaultUpdateTimestamp: &clock0,
},
},
}
assert.Equal(t, expected, data)
}
func TestAddAlreadyExtantVersionAsDefaultErrors(t *testing.T) {
data := mkInitialData(3)
clock := zeroHLC(1)
data := mkInitialData(3, clock)
req := mkNewDefReq("0")
err := UpdateVersionSets(data, req, 0)
_, _, err := UpdateVersionSets(clock, data, req, 0, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.InvalidArgument{}, err)
}
func TestAddAlreadyExtantVersionToAnotherSetErrors(t *testing.T) {
data := mkInitialData(3)
clock := zeroHLC(1)
data := mkInitialData(3, clock)
req := mkNewCompatReq("0", "1", false)
err := UpdateVersionSets(data, req, 0)
_, _, err := UpdateVersionSets(clock, data, req, 0, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.InvalidArgument{}, err)
}
func TestMakeSetDefaultTargetingNonexistentVersionErrors(t *testing.T) {
data := mkInitialData(3)
clock := zeroHLC(1)
data := mkInitialData(3, clock)
req := mkExistingDefault("crab boi")
err := UpdateVersionSets(data, req, 0)
_, _, err := UpdateVersionSets(clock, data, req, 0, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.NotFound{}, err)
}
func TestPromoteWithinSetTargetingNonexistentVersionErrors(t *testing.T) {
data := mkInitialData(3)
clock := zeroHLC(1)
data := mkInitialData(3, clock)
req := mkPromoteInSet("i'd rather be writing rust ;)")
err := UpdateVersionSets(data, req, 0)
_, _, err := UpdateVersionSets(clock, data, req, 0, 0)
assert.Error(t, err)
assert.IsType(t, &serviceerror.NotFound{}, err)
}
func TestToBuildIdOrderingResponseTrimsResponse(t *testing.T) {
clock := zeroHLC(1)
data := mkInitialData(3, clock)
actual := ToBuildIdOrderingResponse(data, 2)
expected := []*taskqueuepb.CompatibleVersionSet{{BuildIds: []string{"1"}}, {BuildIds: []string{"2"}}}
assert.Equal(t, expected, actual.MajorVersionSets)
}