From f5713000e49e6a428001070d8f11a3451e16a294 Mon Sep 17 00:00:00 2001 From: Xuecheng Zhang Date: Mon, 3 Aug 2020 18:07:55 +0800 Subject: [PATCH] feat: get subtask config and status of v1.0.x from dm-worker (#846) --- _utils/terror_gen/errors_release.txt | 1 + dm/pb/dmworker.pb.go | 1190 +++++++++++++++-- dm/pbmock/dmworker.go | 35 + dm/proto/dmworker.proto | 28 +- dm/worker/v1meta.go | 61 + errors.toml | 6 + go.mod | 1 + pkg/terror/error_list.go | 6 + pkg/v1workermeta/api.go | 108 ++ pkg/v1workermeta/api_test.go | 156 +++ pkg/v1workermeta/db.go | 67 + pkg/v1workermeta/meta.go | 157 +++ pkg/v1workermeta/meta_test.go | 136 ++ .../v106_data_for_test/kv/000002.ldb | Bin 0 -> 171 bytes .../v106_data_for_test/kv/000006.ldb | Bin 0 -> 992 bytes .../v106_data_for_test/kv/000007.ldb | Bin 0 -> 1093 bytes .../v106_data_for_test/kv/000009.ldb | Bin 0 -> 1041 bytes .../v106_data_for_test/kv/000010.ldb | Bin 0 -> 1148 bytes .../v106_data_for_test/kv/000011.log | 0 .../v106_data_for_test/kv/000012.ldb | Bin 0 -> 156 bytes .../v106_data_for_test/kv/000013.ldb | Bin 0 -> 1148 bytes .../v106_data_for_test/kv/CURRENT | 1 + .../v106_data_for_test/kv/CURRENT.bak | 1 + pkg/v1workermeta/v106_data_for_test/kv/LOCK | 0 pkg/v1workermeta/v106_data_for_test/kv/LOG | 41 + .../v106_data_for_test/kv/MANIFEST-000004 | Bin 0 -> 594 bytes 26 files changed, 1859 insertions(+), 136 deletions(-) create mode 100644 dm/worker/v1meta.go create mode 100644 pkg/v1workermeta/api.go create mode 100644 pkg/v1workermeta/api_test.go create mode 100644 pkg/v1workermeta/db.go create mode 100644 pkg/v1workermeta/meta.go create mode 100644 pkg/v1workermeta/meta_test.go create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000002.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000006.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000007.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000009.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000010.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000011.log create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000012.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/000013.ldb create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/CURRENT create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/CURRENT.bak create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/LOCK create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/LOG create mode 100644 pkg/v1workermeta/v106_data_for_test/kv/MANIFEST-000004 diff --git a/_utils/terror_gen/errors_release.txt b/_utils/terror_gen/errors_release.txt index a2dfc6bd94..079d7a6749 100644 --- a/_utils/terror_gen/errors_release.txt +++ b/_utils/terror_gen/errors_release.txt @@ -118,6 +118,7 @@ ErrShardDDLOptimismTrySyncFail,[code=11111:class=functional:scope=internal:level ErrConnInvalidTLSConfig,[code=11112:class=functional:scope=internal:level=medium], "Message: invalid TLS config, Workaround: Please check the `ssl-ca`, `ssl-cert` and `ssl-key` config." ErrConnRegistryTLSConfig,[code=11113:class=functional:scope=internal:level=medium], "Message: fail to registry TLS config" ErrUpgradeVersionEtcdFail,[code=11114:class=functional:scope=internal:level=high], "Message: fail to operate DM cluster version in etcd, Workaround: Please use `list-member --master` to confirm whether the DM-master cluster is healthy" +ErrInvalidV1WorkerMetaPath,[code=11115:class=functional:scope=internal:level=medium], "Message: %s is an invalid v1.0.x DM-worker meta path, Workaround: Please check no `meta-dir` set for v1.0.x DM-worker" ErrConfigCheckItemNotSupport,[code=20001:class=config:scope=internal:level=medium], "Message: checking item %s is not supported\n%s, Workaround: Please check `ignore-checking-items` config in task configuration file, which can be set including `all`/`dump_privilege`/`replication_privilege`/`version`/`binlog_enable`/`binlog_format`/`binlog_row_image`/`table_schema`/`schema_of_shard_tables`/`auto_increment_ID`." ErrConfigTomlTransform,[code=20002:class=config:scope=internal:level=medium], "Message: %s, Workaround: Please check the configuration file has correct TOML format." ErrConfigYamlTransform,[code=20003:class=config:scope=internal:level=medium], "Message: %s, Workaround: Please check the configuration file has correct YAML format." diff --git a/dm/pb/dmworker.pb.go b/dm/pb/dmworker.pb.go index 5752093a94..a63ab3d5a2 100644 --- a/dm/pb/dmworker.pb.go +++ b/dm/pb/dmworker.pb.go @@ -261,6 +261,34 @@ func (SchemaOp) EnumDescriptor() ([]byte, []int) { return fileDescriptor_51a1b9e17fd67b10, []int{5} } +type V1MetaOp int32 + +const ( + V1MetaOp_InvalidV1MetaOp V1MetaOp = 0 + V1MetaOp_GetV1Meta V1MetaOp = 1 + V1MetaOp_RemoveV1Meta V1MetaOp = 2 +) + +var V1MetaOp_name = map[int32]string{ + 0: "InvalidV1MetaOp", + 1: "GetV1Meta", + 2: "RemoveV1Meta", +} + +var V1MetaOp_value = map[string]int32{ + "InvalidV1MetaOp": 0, + "GetV1Meta": 1, + "RemoveV1Meta": 2, +} + +func (x V1MetaOp) String() string { + return proto.EnumName(V1MetaOp_name, int32(x)) +} + +func (V1MetaOp) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_51a1b9e17fd67b10, []int{6} +} + type StartSubTaskRequest struct { Task string `protobuf:"bytes,1,opt,name=task,proto3" json:"task,omitempty"` } @@ -2852,6 +2880,179 @@ func (m *OperateWorkerSchemaRequest) GetSchema() string { return "" } +// copied `TaskMeta` from release-1.0 branch. +type V1SubTaskMeta struct { + Op TaskOp `protobuf:"varint,1,opt,name=op,proto3,enum=pb.TaskOp" json:"op,omitempty"` + Stage Stage `protobuf:"varint,2,opt,name=stage,proto3,enum=pb.Stage" json:"stage,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Task []byte `protobuf:"bytes,4,opt,name=task,proto3" json:"task,omitempty"` +} + +func (m *V1SubTaskMeta) Reset() { *m = V1SubTaskMeta{} } +func (m *V1SubTaskMeta) String() string { return proto.CompactTextString(m) } +func (*V1SubTaskMeta) ProtoMessage() {} +func (*V1SubTaskMeta) Descriptor() ([]byte, []int) { + return fileDescriptor_51a1b9e17fd67b10, []int{39} +} +func (m *V1SubTaskMeta) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *V1SubTaskMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_V1SubTaskMeta.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 *V1SubTaskMeta) XXX_Merge(src proto.Message) { + xxx_messageInfo_V1SubTaskMeta.Merge(m, src) +} +func (m *V1SubTaskMeta) XXX_Size() int { + return m.Size() +} +func (m *V1SubTaskMeta) XXX_DiscardUnknown() { + xxx_messageInfo_V1SubTaskMeta.DiscardUnknown(m) +} + +var xxx_messageInfo_V1SubTaskMeta proto.InternalMessageInfo + +func (m *V1SubTaskMeta) GetOp() TaskOp { + if m != nil { + return m.Op + } + return TaskOp_InvalidOp +} + +func (m *V1SubTaskMeta) GetStage() Stage { + if m != nil { + return m.Stage + } + return Stage_InvalidStage +} + +func (m *V1SubTaskMeta) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *V1SubTaskMeta) GetTask() []byte { + if m != nil { + return m.Task + } + return nil +} + +type OperateV1MetaRequest struct { + Op V1MetaOp `protobuf:"varint,1,opt,name=op,proto3,enum=pb.V1MetaOp" json:"op,omitempty"` +} + +func (m *OperateV1MetaRequest) Reset() { *m = OperateV1MetaRequest{} } +func (m *OperateV1MetaRequest) String() string { return proto.CompactTextString(m) } +func (*OperateV1MetaRequest) ProtoMessage() {} +func (*OperateV1MetaRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_51a1b9e17fd67b10, []int{40} +} +func (m *OperateV1MetaRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OperateV1MetaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OperateV1MetaRequest.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 *OperateV1MetaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OperateV1MetaRequest.Merge(m, src) +} +func (m *OperateV1MetaRequest) XXX_Size() int { + return m.Size() +} +func (m *OperateV1MetaRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OperateV1MetaRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_OperateV1MetaRequest proto.InternalMessageInfo + +func (m *OperateV1MetaRequest) GetOp() V1MetaOp { + if m != nil { + return m.Op + } + return V1MetaOp_InvalidV1MetaOp +} + +type OperateV1MetaResponse struct { + Result bool `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Meta map[string]*V1SubTaskMeta `protobuf:"bytes,3,rep,name=meta,proto3" json:"meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *OperateV1MetaResponse) Reset() { *m = OperateV1MetaResponse{} } +func (m *OperateV1MetaResponse) String() string { return proto.CompactTextString(m) } +func (*OperateV1MetaResponse) ProtoMessage() {} +func (*OperateV1MetaResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_51a1b9e17fd67b10, []int{41} +} +func (m *OperateV1MetaResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OperateV1MetaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OperateV1MetaResponse.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 *OperateV1MetaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_OperateV1MetaResponse.Merge(m, src) +} +func (m *OperateV1MetaResponse) XXX_Size() int { + return m.Size() +} +func (m *OperateV1MetaResponse) XXX_DiscardUnknown() { + xxx_messageInfo_OperateV1MetaResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_OperateV1MetaResponse proto.InternalMessageInfo + +func (m *OperateV1MetaResponse) GetResult() bool { + if m != nil { + return m.Result + } + return false +} + +func (m *OperateV1MetaResponse) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +func (m *OperateV1MetaResponse) GetMeta() map[string]*V1SubTaskMeta { + if m != nil { + return m.Meta + } + return nil +} + func init() { proto.RegisterEnum("pb.TaskOp", TaskOp_name, TaskOp_value) proto.RegisterEnum("pb.SQLOp", SQLOp_name, SQLOp_value) @@ -2859,6 +3060,7 @@ func init() { proto.RegisterEnum("pb.UnitType", UnitType_name, UnitType_value) proto.RegisterEnum("pb.RelayOp", RelayOp_name, RelayOp_value) proto.RegisterEnum("pb.SchemaOp", SchemaOp_name, SchemaOp_value) + proto.RegisterEnum("pb.V1MetaOp", V1MetaOp_name, V1MetaOp_value) proto.RegisterType((*StartSubTaskRequest)(nil), "pb.StartSubTaskRequest") proto.RegisterType((*UpdateRelayRequest)(nil), "pb.UpdateRelayRequest") proto.RegisterType((*MigrateRelayRequest)(nil), "pb.MigrateRelayRequest") @@ -2898,146 +3100,160 @@ func init() { proto.RegisterType((*QueryWorkerConfigRequest)(nil), "pb.QueryWorkerConfigRequest") proto.RegisterType((*QueryWorkerConfigResponse)(nil), "pb.QueryWorkerConfigResponse") proto.RegisterType((*OperateWorkerSchemaRequest)(nil), "pb.OperateWorkerSchemaRequest") + proto.RegisterType((*V1SubTaskMeta)(nil), "pb.V1SubTaskMeta") + proto.RegisterType((*OperateV1MetaRequest)(nil), "pb.OperateV1MetaRequest") + proto.RegisterType((*OperateV1MetaResponse)(nil), "pb.OperateV1MetaResponse") + proto.RegisterMapType((map[string]*V1SubTaskMeta)(nil), "pb.OperateV1MetaResponse.MetaEntry") } func init() { proto.RegisterFile("dmworker.proto", fileDescriptor_51a1b9e17fd67b10) } var fileDescriptor_51a1b9e17fd67b10 = []byte{ - // 2143 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x19, 0x4d, 0x6f, 0xe4, 0x48, - 0xb5, 0xed, 0xfe, 0x48, 0xf7, 0xeb, 0xee, 0x8c, 0x53, 0x99, 0xcd, 0xf6, 0x34, 0xb3, 0x4d, 0xe4, - 0x59, 0xed, 0x66, 0x73, 0x88, 0xd8, 0x00, 0x42, 0x42, 0x5a, 0x60, 0xa7, 0x93, 0xcd, 0x84, 0xed, - 0xcc, 0x24, 0xee, 0x19, 0x71, 0x44, 0x8e, 0x5d, 0xe9, 0x58, 0x71, 0xdb, 0x1e, 0x7f, 0x24, 0xca, - 0x9f, 0x00, 0x2e, 0x1c, 0x10, 0xdc, 0x10, 0xe2, 0x82, 0x10, 0xff, 0x02, 0x8e, 0x2b, 0x4e, 0x1c, - 0xd1, 0xcc, 0xdf, 0xe0, 0x80, 0xde, 0xab, 0xb2, 0x5d, 0x4e, 0xba, 0x7b, 0x76, 0x24, 0xb8, 0xf9, - 0x7d, 0xd4, 0xab, 0x57, 0xef, 0xb3, 0xea, 0x19, 0xd6, 0xdd, 0xf9, 0x4d, 0x18, 0x5f, 0xf1, 0x78, - 0x2f, 0x8a, 0xc3, 0x34, 0x64, 0x7a, 0x74, 0x6e, 0x7e, 0x06, 0x9b, 0xd3, 0xd4, 0x8e, 0xd3, 0x69, - 0x76, 0xfe, 0xd2, 0x4e, 0xae, 0x2c, 0xfe, 0x3a, 0xe3, 0x49, 0xca, 0x18, 0x34, 0x52, 0x3b, 0xb9, - 0x1a, 0x68, 0xdb, 0xda, 0x4e, 0xc7, 0xa2, 0x6f, 0x73, 0x0f, 0xd8, 0xab, 0xc8, 0xb5, 0x53, 0x6e, - 0x71, 0xdf, 0xbe, 0xcd, 0x39, 0x07, 0xb0, 0xe6, 0x84, 0x41, 0xca, 0x83, 0x54, 0x32, 0xe7, 0xa0, - 0x39, 0x85, 0xcd, 0x13, 0x6f, 0x16, 0xdf, 0x5d, 0x30, 0x02, 0x78, 0xea, 0x05, 0x7e, 0x38, 0x7b, - 0x6e, 0xcf, 0xb9, 0x5c, 0xa3, 0x60, 0xd8, 0x63, 0xe8, 0x08, 0xe8, 0x34, 0x4c, 0x06, 0xfa, 0xb6, - 0xb6, 0xd3, 0xb7, 0x4a, 0x84, 0x79, 0x04, 0x1f, 0xbc, 0x88, 0x38, 0x0a, 0xbd, 0xa3, 0xf1, 0x10, - 0xf4, 0x30, 0x22, 0x71, 0xeb, 0xfb, 0xb0, 0x17, 0x9d, 0xef, 0x21, 0xf1, 0x45, 0x64, 0xe9, 0x61, - 0x84, 0xa7, 0x09, 0x70, 0x33, 0x5d, 0x9c, 0x06, 0xbf, 0xcd, 0x6b, 0xd8, 0xba, 0x2b, 0x28, 0x89, - 0xc2, 0x20, 0xe1, 0x2b, 0x25, 0x6d, 0x41, 0x2b, 0xe6, 0x49, 0xe6, 0xa7, 0x24, 0xab, 0x6d, 0x49, - 0x08, 0xf1, 0x49, 0x98, 0xc5, 0x0e, 0x1f, 0xd4, 0x69, 0x0f, 0x09, 0x31, 0x03, 0xea, 0xf3, 0x64, - 0x36, 0x68, 0x10, 0x12, 0x3f, 0xcd, 0x5d, 0x78, 0x28, 0xac, 0xf8, 0x2d, 0x2c, 0xbe, 0x03, 0xec, - 0x2c, 0xe3, 0xf1, 0xed, 0x34, 0xb5, 0xd3, 0x2c, 0x51, 0x38, 0x83, 0xd2, 0x74, 0xe2, 0x34, 0x9f, - 0xc2, 0x06, 0x71, 0x1e, 0xc6, 0x71, 0x18, 0xaf, 0x62, 0xfc, 0xbd, 0x06, 0x83, 0x67, 0x76, 0xe0, - 0xfa, 0xf9, 0xfe, 0xd3, 0xb3, 0xc9, 0x2a, 0xc9, 0xec, 0x11, 0x59, 0x43, 0x27, 0x6b, 0x74, 0xd0, - 0x1a, 0xd3, 0xb3, 0x49, 0x69, 0x56, 0x3b, 0x9e, 0x25, 0x83, 0xfa, 0x76, 0x1d, 0xd9, 0xf1, 0x1b, - 0xbd, 0x77, 0x5e, 0x78, 0x4f, 0x1c, 0xbb, 0x44, 0xa0, 0xef, 0x93, 0xd7, 0xfe, 0xa9, 0x9d, 0xa6, - 0x3c, 0x0e, 0x06, 0x4d, 0xe1, 0xfb, 0x12, 0x63, 0x46, 0xf0, 0x70, 0x1c, 0xce, 0xe7, 0x61, 0xf0, - 0x0b, 0x8a, 0xd3, 0xc2, 0x25, 0xa5, 0xd9, 0xb5, 0x8a, 0xd9, 0xa5, 0x79, 0xf5, 0xc2, 0xbc, 0x4b, - 0x1d, 0xb1, 0x05, 0x2d, 0x11, 0xfb, 0x52, 0x29, 0x09, 0x99, 0x7f, 0xd5, 0x60, 0xb3, 0x62, 0xe3, - 0xf7, 0xde, 0xf1, 0x07, 0xd0, 0x13, 0x7b, 0x08, 0x09, 0xb4, 0x6f, 0x77, 0xdf, 0x20, 0x53, 0x29, - 0x78, 0xab, 0xc2, 0xc5, 0x7e, 0x04, 0xfd, 0x44, 0x3a, 0x40, 0x2c, 0x6b, 0x6c, 0xd7, 0x77, 0xba, - 0xfb, 0x1b, 0xb4, 0x4c, 0x25, 0x58, 0x55, 0x3e, 0xf3, 0xcf, 0x9a, 0x0c, 0x0a, 0xe9, 0xea, 0xf7, - 0xd6, 0xf7, 0x73, 0xe8, 0x0a, 0xbd, 0x48, 0x80, 0x54, 0xf7, 0x41, 0xa9, 0xae, 0x90, 0xab, 0xf2, - 0xd0, 0x11, 0x85, 0x12, 0x62, 0x8d, 0xd0, 0xd5, 0x50, 0x74, 0x15, 0x8b, 0x2a, 0x5c, 0xe6, 0x9f, - 0x34, 0xe8, 0x8e, 0x2f, 0xb9, 0x23, 0x35, 0x47, 0x15, 0x23, 0x3b, 0x49, 0xb8, 0x9b, 0xab, 0x28, - 0x20, 0xf6, 0x10, 0x9a, 0x69, 0x98, 0xda, 0x3e, 0x29, 0xd9, 0xb4, 0x04, 0x40, 0xa1, 0x92, 0x39, - 0x0e, 0x4f, 0x92, 0x8b, 0xcc, 0x27, 0x2d, 0x9b, 0x96, 0x82, 0x41, 0x69, 0x17, 0xb6, 0xe7, 0x73, - 0x97, 0x1c, 0xda, 0xb4, 0x24, 0x84, 0xf5, 0xe8, 0xc6, 0x8e, 0x03, 0x2f, 0x98, 0x51, 0x7c, 0x35, - 0xad, 0x1c, 0xc4, 0x15, 0x2e, 0x4f, 0x6d, 0xcf, 0x1f, 0xb4, 0xb6, 0xb5, 0x9d, 0x9e, 0x25, 0x21, - 0xb3, 0x07, 0x70, 0x90, 0xcd, 0x23, 0x69, 0xdf, 0x5f, 0x69, 0x00, 0x93, 0xd0, 0x76, 0xa5, 0xd2, - 0x1f, 0x43, 0xff, 0xc2, 0x0b, 0xbc, 0xe4, 0x92, 0xbb, 0x4f, 0x6f, 0x53, 0x9e, 0x90, 0xee, 0x75, - 0xab, 0x8a, 0x44, 0x65, 0x49, 0x6b, 0xc1, 0xa2, 0x13, 0x8b, 0x82, 0x61, 0x43, 0x68, 0x47, 0x71, - 0x38, 0x8b, 0x79, 0x92, 0xc8, 0xb8, 0x2c, 0x60, 0x5c, 0x3b, 0xe7, 0xa9, 0x2d, 0x4a, 0x9c, 0x8c, - 0x4e, 0x05, 0x63, 0xfe, 0x56, 0x83, 0xfe, 0xf4, 0xd2, 0x8e, 0x5d, 0x2f, 0x98, 0x1d, 0xc5, 0x61, - 0x46, 0x45, 0x28, 0xb5, 0xe3, 0x19, 0xcf, 0x2b, 0xae, 0x84, 0x30, 0x1f, 0x0f, 0x0e, 0x26, 0xb8, - 0x3f, 0xe5, 0x23, 0x7e, 0x0b, 0xfd, 0xe3, 0x24, 0x9d, 0x84, 0x8e, 0x9d, 0x7a, 0x61, 0x20, 0xb7, - 0xaf, 0x22, 0x29, 0x6b, 0x6e, 0x03, 0x87, 0x8c, 0x59, 0xa7, 0xac, 0x21, 0x08, 0xf5, 0xce, 0x02, - 0x49, 0x69, 0x12, 0xa5, 0x80, 0xcd, 0x3f, 0xd6, 0x01, 0xa6, 0xb7, 0x81, 0x23, 0x0d, 0xb5, 0x0d, - 0x5d, 0x3a, 0xf0, 0xe1, 0x35, 0x0f, 0xd2, 0xdc, 0x4c, 0x2a, 0x0a, 0x85, 0x11, 0xf8, 0x32, 0xca, - 0x4d, 0x54, 0xc0, 0x58, 0x36, 0x62, 0xee, 0xf0, 0x20, 0x45, 0x62, 0x9d, 0x88, 0x25, 0x82, 0x99, - 0xd0, 0x9b, 0xdb, 0x49, 0xca, 0xe3, 0x8a, 0x91, 0x2a, 0x38, 0xb6, 0x0b, 0x86, 0x0a, 0x1f, 0xa5, - 0x9e, 0x2b, 0x0b, 0xcc, 0x3d, 0x3c, 0xca, 0xa3, 0x43, 0xe4, 0xf2, 0x5a, 0x42, 0x9e, 0x8a, 0x43, - 0x79, 0x2a, 0x4c, 0xf2, 0xd6, 0x84, 0xbc, 0xbb, 0x78, 0x94, 0x77, 0xee, 0x87, 0xce, 0x95, 0x17, - 0xcc, 0xc8, 0x01, 0x6d, 0x32, 0x55, 0x05, 0xc7, 0xbe, 0x00, 0x23, 0x0b, 0x62, 0x9e, 0x84, 0xfe, - 0x35, 0x77, 0xc9, 0x8f, 0xc9, 0xa0, 0xa3, 0xe4, 0xbc, 0xea, 0x61, 0xeb, 0x1e, 0xab, 0xe2, 0x21, - 0x10, 0xc9, 0x23, 0x3d, 0x34, 0x02, 0x10, 0xe5, 0xf5, 0xe5, 0x6d, 0xc4, 0x07, 0x5d, 0x11, 0x3d, - 0x25, 0xc6, 0xfc, 0x83, 0x06, 0x3d, 0xb5, 0x0c, 0x29, 0x05, 0x52, 0x5b, 0x52, 0x20, 0x75, 0xb5, - 0x40, 0xb2, 0xcf, 0x8a, 0xc2, 0x22, 0x2a, 0x05, 0x69, 0x7b, 0x1a, 0x87, 0x98, 0x87, 0x16, 0x11, - 0x8a, 0x5a, 0xf3, 0x39, 0x74, 0x63, 0xec, 0xf4, 0x45, 0x45, 0x2b, 0x2a, 0x8b, 0x55, 0xa2, 0x2d, - 0x95, 0xc7, 0xfc, 0xbb, 0x0e, 0x5d, 0x85, 0x78, 0xcf, 0xd3, 0xda, 0xb7, 0xf4, 0xb4, 0xbe, 0xc4, - 0xd3, 0xdb, 0xb9, 0x4a, 0xd9, 0xf9, 0x81, 0x17, 0xcb, 0xe0, 0x57, 0x51, 0x05, 0x47, 0x25, 0xb4, - 0x54, 0x14, 0xdb, 0x81, 0x07, 0x0a, 0xa8, 0x04, 0xd6, 0x5d, 0x34, 0xdb, 0x03, 0x46, 0xa8, 0xb1, - 0x9d, 0x3a, 0x97, 0xaf, 0xa2, 0x13, 0xd2, 0x86, 0xa2, 0xab, 0x6d, 0x2d, 0xa0, 0xb0, 0xef, 0x42, - 0x33, 0x49, 0xed, 0x19, 0xa7, 0xc0, 0xca, 0xdb, 0x2b, 0x22, 0x2c, 0x81, 0x57, 0x8c, 0xdf, 0x7e, - 0x87, 0xf1, 0xcd, 0xff, 0xe8, 0xd0, 0xaf, 0x34, 0x8e, 0x85, 0xdd, 0xbc, 0xd8, 0x51, 0x5f, 0xb2, - 0xe3, 0x36, 0x34, 0xb2, 0xc0, 0x13, 0xce, 0x5e, 0xdf, 0xef, 0x21, 0xfd, 0x55, 0xe0, 0xa5, 0x18, - 0x4b, 0x16, 0x51, 0x14, 0x9d, 0x1a, 0xef, 0x0a, 0x88, 0xef, 0xc1, 0x66, 0x19, 0xc8, 0x07, 0x07, - 0x93, 0x49, 0xe8, 0x5c, 0x1d, 0x1f, 0x48, 0xeb, 0x2d, 0x22, 0x31, 0x26, 0xda, 0x15, 0x25, 0xe4, - 0xb3, 0x9a, 0x68, 0x58, 0x9f, 0x42, 0xd3, 0xc1, 0x36, 0x42, 0x56, 0x92, 0x01, 0xa5, 0xf4, 0x95, - 0x67, 0x35, 0x4b, 0xd0, 0xd9, 0xc7, 0xd0, 0x70, 0xb3, 0x79, 0x24, 0x6d, 0xb5, 0x8e, 0x7c, 0x65, - 0x61, 0x7f, 0x56, 0xb3, 0x88, 0x8a, 0x5c, 0x7e, 0x68, 0xbb, 0x83, 0x4e, 0xc9, 0x55, 0xd6, 0x7b, - 0xe4, 0x42, 0x2a, 0x72, 0x61, 0x86, 0x51, 0xb6, 0x49, 0xae, 0xb2, 0xd8, 0x21, 0x17, 0x52, 0x9f, - 0xb6, 0xa1, 0x95, 0x88, 0x40, 0xfe, 0x09, 0x6c, 0x54, 0xac, 0x3f, 0xf1, 0x12, 0x32, 0x95, 0x20, - 0x0f, 0xb4, 0x65, 0xdd, 0x3d, 0x5f, 0x3f, 0x02, 0xa0, 0x33, 0x89, 0x86, 0x2b, 0xbb, 0xb6, 0x56, - 0x5e, 0x1b, 0x3f, 0x82, 0x0e, 0x9e, 0x65, 0x05, 0x19, 0x0f, 0xb1, 0x8c, 0x1c, 0x41, 0x8f, 0xb4, - 0x3f, 0x9b, 0x2c, 0xe1, 0x60, 0xfb, 0xf0, 0x50, 0x34, 0xd0, 0xe2, 0xaa, 0xed, 0x51, 0xbb, 0x10, - 0x89, 0xb5, 0x90, 0x86, 0x05, 0x9d, 0xa3, 0xb8, 0xe9, 0xd9, 0x24, 0xef, 0x6a, 0x39, 0x6c, 0xfe, - 0x10, 0x3a, 0xb8, 0xa3, 0xd8, 0x6e, 0x07, 0x5a, 0x44, 0xc8, 0xed, 0x60, 0x14, 0xe6, 0x94, 0x0a, - 0x59, 0x92, 0x6e, 0xfe, 0x5a, 0xab, 0xdc, 0x4e, 0xde, 0xbb, 0x5a, 0x6d, 0xdf, 0xbf, 0xdc, 0x74, - 0xaa, 0x77, 0x99, 0x3d, 0x00, 0x2a, 0x38, 0xf9, 0x4d, 0xa6, 0x70, 0x6f, 0x89, 0xb5, 0x14, 0x0e, - 0x74, 0x4c, 0x09, 0x2d, 0x30, 0xed, 0xef, 0x74, 0xe8, 0xa9, 0x97, 0xa0, 0xff, 0x57, 0xda, 0x31, - 0xe5, 0x25, 0x91, 0x67, 0xc6, 0x27, 0x79, 0x66, 0x34, 0xcb, 0x63, 0x94, 0x51, 0x54, 0x26, 0xc6, - 0x13, 0x99, 0x18, 0x2d, 0x62, 0xeb, 0xe7, 0x89, 0x91, 0x73, 0x89, 0xbc, 0x78, 0x22, 0xf3, 0x62, - 0xad, 0x64, 0x2a, 0x42, 0xaa, 0x48, 0x8b, 0x27, 0x32, 0x2d, 0xda, 0x25, 0x53, 0xe1, 0xe6, 0x22, - 0x2b, 0xd6, 0xa0, 0x49, 0xee, 0x34, 0x7f, 0x0c, 0x86, 0x6a, 0x1a, 0xca, 0x89, 0x4f, 0x24, 0xb1, - 0x12, 0x0a, 0xea, 0x25, 0x52, 0xae, 0x7d, 0x0d, 0xfd, 0x4a, 0x51, 0xc1, 0x4e, 0xe7, 0x25, 0x63, - 0x3b, 0x70, 0xb8, 0x5f, 0x5c, 0x21, 0x15, 0x8c, 0x12, 0x64, 0x7a, 0x29, 0x59, 0x8a, 0xa8, 0x04, - 0x99, 0x72, 0x11, 0xac, 0x57, 0x2e, 0x82, 0xff, 0xd4, 0xa0, 0xa7, 0x2e, 0xc0, 0xbb, 0xe4, 0x61, - 0x1c, 0x8f, 0x43, 0x57, 0x78, 0xb3, 0x69, 0xe5, 0x20, 0x86, 0x3e, 0x7e, 0xfa, 0x76, 0x92, 0xc8, - 0x08, 0x2c, 0x60, 0x49, 0x9b, 0x3a, 0x61, 0x94, 0x3f, 0x42, 0x0a, 0x58, 0xd2, 0x26, 0xfc, 0x9a, - 0xfb, 0xb2, 0xd5, 0x14, 0x30, 0xee, 0x76, 0xc2, 0x93, 0x04, 0xc3, 0x44, 0x54, 0xc8, 0x1c, 0xc4, - 0x55, 0x96, 0x7d, 0x33, 0xb6, 0xb3, 0x84, 0xcb, 0xbb, 0x4a, 0x01, 0xa3, 0x59, 0xf0, 0xb1, 0x64, - 0xc7, 0x61, 0x16, 0xe4, 0x37, 0x14, 0x05, 0x63, 0x0e, 0x61, 0x30, 0xbd, 0xf1, 0x52, 0xe7, 0x92, - 0xa2, 0x58, 0x34, 0x1e, 0xf9, 0xde, 0x33, 0xf7, 0x61, 0x53, 0xbe, 0x81, 0x2b, 0x2f, 0xf4, 0xef, - 0x28, 0x0f, 0xe0, 0x6e, 0x91, 0x1a, 0xe2, 0xd1, 0x67, 0x66, 0xf0, 0xb0, 0xba, 0x46, 0x3e, 0x40, - 0x56, 0x2d, 0xfa, 0x1f, 0x3c, 0x9b, 0x6f, 0x60, 0xe3, 0x34, 0x8b, 0x67, 0x55, 0x45, 0x87, 0xd0, - 0xf6, 0x02, 0xdb, 0x49, 0xbd, 0x6b, 0x2e, 0x03, 0xa2, 0x80, 0xe9, 0x3d, 0xed, 0xc9, 0x37, 0x7f, - 0xdd, 0xa2, 0x6f, 0xe4, 0xbf, 0xf0, 0x7c, 0x4e, 0xe9, 0x29, 0x3d, 0x93, 0xc3, 0xa4, 0x8a, 0xb8, - 0x24, 0xc8, 0x07, 0xa2, 0x80, 0xd0, 0x7e, 0xf4, 0xdc, 0x12, 0x2f, 0xd2, 0x71, 0x18, 0x5c, 0x78, - 0xb3, 0xdc, 0x7e, 0x37, 0xf0, 0x68, 0x01, 0xed, 0x1d, 0x2f, 0xb2, 0xf2, 0xcc, 0xfa, 0xa2, 0x33, - 0xd7, 0xcb, 0x9a, 0xac, 0x8c, 0x56, 0x1a, 0xd5, 0xd1, 0xca, 0xdf, 0x34, 0x18, 0x4a, 0x2f, 0x88, - 0xbd, 0xa7, 0xce, 0x25, 0x9f, 0xdb, 0xb9, 0x5d, 0x1e, 0x2b, 0xbe, 0xa0, 0x5a, 0x22, 0xc8, 0xe5, - 0xb3, 0x9d, 0x26, 0x0d, 0x7a, 0x39, 0x69, 0x58, 0xea, 0x88, 0x21, 0xb4, 0x5d, 0x3b, 0xb5, 0xcf, - 0xed, 0x84, 0xe7, 0xf1, 0x9a, 0xc3, 0xf4, 0x6e, 0xb3, 0xcf, 0xfd, 0x3c, 0x5a, 0x05, 0x40, 0x92, - 0x68, 0x37, 0x19, 0xa9, 0x12, 0xda, 0xfd, 0x25, 0xb4, 0xc4, 0x1c, 0x85, 0xf5, 0xa1, 0x73, 0x1c, - 0x5c, 0xdb, 0xbe, 0xe7, 0xbe, 0x88, 0x8c, 0x1a, 0x6b, 0x43, 0x63, 0x9a, 0x86, 0x91, 0xa1, 0xb1, - 0x0e, 0x34, 0x4f, 0x31, 0xa6, 0x0d, 0x9d, 0x01, 0xb4, 0x30, 0xed, 0xe7, 0xdc, 0xa8, 0x23, 0x9a, - 0x46, 0x54, 0x46, 0x03, 0xd1, 0x62, 0x78, 0x62, 0x34, 0xd9, 0x3a, 0xc0, 0x97, 0x59, 0x1a, 0x4a, - 0xb6, 0xd6, 0xee, 0x2e, 0x34, 0x69, 0x34, 0x41, 0x02, 0xbf, 0x3e, 0x3e, 0x35, 0x6a, 0xac, 0x0b, - 0x6b, 0xd6, 0xe1, 0xe9, 0xe4, 0xcb, 0xf1, 0xa1, 0xa1, 0xe1, 0xda, 0xe3, 0xe7, 0x3f, 0x3f, 0x1c, - 0xbf, 0x34, 0xf4, 0xdd, 0xd7, 0x24, 0x72, 0x86, 0x46, 0xef, 0x49, 0x5d, 0x08, 0x36, 0x6a, 0x6c, - 0x0d, 0xea, 0xcf, 0xf9, 0x8d, 0xa1, 0xd1, 0xe2, 0x2c, 0xc0, 0x97, 0xa3, 0xd0, 0x87, 0x54, 0x73, - 0x8d, 0x3a, 0x12, 0x50, 0xe1, 0x88, 0xbb, 0x46, 0x83, 0xf5, 0xa0, 0xfd, 0x95, 0x7c, 0x0a, 0x1a, - 0x4d, 0x24, 0x21, 0x1b, 0xae, 0x69, 0x21, 0x89, 0x94, 0x43, 0x68, 0x6d, 0xf7, 0x05, 0xb4, 0xf3, - 0x8a, 0xce, 0x1e, 0x40, 0x57, 0xee, 0x8a, 0x28, 0xa3, 0x86, 0x47, 0xa4, 0xba, 0x6d, 0x68, 0xa8, - 0x3d, 0xd6, 0x66, 0x43, 0xc7, 0x2f, 0x2c, 0xc0, 0x46, 0x9d, 0x4e, 0x74, 0x1b, 0x38, 0x46, 0x03, - 0x19, 0x29, 0x03, 0x0c, 0x77, 0xf7, 0x04, 0xd6, 0x64, 0x8a, 0x31, 0x06, 0xeb, 0x52, 0x9e, 0xc4, - 0x18, 0x35, 0xb4, 0x32, 0x6a, 0x29, 0xb8, 0x35, 0xb4, 0x16, 0x1d, 0x40, 0xc0, 0x3a, 0xaa, 0x20, - 0x2c, 0x27, 0x10, 0x75, 0xd4, 0x2f, 0x8f, 0x12, 0xb6, 0x09, 0x0f, 0x72, 0xab, 0x48, 0x94, 0x10, - 0x78, 0xc4, 0x53, 0x81, 0x30, 0x34, 0x92, 0x5f, 0x80, 0x3a, 0x1a, 0xd2, 0xe2, 0xf3, 0xf0, 0x9a, - 0x4b, 0x4c, 0x7d, 0xff, 0x2f, 0x6b, 0xd0, 0x12, 0xc1, 0xc9, 0xc6, 0xd0, 0x53, 0x87, 0x8c, 0xec, - 0x43, 0xd9, 0xff, 0xee, 0x8e, 0x1d, 0x87, 0x03, 0xea, 0x60, 0x0b, 0x26, 0x40, 0x66, 0x8d, 0x1d, - 0xc3, 0x7a, 0x75, 0x60, 0xc7, 0x1e, 0x21, 0xf7, 0xc2, 0x69, 0xe0, 0x70, 0xb8, 0x88, 0x54, 0x88, - 0x3a, 0x84, 0x7e, 0x65, 0x06, 0xc7, 0x68, 0xdf, 0x45, 0x63, 0xb9, 0x95, 0x1a, 0xfd, 0x0c, 0xba, - 0xca, 0xe8, 0x88, 0x6d, 0x21, 0xeb, 0xfd, 0x79, 0xdd, 0xf0, 0xc3, 0x7b, 0xf8, 0x42, 0xc2, 0x17, - 0x00, 0xe5, 0x2c, 0x87, 0x7d, 0x50, 0x30, 0xaa, 0x63, 0xbc, 0xe1, 0xd6, 0x5d, 0x74, 0xb1, 0xfc, - 0x2b, 0x00, 0x39, 0xcb, 0x3b, 0x9b, 0x24, 0xec, 0x31, 0xf2, 0x2d, 0x9b, 0xed, 0xad, 0x3c, 0xc8, - 0x09, 0x6c, 0xdc, 0xeb, 0x11, 0x42, 0xdc, 0xb2, 0xd6, 0xb1, 0x52, 0xdc, 0x18, 0x7a, 0x6a, 0x8b, - 0x10, 0xee, 0x5e, 0xd0, 0x68, 0x84, 0x90, 0x45, 0xdd, 0xc4, 0xac, 0xb1, 0x9f, 0x02, 0x94, 0x05, - 0x5f, 0x98, 0xe6, 0x5e, 0x03, 0x58, 0xa9, 0xc5, 0x11, 0x6c, 0x28, 0xe3, 0x6a, 0x51, 0x9c, 0x85, - 0x8f, 0xee, 0x4f, 0xb1, 0x57, 0x0a, 0xb2, 0xe4, 0x6c, 0x55, 0xad, 0xf2, 0xc2, 0x3a, 0xcb, 0x1a, - 0xc3, 0xf0, 0xa3, 0x25, 0x54, 0xd5, 0x44, 0xea, 0x6c, 0x5c, 0x98, 0x68, 0xc1, 0xb4, 0x7c, 0xa5, - 0x62, 0x5f, 0x43, 0x3f, 0x0f, 0x71, 0x4a, 0x3a, 0x36, 0x52, 0xec, 0xb9, 0xa0, 0x2f, 0xac, 0x12, - 0xf6, 0x74, 0xf0, 0x8f, 0x37, 0x23, 0xed, 0x9b, 0x37, 0x23, 0xed, 0xdf, 0x6f, 0x46, 0xda, 0x6f, - 0xde, 0x8e, 0x6a, 0xdf, 0xbc, 0x1d, 0xd5, 0xfe, 0xf5, 0x76, 0x54, 0x3b, 0x6f, 0xd1, 0xdf, 0x82, - 0xef, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x19, 0xf9, 0x8a, 0x86, 0x3f, 0x18, 0x00, 0x00, + // 2293 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x39, 0xcd, 0x6f, 0x1b, 0xc7, + 0xf5, 0xdc, 0xe5, 0x87, 0xc8, 0x47, 0x52, 0x5e, 0x8d, 0x1c, 0x87, 0xe6, 0xcf, 0xe1, 0x4f, 0x58, + 0x07, 0x89, 0xa2, 0x83, 0x50, 0xab, 0x29, 0x52, 0x04, 0x48, 0x9b, 0x98, 0x92, 0x65, 0x25, 0x94, + 0x2d, 0x2d, 0xed, 0xf4, 0x58, 0xac, 0xc8, 0x11, 0xb5, 0x10, 0xb9, 0xbb, 0xde, 0x0f, 0x09, 0xfc, + 0x27, 0xda, 0x5e, 0x7a, 0x28, 0xda, 0x5b, 0x51, 0xf4, 0x56, 0xf4, 0xaf, 0x68, 0x7b, 0x0c, 0x7a, + 0xea, 0xb1, 0xb0, 0xff, 0x85, 0x1e, 0x7b, 0x28, 0xde, 0x9b, 0x99, 0xdd, 0x59, 0x89, 0xa4, 0x63, + 0xa0, 0xbd, 0xed, 0xfb, 0x98, 0x37, 0x6f, 0xde, 0xe7, 0xcc, 0x5b, 0x58, 0x1f, 0xcf, 0xae, 0x83, + 0xe8, 0x92, 0x47, 0xbb, 0x61, 0x14, 0x24, 0x01, 0x33, 0xc3, 0x33, 0xfb, 0x13, 0xd8, 0x1c, 0x26, + 0x6e, 0x94, 0x0c, 0xd3, 0xb3, 0x17, 0x6e, 0x7c, 0xe9, 0xf0, 0x57, 0x29, 0x8f, 0x13, 0xc6, 0xa0, + 0x92, 0xb8, 0xf1, 0x65, 0xc7, 0xd8, 0x32, 0xb6, 0x1b, 0x0e, 0x7d, 0xdb, 0xbb, 0xc0, 0x5e, 0x86, + 0x63, 0x37, 0xe1, 0x0e, 0x9f, 0xba, 0x73, 0xc5, 0xd9, 0x81, 0xb5, 0x51, 0xe0, 0x27, 0xdc, 0x4f, + 0x24, 0xb3, 0x02, 0xed, 0x21, 0x6c, 0x1e, 0x7b, 0x93, 0xe8, 0xe6, 0x82, 0x1e, 0xc0, 0x63, 0xcf, + 0x9f, 0x06, 0x93, 0x67, 0xee, 0x8c, 0xcb, 0x35, 0x1a, 0x86, 0x3d, 0x80, 0x86, 0x80, 0x4e, 0x82, + 0xb8, 0x63, 0x6e, 0x19, 0xdb, 0x6d, 0x27, 0x47, 0xd8, 0x87, 0xf0, 0xde, 0xf3, 0x90, 0xa3, 0xd0, + 0x1b, 0x1a, 0x77, 0xc1, 0x0c, 0x42, 0x12, 0xb7, 0xbe, 0x07, 0xbb, 0xe1, 0xd9, 0x2e, 0x12, 0x9f, + 0x87, 0x8e, 0x19, 0x84, 0x78, 0x1a, 0x1f, 0x37, 0x33, 0xc5, 0x69, 0xf0, 0xdb, 0xbe, 0x82, 0x7b, + 0x37, 0x05, 0xc5, 0x61, 0xe0, 0xc7, 0x7c, 0xa5, 0xa4, 0x7b, 0x50, 0x8b, 0x78, 0x9c, 0x4e, 0x13, + 0x92, 0x55, 0x77, 0x24, 0x84, 0xf8, 0x38, 0x48, 0xa3, 0x11, 0xef, 0x94, 0x69, 0x0f, 0x09, 0x31, + 0x0b, 0xca, 0xb3, 0x78, 0xd2, 0xa9, 0x10, 0x12, 0x3f, 0xed, 0x1d, 0xb8, 0x2b, 0xac, 0xf8, 0x3d, + 0x2c, 0xbe, 0x0d, 0xec, 0x34, 0xe5, 0xd1, 0x7c, 0x98, 0xb8, 0x49, 0x1a, 0x6b, 0x9c, 0x7e, 0x6e, + 0x3a, 0x71, 0x9a, 0x8f, 0x61, 0x83, 0x38, 0x0f, 0xa2, 0x28, 0x88, 0x56, 0x31, 0xfe, 0xd6, 0x80, + 0xce, 0x53, 0xd7, 0x1f, 0x4f, 0xd5, 0xfe, 0xc3, 0xd3, 0xc1, 0x2a, 0xc9, 0xec, 0x3e, 0x59, 0xc3, + 0x24, 0x6b, 0x34, 0xd0, 0x1a, 0xc3, 0xd3, 0x41, 0x6e, 0x56, 0x37, 0x9a, 0xc4, 0x9d, 0xf2, 0x56, + 0x19, 0xd9, 0xf1, 0x1b, 0xbd, 0x77, 0x96, 0x79, 0x4f, 0x1c, 0x3b, 0x47, 0xa0, 0xef, 0xe3, 0x57, + 0xd3, 0x13, 0x37, 0x49, 0x78, 0xe4, 0x77, 0xaa, 0xc2, 0xf7, 0x39, 0xc6, 0x0e, 0xe1, 0x6e, 0x3f, + 0x98, 0xcd, 0x02, 0xff, 0x67, 0x14, 0xa7, 0x99, 0x4b, 0x72, 0xb3, 0x1b, 0x05, 0xb3, 0x4b, 0xf3, + 0x9a, 0x99, 0x79, 0x97, 0x3a, 0xe2, 0x1e, 0xd4, 0x44, 0xec, 0x4b, 0xa5, 0x24, 0x64, 0xff, 0xc9, + 0x80, 0xcd, 0x82, 0x8d, 0xdf, 0x79, 0xc7, 0x4f, 0xa1, 0x25, 0xf6, 0x10, 0x12, 0x68, 0xdf, 0xe6, + 0x9e, 0x45, 0xa6, 0xd2, 0xf0, 0x4e, 0x81, 0x8b, 0x7d, 0x06, 0xed, 0x58, 0x3a, 0x40, 0x2c, 0xab, + 0x6c, 0x95, 0xb7, 0x9b, 0x7b, 0x1b, 0xb4, 0x4c, 0x27, 0x38, 0x45, 0x3e, 0xfb, 0x8f, 0x86, 0x0c, + 0x0a, 0xe9, 0xea, 0x77, 0xd6, 0xf7, 0x11, 0x34, 0x85, 0x5e, 0x24, 0x40, 0xaa, 0x7b, 0x27, 0x57, + 0x57, 0xc8, 0xd5, 0x79, 0xe8, 0x88, 0x42, 0x09, 0xb1, 0x46, 0xe8, 0x6a, 0x69, 0xba, 0x8a, 0x45, + 0x05, 0x2e, 0xfb, 0x0f, 0x06, 0x34, 0xfb, 0x17, 0x7c, 0x24, 0x35, 0x47, 0x15, 0x43, 0x37, 0x8e, + 0xf9, 0x58, 0xa9, 0x28, 0x20, 0x76, 0x17, 0xaa, 0x49, 0x90, 0xb8, 0x53, 0x52, 0xb2, 0xea, 0x08, + 0x80, 0x42, 0x25, 0x1d, 0x8d, 0x78, 0x1c, 0x9f, 0xa7, 0x53, 0xd2, 0xb2, 0xea, 0x68, 0x18, 0x94, + 0x76, 0xee, 0x7a, 0x53, 0x3e, 0x26, 0x87, 0x56, 0x1d, 0x09, 0x61, 0x3d, 0xba, 0x76, 0x23, 0xdf, + 0xf3, 0x27, 0x14, 0x5f, 0x55, 0x47, 0x81, 0xb8, 0x62, 0xcc, 0x13, 0xd7, 0x9b, 0x76, 0x6a, 0x5b, + 0xc6, 0x76, 0xcb, 0x91, 0x90, 0xdd, 0x02, 0xd8, 0x4f, 0x67, 0xa1, 0xb4, 0xef, 0x2f, 0x0c, 0x80, + 0x41, 0xe0, 0x8e, 0xa5, 0xd2, 0x1f, 0x42, 0xfb, 0xdc, 0xf3, 0xbd, 0xf8, 0x82, 0x8f, 0x1f, 0xcf, + 0x13, 0x1e, 0x93, 0xee, 0x65, 0xa7, 0x88, 0x44, 0x65, 0x49, 0x6b, 0xc1, 0x62, 0x12, 0x8b, 0x86, + 0x61, 0x5d, 0xa8, 0x87, 0x51, 0x30, 0x89, 0x78, 0x1c, 0xcb, 0xb8, 0xcc, 0x60, 0x5c, 0x3b, 0xe3, + 0x89, 0x2b, 0x4a, 0x9c, 0x8c, 0x4e, 0x0d, 0x63, 0xff, 0xda, 0x80, 0xf6, 0xf0, 0xc2, 0x8d, 0xc6, + 0x9e, 0x3f, 0x39, 0x8c, 0x82, 0x94, 0x8a, 0x50, 0xe2, 0x46, 0x13, 0xae, 0x2a, 0xae, 0x84, 0x30, + 0x1f, 0xf7, 0xf7, 0x07, 0xb8, 0x3f, 0xe5, 0x23, 0x7e, 0x0b, 0xfd, 0xa3, 0x38, 0x19, 0x04, 0x23, + 0x37, 0xf1, 0x02, 0x5f, 0x6e, 0x5f, 0x44, 0x52, 0xd6, 0xcc, 0xfd, 0x11, 0x19, 0xb3, 0x4c, 0x59, + 0x43, 0x10, 0xea, 0x9d, 0xfa, 0x92, 0x52, 0x25, 0x4a, 0x06, 0xdb, 0xbf, 0x2f, 0x03, 0x0c, 0xe7, + 0xfe, 0x48, 0x1a, 0x6a, 0x0b, 0x9a, 0x74, 0xe0, 0x83, 0x2b, 0xee, 0x27, 0xca, 0x4c, 0x3a, 0x0a, + 0x85, 0x11, 0xf8, 0x22, 0x54, 0x26, 0xca, 0x60, 0x2c, 0x1b, 0x11, 0x1f, 0x71, 0x3f, 0x41, 0x62, + 0x99, 0x88, 0x39, 0x82, 0xd9, 0xd0, 0x9a, 0xb9, 0x71, 0xc2, 0xa3, 0x82, 0x91, 0x0a, 0x38, 0xb6, + 0x03, 0x96, 0x0e, 0x1f, 0x26, 0xde, 0x58, 0x16, 0x98, 0x5b, 0x78, 0x94, 0x47, 0x87, 0x50, 0xf2, + 0x6a, 0x42, 0x9e, 0x8e, 0x43, 0x79, 0x3a, 0x4c, 0xf2, 0xd6, 0x84, 0xbc, 0x9b, 0x78, 0x94, 0x77, + 0x36, 0x0d, 0x46, 0x97, 0x9e, 0x3f, 0x21, 0x07, 0xd4, 0xc9, 0x54, 0x05, 0x1c, 0xfb, 0x02, 0xac, + 0xd4, 0x8f, 0x78, 0x1c, 0x4c, 0xaf, 0xf8, 0x98, 0xfc, 0x18, 0x77, 0x1a, 0x5a, 0xce, 0xeb, 0x1e, + 0x76, 0x6e, 0xb1, 0x6a, 0x1e, 0x02, 0x91, 0x3c, 0xd2, 0x43, 0x3d, 0x00, 0x51, 0x5e, 0x5f, 0xcc, + 0x43, 0xde, 0x69, 0x8a, 0xe8, 0xc9, 0x31, 0xf6, 0xef, 0x0c, 0x68, 0xe9, 0x65, 0x48, 0x2b, 0x90, + 0xc6, 0x92, 0x02, 0x69, 0xea, 0x05, 0x92, 0x7d, 0x92, 0x15, 0x16, 0x51, 0x29, 0x48, 0xdb, 0x93, + 0x28, 0xc0, 0x3c, 0x74, 0x88, 0x90, 0xd5, 0x9a, 0x47, 0xd0, 0x8c, 0xb0, 0xd3, 0x67, 0x15, 0x2d, + 0xab, 0x2c, 0x4e, 0x8e, 0x76, 0x74, 0x1e, 0xfb, 0xaf, 0x26, 0x34, 0x35, 0xe2, 0x2d, 0x4f, 0x1b, + 0xdf, 0xd3, 0xd3, 0xe6, 0x12, 0x4f, 0x6f, 0x29, 0x95, 0xd2, 0xb3, 0x7d, 0x2f, 0x92, 0xc1, 0xaf, + 0xa3, 0x32, 0x8e, 0x42, 0x68, 0xe9, 0x28, 0xb6, 0x0d, 0x77, 0x34, 0x50, 0x0b, 0xac, 0x9b, 0x68, + 0xb6, 0x0b, 0x8c, 0x50, 0x7d, 0x37, 0x19, 0x5d, 0xbc, 0x0c, 0x8f, 0x49, 0x1b, 0x8a, 0xae, 0xba, + 0xb3, 0x80, 0xc2, 0xfe, 0x1f, 0xaa, 0x71, 0xe2, 0x4e, 0x38, 0x05, 0x96, 0x6a, 0xaf, 0x88, 0x70, + 0x04, 0x5e, 0x33, 0x7e, 0xfd, 0x2d, 0xc6, 0xb7, 0xff, 0x6d, 0x42, 0xbb, 0xd0, 0x38, 0x16, 0x76, + 0xf3, 0x6c, 0x47, 0x73, 0xc9, 0x8e, 0x5b, 0x50, 0x49, 0x7d, 0x4f, 0x38, 0x7b, 0x7d, 0xaf, 0x85, + 0xf4, 0x97, 0xbe, 0x97, 0x60, 0x2c, 0x39, 0x44, 0xd1, 0x74, 0xaa, 0xbc, 0x2d, 0x20, 0x7e, 0x00, + 0x9b, 0x79, 0x20, 0xef, 0xef, 0x0f, 0x06, 0xc1, 0xe8, 0xf2, 0x68, 0x5f, 0x5a, 0x6f, 0x11, 0x89, + 0x31, 0xd1, 0xae, 0x28, 0x21, 0x9f, 0x96, 0x44, 0xc3, 0xfa, 0x18, 0xaa, 0x23, 0x6c, 0x23, 0x64, + 0x25, 0x19, 0x50, 0x5a, 0x5f, 0x79, 0x5a, 0x72, 0x04, 0x9d, 0x7d, 0x08, 0x95, 0x71, 0x3a, 0x0b, + 0xa5, 0xad, 0xd6, 0x91, 0x2f, 0x2f, 0xec, 0x4f, 0x4b, 0x0e, 0x51, 0x91, 0x6b, 0x1a, 0xb8, 0xe3, + 0x4e, 0x23, 0xe7, 0xca, 0xeb, 0x3d, 0x72, 0x21, 0x15, 0xb9, 0x30, 0xc3, 0x28, 0xdb, 0x24, 0x57, + 0x5e, 0xec, 0x90, 0x0b, 0xa9, 0x8f, 0xeb, 0x50, 0x8b, 0x45, 0x20, 0xff, 0x04, 0x36, 0x0a, 0xd6, + 0x1f, 0x78, 0x31, 0x99, 0x4a, 0x90, 0x3b, 0xc6, 0xb2, 0xee, 0xae, 0xd6, 0xf7, 0x00, 0xe8, 0x4c, + 0xa2, 0xe1, 0xca, 0xae, 0x6d, 0xe4, 0xd7, 0xc6, 0x0f, 0xa0, 0x81, 0x67, 0x59, 0x41, 0xc6, 0x43, + 0x2c, 0x23, 0x87, 0xd0, 0x22, 0xed, 0x4f, 0x07, 0x4b, 0x38, 0xd8, 0x1e, 0xdc, 0x15, 0x0d, 0x34, + 0xbb, 0x6a, 0x7b, 0xd4, 0x2e, 0x44, 0x62, 0x2d, 0xa4, 0x61, 0x41, 0xe7, 0x28, 0x6e, 0x78, 0x3a, + 0x50, 0x5d, 0x4d, 0xc1, 0xf6, 0x8f, 0xa0, 0x81, 0x3b, 0x8a, 0xed, 0xb6, 0xa1, 0x46, 0x04, 0x65, + 0x07, 0x2b, 0x33, 0xa7, 0x54, 0xc8, 0x91, 0x74, 0xfb, 0x97, 0x46, 0xe1, 0x76, 0xf2, 0xce, 0xd5, + 0x6a, 0xeb, 0xf6, 0xe5, 0xa6, 0x51, 0xbc, 0xcb, 0xec, 0x02, 0x50, 0xc1, 0x51, 0x37, 0x99, 0xcc, + 0xbd, 0x39, 0xd6, 0xd1, 0x38, 0xd0, 0x31, 0x39, 0xb4, 0xc0, 0xb4, 0xbf, 0x31, 0xa1, 0xa5, 0x5f, + 0x82, 0xfe, 0x57, 0x69, 0xc7, 0xb4, 0x97, 0x84, 0xca, 0x8c, 0x8f, 0x54, 0x66, 0x54, 0xf3, 0x63, + 0xe4, 0x51, 0x94, 0x27, 0xc6, 0x43, 0x99, 0x18, 0x35, 0x62, 0x6b, 0xab, 0xc4, 0x50, 0x5c, 0x22, + 0x2f, 0x1e, 0xca, 0xbc, 0x58, 0xcb, 0x99, 0xb2, 0x90, 0xca, 0xd2, 0xe2, 0xa1, 0x4c, 0x8b, 0x7a, + 0xce, 0x94, 0xb9, 0x39, 0xcb, 0x8a, 0x35, 0xa8, 0x92, 0x3b, 0xed, 0xcf, 0xc1, 0xd2, 0x4d, 0x43, + 0x39, 0xf1, 0x91, 0x24, 0x16, 0x42, 0x41, 0xbf, 0x44, 0xca, 0xb5, 0xaf, 0xa0, 0x5d, 0x28, 0x2a, + 0xd8, 0xe9, 0xbc, 0xb8, 0xef, 0xfa, 0x23, 0x3e, 0xcd, 0xae, 0x90, 0x1a, 0x46, 0x0b, 0x32, 0x33, + 0x97, 0x2c, 0x45, 0x14, 0x82, 0x4c, 0xbb, 0x08, 0x96, 0x0b, 0x17, 0xc1, 0xbf, 0x1b, 0xd0, 0xd2, + 0x17, 0xe0, 0x5d, 0xf2, 0x20, 0x8a, 0xfa, 0xc1, 0x58, 0x78, 0xb3, 0xea, 0x28, 0x10, 0x43, 0x1f, + 0x3f, 0xa7, 0x6e, 0x1c, 0xcb, 0x08, 0xcc, 0x60, 0x49, 0x1b, 0x8e, 0x82, 0x50, 0x3d, 0x42, 0x32, + 0x58, 0xd2, 0x06, 0xfc, 0x8a, 0x4f, 0x65, 0xab, 0xc9, 0x60, 0xdc, 0xed, 0x98, 0xc7, 0x31, 0x86, + 0x89, 0xa8, 0x90, 0x0a, 0xc4, 0x55, 0x8e, 0x7b, 0xdd, 0x77, 0xd3, 0x98, 0xcb, 0xbb, 0x4a, 0x06, + 0xa3, 0x59, 0xf0, 0xb1, 0xe4, 0x46, 0x41, 0xea, 0xab, 0x1b, 0x8a, 0x86, 0xb1, 0xbb, 0xd0, 0x19, + 0x5e, 0x7b, 0xc9, 0xe8, 0x82, 0xa2, 0x58, 0x34, 0x1e, 0xf9, 0xde, 0xb3, 0xf7, 0x60, 0x53, 0xbe, + 0x81, 0x0b, 0x2f, 0xf4, 0xff, 0xd3, 0x1e, 0xc0, 0xcd, 0x2c, 0x35, 0xc4, 0xa3, 0xcf, 0x4e, 0xe1, + 0x6e, 0x71, 0x8d, 0x7c, 0x80, 0xac, 0x5a, 0xf4, 0x5f, 0x78, 0x36, 0x5f, 0xc3, 0xc6, 0x49, 0x1a, + 0x4d, 0x8a, 0x8a, 0x76, 0xa1, 0xee, 0xf9, 0xee, 0x28, 0xf1, 0xae, 0xb8, 0x0c, 0x88, 0x0c, 0xa6, + 0xf7, 0xb4, 0x27, 0xdf, 0xfc, 0x65, 0x87, 0xbe, 0x91, 0xff, 0xdc, 0x9b, 0x72, 0x4a, 0x4f, 0xe9, + 0x19, 0x05, 0x93, 0x2a, 0xe2, 0x92, 0x20, 0x1f, 0x88, 0x02, 0x42, 0xfb, 0xd1, 0x73, 0x4b, 0xbc, + 0x48, 0xfb, 0x81, 0x7f, 0xee, 0x4d, 0x94, 0xfd, 0xae, 0xe1, 0xfe, 0x02, 0xda, 0x5b, 0x5e, 0x64, + 0xf9, 0x99, 0xcd, 0x45, 0x67, 0x2e, 0xe7, 0x35, 0x59, 0x1b, 0xad, 0x54, 0x8a, 0xa3, 0x95, 0x3f, + 0x1b, 0xd0, 0x95, 0x5e, 0x10, 0x7b, 0x0f, 0x47, 0x17, 0x7c, 0xe6, 0x2a, 0xbb, 0x3c, 0xd0, 0x7c, + 0x41, 0xb5, 0x44, 0x90, 0xf3, 0x67, 0x3b, 0x4d, 0x1a, 0xcc, 0x7c, 0xd2, 0xb0, 0xd4, 0x11, 0x5d, + 0xa8, 0x8f, 0xdd, 0xc4, 0x3d, 0x73, 0x63, 0xae, 0xe2, 0x55, 0xc1, 0xf4, 0x6e, 0x73, 0xcf, 0xa6, + 0x2a, 0x5a, 0x05, 0x40, 0x92, 0x68, 0x37, 0x19, 0xa9, 0x12, 0xb2, 0x13, 0x68, 0x7f, 0xfb, 0x48, + 0x26, 0xfa, 0x31, 0x4f, 0xdc, 0x95, 0x63, 0x96, 0xb7, 0xd6, 0x4b, 0x55, 0x64, 0xcb, 0x5a, 0x91, + 0x55, 0xe7, 0xaa, 0x50, 0x52, 0x8b, 0x09, 0xca, 0xa7, 0x59, 0xb4, 0x7e, 0xfb, 0x08, 0x77, 0x5d, + 0x6a, 0x21, 0x41, 0x96, 0x31, 0xfe, 0x17, 0x23, 0x9b, 0x32, 0xa9, 0x65, 0xef, 0xfc, 0xcc, 0xfe, + 0x0c, 0x2a, 0xf8, 0x88, 0xa3, 0xe1, 0x48, 0x73, 0xef, 0x21, 0xee, 0xb1, 0x50, 0xe4, 0x2e, 0x02, + 0x07, 0x7e, 0x12, 0xcd, 0x1d, 0x5a, 0xd0, 0xfd, 0x1a, 0x1a, 0x19, 0x0a, 0xe5, 0x5e, 0xf2, 0xb9, + 0xea, 0x37, 0x97, 0x7c, 0x8e, 0xb7, 0xa1, 0x2b, 0x77, 0x9a, 0x0a, 0xd3, 0xc8, 0x2b, 0x45, 0xc1, + 0xb0, 0x8e, 0xa0, 0x7f, 0x6e, 0xfe, 0xd8, 0xd8, 0xf9, 0x39, 0xd4, 0x84, 0x55, 0x59, 0x1b, 0x1a, + 0x47, 0xfe, 0x95, 0x3b, 0xf5, 0xc6, 0xcf, 0x43, 0xab, 0xc4, 0xea, 0x50, 0x19, 0x26, 0x41, 0x68, + 0x19, 0xac, 0x01, 0xd5, 0x13, 0x2c, 0x24, 0x96, 0xc9, 0x00, 0x6a, 0x58, 0x6b, 0x67, 0xdc, 0x2a, + 0x23, 0x9a, 0xe6, 0x82, 0x56, 0x05, 0xd1, 0x62, 0x62, 0x65, 0x55, 0xd9, 0x3a, 0xc0, 0x57, 0x69, + 0x12, 0x48, 0xb6, 0xda, 0xce, 0x0e, 0x54, 0x69, 0x1e, 0x44, 0x02, 0xbf, 0x39, 0x3a, 0xb1, 0x4a, + 0xac, 0x09, 0x6b, 0xce, 0xc1, 0xc9, 0xe0, 0xab, 0xfe, 0x81, 0x65, 0xe0, 0xda, 0xa3, 0x67, 0x5f, + 0x1f, 0xf4, 0x5f, 0x58, 0xe6, 0xce, 0x2b, 0x12, 0x39, 0xc1, 0x48, 0x6f, 0x49, 0x5d, 0x08, 0xb6, + 0x4a, 0x6c, 0x0d, 0xca, 0xcf, 0xf8, 0xb5, 0x65, 0xd0, 0xe2, 0xd4, 0xc7, 0xe7, 0xba, 0xd0, 0x87, + 0x54, 0x1b, 0x5b, 0x65, 0x24, 0xa0, 0xc2, 0x21, 0x1f, 0x5b, 0x15, 0xd6, 0x82, 0xfa, 0x13, 0xf9, + 0xfe, 0xb6, 0xaa, 0x48, 0x42, 0x36, 0x5c, 0x53, 0x43, 0x12, 0x29, 0x87, 0xd0, 0xda, 0xce, 0x73, + 0xa8, 0xab, 0x36, 0xca, 0xee, 0x40, 0x53, 0xee, 0x8a, 0x28, 0xab, 0x84, 0x47, 0xa4, 0x66, 0x69, + 0x19, 0xa8, 0x3d, 0x36, 0x44, 0xcb, 0xc4, 0x2f, 0xec, 0x7a, 0x56, 0x99, 0x4e, 0x34, 0xf7, 0x47, + 0x56, 0x05, 0x19, 0xa9, 0xec, 0x58, 0xe3, 0x9d, 0x63, 0x58, 0x93, 0x75, 0x8d, 0x31, 0x58, 0x97, + 0xf2, 0x24, 0xc6, 0x2a, 0xa1, 0x95, 0x51, 0x4b, 0xc1, 0x6d, 0xa0, 0xb5, 0xe8, 0x00, 0x02, 0x36, + 0x51, 0x05, 0x61, 0x39, 0x81, 0x28, 0xa3, 0x7e, 0x2a, 0x35, 0xd9, 0x26, 0xdc, 0x51, 0x56, 0x91, + 0x28, 0x21, 0xf0, 0x90, 0x27, 0x02, 0x61, 0x19, 0x24, 0x3f, 0x03, 0x4d, 0x34, 0xa4, 0xc3, 0x67, + 0xc1, 0x15, 0x97, 0x98, 0xf2, 0xce, 0x97, 0x50, 0x57, 0x91, 0xac, 0x09, 0x54, 0xa8, 0x4c, 0xa0, + 0x40, 0x58, 0x46, 0x2e, 0x41, 0x62, 0xcc, 0xbd, 0x7f, 0xad, 0x41, 0x4d, 0xd4, 0x14, 0xd6, 0x87, + 0x96, 0x3e, 0x1b, 0x66, 0xef, 0xcb, 0x34, 0xbc, 0x39, 0x2d, 0xee, 0x76, 0xe8, 0xe2, 0xb1, 0x60, + 0x70, 0x67, 0x97, 0xd8, 0x11, 0xac, 0x17, 0xe7, 0xac, 0xec, 0xbe, 0x96, 0x0b, 0x37, 0x04, 0x75, + 0x17, 0x91, 0x32, 0x51, 0x07, 0xd0, 0x2e, 0x8c, 0x4e, 0x19, 0xed, 0xbb, 0x68, 0x9a, 0xba, 0x52, + 0xa3, 0x2f, 0xa1, 0xa9, 0x4d, 0xfc, 0xd8, 0x3d, 0x64, 0xbd, 0x3d, 0x66, 0xed, 0xbe, 0x7f, 0x0b, + 0x9f, 0x49, 0xf8, 0x02, 0x20, 0x1f, 0xc1, 0xb1, 0xf7, 0x32, 0x46, 0x7d, 0xfa, 0xda, 0xbd, 0x77, + 0x13, 0x9d, 0x2d, 0x7f, 0x02, 0x20, 0x47, 0xb0, 0xa7, 0x83, 0x98, 0x3d, 0x40, 0xbe, 0x65, 0x23, + 0xd9, 0x95, 0x07, 0x39, 0x86, 0x8d, 0x5b, 0xad, 0x5d, 0x88, 0x5b, 0xd6, 0xf1, 0x57, 0x8a, 0xeb, + 0x43, 0x4b, 0xef, 0xec, 0xc2, 0xdd, 0x0b, 0xee, 0x07, 0x42, 0xc8, 0xa2, 0x4b, 0x80, 0x5d, 0x62, + 0x3f, 0x05, 0xc8, 0xfb, 0xb4, 0x30, 0xcd, 0xad, 0xbe, 0xbd, 0x52, 0x8b, 0x43, 0xd8, 0xd0, 0xfe, + 0x32, 0x88, 0x9e, 0x2a, 0x7c, 0x74, 0xfb, 0xe7, 0xc3, 0x4a, 0x41, 0x8e, 0x1c, 0x89, 0xeb, 0xcd, + 0x59, 0x58, 0x67, 0x59, 0x3f, 0xef, 0x7e, 0xb0, 0x84, 0xaa, 0x9b, 0x48, 0xff, 0xa5, 0x21, 0x4c, + 0xb4, 0xe0, 0x27, 0xc7, 0x4a, 0xc5, 0xbe, 0x81, 0xb6, 0x0a, 0x71, 0x4a, 0x5b, 0xd6, 0xd3, 0xec, + 0xb9, 0xa0, 0x9d, 0xaf, 0x14, 0xf6, 0x24, 0x13, 0x26, 0x32, 0x98, 0x75, 0x16, 0x74, 0x1a, 0x21, + 0xe6, 0xfe, 0xd2, 0x1e, 0x64, 0x97, 0x1e, 0x77, 0xfe, 0xf6, 0xba, 0x67, 0x7c, 0xf7, 0xba, 0x67, + 0xfc, 0xf3, 0x75, 0xcf, 0xf8, 0xd5, 0x9b, 0x5e, 0xe9, 0xbb, 0x37, 0xbd, 0xd2, 0x3f, 0xde, 0xf4, + 0x4a, 0x67, 0x35, 0xfa, 0x59, 0xf4, 0xc3, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x6a, 0xbc, 0xaa, + 0xcb, 0x3e, 0x1a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3072,6 +3288,7 @@ type WorkerClient interface { // a `set`/`remove` operation should be an one-time operation (only take effect once), // so we use a gRPC method rather than a etcd operation now (no persistent operation state). OperateSchema(ctx context.Context, in *OperateWorkerSchemaRequest, opts ...grpc.CallOption) (*CommonWorkerResponse, error) + OperateV1Meta(ctx context.Context, in *OperateV1MetaRequest, opts ...grpc.CallOption) (*OperateV1MetaResponse, error) } type workerClient struct { @@ -3199,6 +3416,15 @@ func (c *workerClient) OperateSchema(ctx context.Context, in *OperateWorkerSchem return out, nil } +func (c *workerClient) OperateV1Meta(ctx context.Context, in *OperateV1MetaRequest, opts ...grpc.CallOption) (*OperateV1MetaResponse, error) { + out := new(OperateV1MetaResponse) + err := c.cc.Invoke(ctx, "/pb.Worker/OperateV1Meta", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // WorkerServer is the server API for Worker service. type WorkerServer interface { StartSubTask(context.Context, *StartSubTaskRequest) (*CommonWorkerResponse, error) @@ -3221,6 +3447,7 @@ type WorkerServer interface { // a `set`/`remove` operation should be an one-time operation (only take effect once), // so we use a gRPC method rather than a etcd operation now (no persistent operation state). OperateSchema(context.Context, *OperateWorkerSchemaRequest) (*CommonWorkerResponse, error) + OperateV1Meta(context.Context, *OperateV1MetaRequest) (*OperateV1MetaResponse, error) } // UnimplementedWorkerServer can be embedded to have forward compatible implementations. @@ -3266,6 +3493,9 @@ func (*UnimplementedWorkerServer) MigrateRelay(ctx context.Context, req *Migrate func (*UnimplementedWorkerServer) OperateSchema(ctx context.Context, req *OperateWorkerSchemaRequest) (*CommonWorkerResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method OperateSchema not implemented") } +func (*UnimplementedWorkerServer) OperateV1Meta(ctx context.Context, req *OperateV1MetaRequest) (*OperateV1MetaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OperateV1Meta not implemented") +} func RegisterWorkerServer(s *grpc.Server, srv WorkerServer) { s.RegisterService(&_Worker_serviceDesc, srv) @@ -3505,6 +3735,24 @@ func _Worker_OperateSchema_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Worker_OperateV1Meta_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OperateV1MetaRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkerServer).OperateV1Meta(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.Worker/OperateV1Meta", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkerServer).OperateV1Meta(ctx, req.(*OperateV1MetaRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Worker_serviceDesc = grpc.ServiceDesc{ ServiceName: "pb.Worker", HandlerType: (*WorkerServer)(nil), @@ -3561,6 +3809,10 @@ var _Worker_serviceDesc = grpc.ServiceDesc{ MethodName: "OperateSchema", Handler: _Worker_OperateSchema_Handler, }, + { + MethodName: "OperateV1Meta", + Handler: _Worker_OperateV1Meta_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "dmworker.proto", @@ -5591,6 +5843,147 @@ func (m *OperateWorkerSchemaRequest) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *V1SubTaskMeta) 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 *V1SubTaskMeta) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *V1SubTaskMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Task) > 0 { + i -= len(m.Task) + copy(dAtA[i:], m.Task) + i = encodeVarintDmworker(dAtA, i, uint64(len(m.Task))) + i-- + dAtA[i] = 0x22 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintDmworker(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + } + if m.Stage != 0 { + i = encodeVarintDmworker(dAtA, i, uint64(m.Stage)) + i-- + dAtA[i] = 0x10 + } + if m.Op != 0 { + i = encodeVarintDmworker(dAtA, i, uint64(m.Op)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *OperateV1MetaRequest) 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 *OperateV1MetaRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OperateV1MetaRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Op != 0 { + i = encodeVarintDmworker(dAtA, i, uint64(m.Op)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *OperateV1MetaResponse) 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 *OperateV1MetaResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OperateV1MetaResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Meta) > 0 { + for k := range m.Meta { + v := m.Meta[k] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintDmworker(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarintDmworker(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarintDmworker(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintDmworker(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x12 + } + if m.Result { + i-- + if m.Result { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintDmworker(dAtA []byte, offset int, v uint64) int { offset -= sovDmworker(v) base := offset @@ -6541,6 +6934,70 @@ func (m *OperateWorkerSchemaRequest) Size() (n int) { return n } +func (m *V1SubTaskMeta) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Op != 0 { + n += 1 + sovDmworker(uint64(m.Op)) + } + if m.Stage != 0 { + n += 1 + sovDmworker(uint64(m.Stage)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovDmworker(uint64(l)) + } + l = len(m.Task) + if l > 0 { + n += 1 + l + sovDmworker(uint64(l)) + } + return n +} + +func (m *OperateV1MetaRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Op != 0 { + n += 1 + sovDmworker(uint64(m.Op)) + } + return n +} + +func (m *OperateV1MetaResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result { + n += 2 + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovDmworker(uint64(l)) + } + if len(m.Meta) > 0 { + for k, v := range m.Meta { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovDmworker(uint64(l)) + } + mapEntrySize := 1 + len(k) + sovDmworker(uint64(len(k))) + l + n += mapEntrySize + 1 + sovDmworker(uint64(mapEntrySize)) + } + } + return n +} + func sovDmworker(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -12381,6 +12838,469 @@ func (m *OperateWorkerSchemaRequest) Unmarshal(dAtA []byte) error { } return nil } +func (m *V1SubTaskMeta) 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 ErrIntOverflowDmworker + } + 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: V1SubTaskMeta: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: V1SubTaskMeta: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Op", wireType) + } + m.Op = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Op |= TaskOp(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Stage", wireType) + } + m.Stage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Stage |= Stage(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDmworker + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDmworker + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Task", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthDmworker + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthDmworker + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Task = append(m.Task[:0], dAtA[iNdEx:postIndex]...) + if m.Task == nil { + m.Task = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipDmworker(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OperateV1MetaRequest) 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 ErrIntOverflowDmworker + } + 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: OperateV1MetaRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OperateV1MetaRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Op", wireType) + } + m.Op = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Op |= V1MetaOp(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipDmworker(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OperateV1MetaResponse) 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 ErrIntOverflowDmworker + } + 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: OperateV1MetaResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OperateV1MetaResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Result = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthDmworker + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDmworker + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthDmworker + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthDmworker + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Meta == nil { + m.Meta = make(map[string]*V1SubTaskMeta) + } + var mapkey string + var mapvalue *V1SubTaskMeta + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthDmworker + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthDmworker + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDmworker + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthDmworker + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthDmworker + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &V1SubTaskMeta{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipDmworker(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Meta[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipDmworker(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthDmworker + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipDmworker(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/dm/pbmock/dmworker.go b/dm/pbmock/dmworker.go index 0522243f70..b4970f49af 100644 --- a/dm/pbmock/dmworker.go +++ b/dm/pbmock/dmworker.go @@ -135,6 +135,26 @@ func (mr *MockWorkerClientMockRecorder) OperateSubTask(arg0, arg1 interface{}, a return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OperateSubTask", reflect.TypeOf((*MockWorkerClient)(nil).OperateSubTask), varargs...) } +// OperateV1Meta mocks base method +func (m *MockWorkerClient) OperateV1Meta(arg0 context.Context, arg1 *pb.OperateV1MetaRequest, arg2 ...grpc.CallOption) (*pb.OperateV1MetaResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "OperateV1Meta", varargs...) + ret0, _ := ret[0].(*pb.OperateV1MetaResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OperateV1Meta indicates an expected call of OperateV1Meta +func (mr *MockWorkerClientMockRecorder) OperateV1Meta(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OperateV1Meta", reflect.TypeOf((*MockWorkerClient)(nil).OperateV1Meta), varargs...) +} + // PurgeRelay mocks base method func (m *MockWorkerClient) PurgeRelay(arg0 context.Context, arg1 *pb.PurgeRelayRequest, arg2 ...grpc.CallOption) (*pb.CommonWorkerResponse, error) { m.ctrl.T.Helper() @@ -393,6 +413,21 @@ func (mr *MockWorkerServerMockRecorder) OperateSubTask(arg0, arg1 interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OperateSubTask", reflect.TypeOf((*MockWorkerServer)(nil).OperateSubTask), arg0, arg1) } +// OperateV1Meta mocks base method +func (m *MockWorkerServer) OperateV1Meta(arg0 context.Context, arg1 *pb.OperateV1MetaRequest) (*pb.OperateV1MetaResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "OperateV1Meta", arg0, arg1) + ret0, _ := ret[0].(*pb.OperateV1MetaResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// OperateV1Meta indicates an expected call of OperateV1Meta +func (mr *MockWorkerServerMockRecorder) OperateV1Meta(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OperateV1Meta", reflect.TypeOf((*MockWorkerServer)(nil).OperateV1Meta), arg0, arg1) +} + // PurgeRelay mocks base method func (m *MockWorkerServer) PurgeRelay(arg0 context.Context, arg1 *pb.PurgeRelayRequest) (*pb.CommonWorkerResponse, error) { m.ctrl.T.Helper() diff --git a/dm/proto/dmworker.proto b/dm/proto/dmworker.proto index d0bd70642d..4d08aa429a 100644 --- a/dm/proto/dmworker.proto +++ b/dm/proto/dmworker.proto @@ -33,6 +33,8 @@ service Worker { // a `set`/`remove` operation should be an one-time operation (only take effect once), // so we use a gRPC method rather than a etcd operation now (no persistent operation state). rpc OperateSchema(OperateWorkerSchemaRequest) returns(CommonWorkerResponse) {} + + rpc OperateV1Meta(OperateV1MetaRequest) returns(OperateV1MetaResponse) {} } message StartSubTaskRequest { @@ -418,4 +420,28 @@ message OperateWorkerSchemaRequest { string database = 4; // database name string table = 5; // table name string schema = 6; // schema content, a `CREATE TABLE` statement -} \ No newline at end of file +} + +// copied `TaskMeta` from release-1.0 branch. +message V1SubTaskMeta { + TaskOp op = 1; + Stage stage = 2; // the stage of sub-task after we apply some operations + string name = 3; // sub task's name + bytes task = 4; // (sub) task's configuration +} + +enum V1MetaOp { + InvalidV1MetaOp = 0; + GetV1Meta = 1; + RemoveV1Meta = 2; +} + +message OperateV1MetaRequest { + V1MetaOp op = 1; +} + +message OperateV1MetaResponse { + bool result = 1; + string msg = 2; // error message if failed. + map meta = 3; // subtasks' meta for `get` operation. +} diff --git a/dm/worker/v1meta.go b/dm/worker/v1meta.go new file mode 100644 index 0000000000..8d64335cbe --- /dev/null +++ b/dm/worker/v1meta.go @@ -0,0 +1,61 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package worker + +import ( + "context" + "fmt" + + "go.uber.org/zap" + + "github.com/pingcap/dm/dm/pb" + "github.com/pingcap/dm/pkg/log" + "github.com/pingcap/dm/pkg/v1workermeta" +) + +// OperateV1Meta implements WorkerServer.OperateV1Meta. +func (s *Server) OperateV1Meta(ctx context.Context, req *pb.OperateV1MetaRequest) (*pb.OperateV1MetaResponse, error) { + log.L().Info("", zap.String("request", "OperateV1Meta"), zap.Stringer("payload", req)) + + switch req.Op { + case pb.V1MetaOp_GetV1Meta: + meta, err := v1workermeta.GetSubtasksMeta() + if err != nil { + return &pb.OperateV1MetaResponse{ + Result: false, + Msg: err.Error(), + }, nil + } + return &pb.OperateV1MetaResponse{ + Result: true, + Meta: meta, + }, nil + case pb.V1MetaOp_RemoveV1Meta: + err := v1workermeta.RemoveSubtasksMeta() + if err != nil { + return &pb.OperateV1MetaResponse{ + Result: false, + Msg: err.Error(), + }, nil + } + return &pb.OperateV1MetaResponse{ + Result: true, + }, nil + default: + return &pb.OperateV1MetaResponse{ + Result: false, + Msg: fmt.Sprintf("invalid op %s", req.Op.String()), + }, nil + } +} diff --git a/errors.toml b/errors.toml index c6f2248034..e7a50c345e 100644 --- a/errors.toml +++ b/errors.toml @@ -718,6 +718,12 @@ description = "" workaround = "Please use `list-member --master` to confirm whether the DM-master cluster is healthy" tags = ["internal", "high"] +[error.DM-functional-11115] +message = "%s is an invalid v1.0.x DM-worker meta path" +description = "" +workaround = "Please check no `meta-dir` set for v1.0.x DM-worker" +tags = ["internal", "medium"] + [error.DM-config-20001] message = "checking item %s is not supported\n%s" description = "" diff --git a/go.mod b/go.mod index 915a8bbf87..1378758202 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 + github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285 github.com/twitchtv/retool v1.3.8-0.20180918173430-41330f8b4e07 github.com/uber-go/atomic v1.4.0 // indirect github.com/unrolled/render v1.0.1 diff --git a/pkg/terror/error_list.go b/pkg/terror/error_list.go index c0044c0ce9..112f4cabc3 100644 --- a/pkg/terror/error_list.go +++ b/pkg/terror/error_list.go @@ -159,6 +159,9 @@ const ( // pkg/upgrade codeUpgradeVersionEtcdFail + + // pkg/v1workermeta + codeInvalidV1WorkerMetaPath ) // Config related error code list @@ -724,6 +727,9 @@ var ( // pkg/upgrade ErrUpgradeVersionEtcdFail = New(codeUpgradeVersionEtcdFail, ClassFunctional, ScopeInternal, LevelHigh, "fail to operate DM cluster version in etcd", "Please use `list-member --master` to confirm whether the DM-master cluster is healthy") + // pkg/v1workermeta + ErrInvalidV1WorkerMetaPath = New(codeInvalidV1WorkerMetaPath, ClassFunctional, ScopeInternal, LevelMedium, "%s is an invalid v1.0.x DM-worker meta path", "Please check no `meta-dir` set for v1.0.x DM-worker") + // Config related error ErrConfigCheckItemNotSupport = New(codeConfigCheckItemNotSupport, ClassConfig, ScopeInternal, LevelMedium, "checking item %s is not supported\n%s", "Please check `ignore-checking-items` config in task configuration file, which can be set including `all`/`dump_privilege`/`replication_privilege`/`version`/`binlog_enable`/`binlog_format`/`binlog_row_image`/`table_schema`/`schema_of_shard_tables`/`auto_increment_ID`.") ErrConfigTomlTransform = New(codeConfigTomlTransform, ClassConfig, ScopeInternal, LevelMedium, "%s", "Please check the configuration file has correct TOML format.") diff --git a/pkg/v1workermeta/api.go b/pkg/v1workermeta/api.go new file mode 100644 index 0000000000..d9026be256 --- /dev/null +++ b/pkg/v1workermeta/api.go @@ -0,0 +1,108 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1workermeta + +import ( + "os" + "path/filepath" + "strconv" + + "github.com/BurntSushi/toml" + + "github.com/pingcap/dm/dm/config" + "github.com/pingcap/dm/dm/pb" + "github.com/pingcap/dm/pkg/terror" + "github.com/pingcap/dm/pkg/utils" +) + +// `var` rather than `const` for testing. +var ( + // metaPath is the meta data path in v1.0.x. + metaPath = "./dm_worker_meta" + // dbPath is the levelDB path in v1.0.x. + dbPath = "./dm_worker_meta/kv" +) + +// v1SubTaskConfig represents the subtask config in v1.0.x. +type v1SubTaskConfig struct { + config.SubTaskConfig // embed the subtask config in v2.0.x. + + // NOTE: in v1.0.x, `ChunkFilesize` is `int64`, but in v2.0.x it's `string`. + // (ref: https://github.com/pingcap/dm/pull/713). + // if we decode data with v1.0.x from TOML directly, + // an error of `toml: cannot load TOML value of type int64 into a Go string` will be reported, + // so we overwrite it with another filed which has the same struct tag `chunk-filesize` here. + // but if set `chunk-filesize: 64` in a YAML file, both v1.0.x (int64) and v2.0.x (string) can support it. + ChunkFilesize int64 `yaml:"chunk-filesize" toml:"chunk-filesize" json:"chunk-filesize"` // -F, --chunk-filesize +} + +// GetSubtasksMeta gets all subtasks' meta (config and status) from `dm_worker_meta` in v1.0.x. +func GetSubtasksMeta() (map[string]*pb.V1SubTaskMeta, error) { + // check if meta data exist. + if !utils.IsDirExists(metaPath) || !utils.IsDirExists(dbPath) { + return nil, nil + } + + // open levelDB to get subtasks meta. + db, err := openDB(dbPath, defaultKVConfig) + if err != nil { + return nil, err + } + defer db.Close() + + // load subtasks' meta from levelDB. + meta, err := newMeta(db) + if err != nil { + return nil, err + } + + return meta.TasksMeta(), nil +} + +// RemoveSubtasksMeta removes subtasks' metadata. +// this is often called after upgraded from v1.0.x to v2.0.x, +// so no need to handle again after re-started the DM-worker process. +func RemoveSubtasksMeta() error { + // check is a valid v1.0.x meta path. + if !utils.IsDirExists(metaPath) || !utils.IsDirExists(dbPath) { + return terror.ErrInvalidV1WorkerMetaPath.Generate(filepath.Abs(metaPath)) + } + + // try to open levelDB to check. + db, err := openDB(dbPath, defaultKVConfig) + if err != nil { + return terror.ErrInvalidV1WorkerMetaPath.Generate(filepath.Abs(metaPath)) + } + defer db.Close() + + return os.RemoveAll(metaPath) +} + +// SubTaskConfigFromV1TOML gets SubTaskConfig from subtask's TOML data with v1.0.x. +func SubTaskConfigFromV1TOML(data []byte) (config.SubTaskConfig, error) { + var v1Cfg v1SubTaskConfig + _, err := toml.Decode(string(data), &v1Cfg) + if err != nil { + return config.SubTaskConfig{}, terror.ErrConfigTomlTransform.Delegate(err, "decode v1 subtask config from data") + } + + cfg := v1Cfg.SubTaskConfig + cfg.MydumperConfig.ChunkFilesize = strconv.FormatInt(v1Cfg.ChunkFilesize, 10) + err = cfg.Adjust(true) + if err != nil { + return config.SubTaskConfig{}, terror.ErrConfigTomlTransform.Delegate(err, "transform `chunk-filesize`") + } + + return cfg, nil +} diff --git a/pkg/v1workermeta/api_test.go b/pkg/v1workermeta/api_test.go new file mode 100644 index 0000000000..9c0065fb35 --- /dev/null +++ b/pkg/v1workermeta/api_test.go @@ -0,0 +1,156 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1workermeta + +import ( + "io" + "io/ioutil" + "os" + "path/filepath" + "runtime" + + . "github.com/pingcap/check" + + "github.com/pingcap/dm/dm/pb" + "github.com/pingcap/dm/pkg/terror" + "github.com/pingcap/dm/pkg/utils" +) + +type testAPI struct{} + +var _ = Suite(&testAPI{}) + +func (t *testAPI) TestAPI(c *C) { + _, currFile, _, _ := runtime.Caller(0) + srcMetaPath := filepath.Join(filepath.Dir(currFile), "v106_data_for_test") + srcDBPath := filepath.Join(srcMetaPath, "kv") + + oldMetaPath := metaPath + oldDBPath := dbPath + defer func() { + metaPath = oldMetaPath + dbPath = oldDBPath + }() + + metaPath = c.MkDir() + dbPath = filepath.Join(metaPath, "kv") + + // copy test data to a temp directory. + copyDir(c, dbPath, srcDBPath) + + // get subtasks meta. + meta, err := GetSubtasksMeta() + c.Assert(err, IsNil) + + // verify tasks meta. + // - task_single: + // - no shard task, Running stage. + // - task_shard + // - shard task, Paused stage. + c.Assert(meta, HasLen, 2) + c.Assert(meta, HasKey, "task_single") + c.Assert(meta, HasKey, "task_shard") + c.Assert(meta["task_single"].Stage, Equals, pb.Stage_Running) + c.Assert(meta["task_shard"].Stage, Equals, pb.Stage_Paused) + + taskSingleCfg, err := SubTaskConfigFromV1TOML(meta["task_single"].Task) + c.Assert(err, IsNil) + c.Assert(taskSingleCfg.IsSharding, IsFalse) + c.Assert(taskSingleCfg.MydumperConfig.ChunkFilesize, Equals, "64") + + taskShardCfg, err := SubTaskConfigFromV1TOML(meta["task_shard"].Task) + c.Assert(err, IsNil) + c.Assert(taskShardCfg.IsSharding, IsTrue) + c.Assert(taskSingleCfg.MydumperConfig.ChunkFilesize, Equals, "64") + + // try to get meta again, the same as before. + meta2, err := GetSubtasksMeta() + c.Assert(err, IsNil) + c.Assert(meta2, DeepEquals, meta) + + // remove all metadata. + c.Assert(RemoveSubtasksMeta(), IsNil) + + // verify removed. + c.Assert(utils.IsDirExists(metaPath), IsFalse) + + // try to get meta again, nothing exists. + meta3, err := GetSubtasksMeta() + c.Assert(err, IsNil) + c.Assert(meta3, IsNil) + + // remove empty path is invalid. + c.Assert(terror.ErrInvalidV1WorkerMetaPath.Equal(RemoveSubtasksMeta()), IsTrue) + + // remove an invalid meta path. + metaPath = c.MkDir() + dbPath = filepath.Join(metaPath, "kv") + c.Assert(os.Mkdir(dbPath, 0644), IsNil) + c.Assert(terror.ErrInvalidV1WorkerMetaPath.Equal(RemoveSubtasksMeta()), IsTrue) +} + +func copyDir(c *C, dst, src string) { + si, err := os.Stat(src) + c.Assert(err, IsNil) + if !si.IsDir() { + c.Fatalf("source %s is not a directory", src) + } + + _, err = os.Stat(dst) + if err != nil && !os.IsNotExist(err) { + c.Fatalf("fail to get stat for source %s", src) + } + if err == nil { + c.Fatalf("destination %s already exists", dst) + } + + err = os.MkdirAll(dst, si.Mode()) + c.Assert(err, IsNil) + + entries, err := ioutil.ReadDir(src) + c.Assert(err, IsNil) + + for _, entry := range entries { + srcPath := filepath.Join(src, entry.Name()) + dstPath := filepath.Join(dst, entry.Name()) + + if entry.IsDir() { + copyDir(c, dstPath, srcPath) + } else { + // Skip symlinks. + if entry.Mode()&os.ModeSymlink != 0 { + continue + } + copyFile(c, dstPath, srcPath) + } + } +} + +func copyFile(c *C, dst, src string) { + in, err := os.Open(src) + c.Assert(err, IsNil) + defer in.Close() + + out, err := os.Create(dst) + c.Assert(err, IsNil) + defer out.Close() + + _, err = io.Copy(out, in) + c.Assert(err, IsNil) + + si, err := os.Stat(src) + c.Assert(err, IsNil) + err = os.Chmod(dst, si.Mode()) + c.Assert(err, IsNil) +} diff --git a/pkg/v1workermeta/db.go b/pkg/v1workermeta/db.go new file mode 100644 index 0000000000..c3d64c2f69 --- /dev/null +++ b/pkg/v1workermeta/db.go @@ -0,0 +1,67 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1workermeta + +import ( + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/opt" + + "github.com/pingcap/dm/pkg/terror" +) + +// kvConfig is the configuration of goleveldb +type kvConfig struct { + BlockCacheCapacity int `toml:"block-cache-capacity" json:"block-cache-capacity"` + BlockRestartInterval int `toml:"block-restart-interval" json:"block-restart-interval"` + BlockSize int `toml:"block-size" json:"block-size"` + CompactionL0Trigger int `toml:"compaction-L0-trigger" json:"compaction-L0-trigger"` + CompactionTableSize int `toml:"compaction-table-size" json:"compaction-table-size"` + CompactionTotalSize int `toml:"compaction-total-size" json:"compaction-total-size"` + CompactionTotalSizeMultiplier float64 `toml:"compaction-total-size-multiplier" json:"compaction-total-size-multiplier"` + WriteBuffer int `toml:"write-buffer" json:"write-buffer"` + WriteL0PauseTrigger int `toml:"write-L0-pause-trigger" json:"write-L0-pause-trigger"` + WriteL0SlowdownTrigger int `toml:"write-L0-slowdown-trigger" json:"write-L0-slowdown-trigger"` +} + +// default leveldb config +var defaultKVConfig = &kvConfig{ + BlockCacheCapacity: 8388608, + BlockRestartInterval: 16, + BlockSize: 4096, + CompactionL0Trigger: 8, + CompactionTableSize: 67108864, + CompactionTotalSize: 536870912, + CompactionTotalSizeMultiplier: 8, + WriteBuffer: 67108864, + WriteL0PauseTrigger: 24, + WriteL0SlowdownTrigger: 17, +} + +// openDB opens a levelDB. +func openDB(kvDir string, config *kvConfig) (*leveldb.DB, error) { + var opts opt.Options + opts.BlockCacheCapacity = config.BlockCacheCapacity + opts.BlockRestartInterval = config.BlockRestartInterval + opts.BlockSize = config.BlockSize + opts.CompactionL0Trigger = config.CompactionL0Trigger + opts.CompactionTableSize = config.CompactionTableSize + opts.CompactionTotalSize = config.CompactionTotalSize + opts.CompactionTotalSizeMultiplier = config.CompactionTotalSizeMultiplier + opts.WriteBuffer = config.WriteBuffer + opts.WriteL0PauseTrigger = config.WriteL0PauseTrigger + opts.WriteL0SlowdownTrigger = config.WriteL0SlowdownTrigger + + db, err := leveldb.OpenFile(kvDir, &opts) + return db, terror.ErrWorkerOpenKVDBFile.Delegate(err) +} diff --git a/pkg/v1workermeta/meta.go b/pkg/v1workermeta/meta.go new file mode 100644 index 0000000000..dfc6f9be70 --- /dev/null +++ b/pkg/v1workermeta/meta.go @@ -0,0 +1,157 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1workermeta + +import ( + "github.com/golang/protobuf/proto" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/util" + + "github.com/pingcap/dm/dm/pb" + "github.com/pingcap/dm/pkg/terror" +) + +// meta stores metadata of tasks. +type meta struct { + tasks map[string]*pb.V1SubTaskMeta +} + +// newMeta returns a meta object. +func newMeta(db *leveldb.DB) (*meta, error) { + tasks, err := loadTaskMetas(db) + if err != nil { + return nil, err + } + + return &meta{ + tasks: tasks, + }, nil +} + +// TasksMeta returns meta of all tasks. +func (meta *meta) TasksMeta() map[string]*pb.V1SubTaskMeta { + tasks := make(map[string]*pb.V1SubTaskMeta, len(meta.tasks)) + for name, task := range meta.tasks { + tasks[name] = proto.Clone(task).(*pb.V1SubTaskMeta) + } + return tasks +} + +// taskMetaPrefix is prefix of task meta key. +var taskMetaPrefix = []byte("!DM!TaskMeta") + +// encodeTaskMetaKey encodes take name into a task meta key. +func encodeTaskMetaKey(name string) []byte { + key := append([]byte{}, taskMetaPrefix...) + return append(key, name...) +} + +// loadTaskMetas loads all task metas from kv db. +func loadTaskMetas(db *leveldb.DB) (map[string]*pb.V1SubTaskMeta, error) { + if db == nil { + return nil, terror.ErrWorkerLogInvalidHandler.Generate() + } + + var ( + tasks = make(map[string]*pb.V1SubTaskMeta) + err error + ) + + iter := db.NewIterator(util.BytesPrefix(taskMetaPrefix), nil) + for iter.Next() { + taskBytes := iter.Value() + task := &pb.V1SubTaskMeta{} + err = task.Unmarshal(taskBytes) + if err != nil { + iter.Release() + return nil, terror.ErrWorkerLogUnmarshalTaskMeta.Delegate(err, taskBytes) + } + + tasks[task.Name] = task + } + iter.Release() + + err = iter.Error() + if err != nil { + return nil, terror.ErrWorkerLogFetchTaskFromMeta.Delegate(err, taskMetaPrefix) + } + + return tasks, nil +} + +// setTaskMeta saves task meta into kv db. +// it's used for testing. +func setTaskMeta(db *leveldb.DB, task *pb.V1SubTaskMeta) error { + if db == nil { + return terror.ErrWorkerLogInvalidHandler.Generate() + } + + err := verifyTaskMeta(task) + if err != nil { + return terror.Annotatef(err, "verify task meta %+v", task) + } + + taskBytes, err := task.Marshal() + if err != nil { + return terror.ErrWorkerLogMarshalTask.Delegate(err, task) + } + + err = db.Put(encodeTaskMetaKey(task.Name), taskBytes, nil) + if err != nil { + return terror.ErrWorkerLogSaveTaskMeta.Delegate(err, task.Name) + } + + return nil +} + +// deleteTaskMeta deletes task meta from kv DB. +// it's used for testing. +func deleteTaskMeta(db *leveldb.DB, name string) error { + if db == nil { + return terror.ErrWorkerLogInvalidHandler.Generate() + } + + err := db.Delete(encodeTaskMetaKey(name), nil) + if err != nil { + return terror.ErrWorkerLogDeleteTaskMeta.Delegate(err, name) + } + + return nil +} + +// verifyTaskMeta verifies legality of take meta. +// it's used for testing. +func verifyTaskMeta(task *pb.V1SubTaskMeta) error { + if task == nil { + return terror.ErrWorkerLogVerifyTaskMeta.New("empty task not valid") + } + + if len(task.Name) == 0 { + return terror.ErrWorkerLogVerifyTaskMeta.New("empty task name not valid") + } + + if len(task.Task) == 0 { + return terror.ErrWorkerLogVerifyTaskMeta.New("empty task config not valid") + } + + if task.Stage == pb.Stage_InvalidStage { + return terror.ErrWorkerLogVerifyTaskMeta.Generatef("stage %s not valid", task.Stage) + } + + if task.Op == pb.TaskOp_InvalidOp { + return terror.ErrWorkerLogVerifyTaskMeta.Generatef("task operation %s not valid", task.Op) + } + + return nil +} diff --git a/pkg/v1workermeta/meta_test.go b/pkg/v1workermeta/meta_test.go new file mode 100644 index 0000000000..05425a9c06 --- /dev/null +++ b/pkg/v1workermeta/meta_test.go @@ -0,0 +1,136 @@ +// Copyright 2020 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1workermeta + +import ( + "path" + "testing" + + . "github.com/pingcap/check" + "github.com/syndtr/goleveldb/leveldb" + + "github.com/pingcap/dm/dm/config" + "github.com/pingcap/dm/dm/pb" + "github.com/pingcap/dm/pkg/terror" +) + +func TestSuite(t *testing.T) { + TestingT(t) +} + +type testMeta struct{} + +var _ = Suite(&testMeta{}) + +var ( + testTask1 = &config.SubTaskConfig{ + Name: "task1", + SourceID: "replica-1", + } + testTask1Meta *pb.V1SubTaskMeta + + testTask2 = &config.SubTaskConfig{ + Name: "task2", + SourceID: "replica-1", + } + testTask2Meta *pb.V1SubTaskMeta +) + +func testSetUpDB(c *C) *leveldb.DB { + c.Assert(testTask1.Adjust(true), IsNil) + c.Assert(testTask2.Adjust(true), IsNil) + + testTask1Str, err := testTask1.Toml() + c.Assert(err, IsNil) + testTask1Meta = &pb.V1SubTaskMeta{ + Op: pb.TaskOp_Start, + Name: testTask1.Name, + Stage: pb.Stage_New, + Task: []byte(testTask1Str), + } + + testTask2Str, err := testTask2.Toml() + c.Assert(err, IsNil) + testTask2Meta = &pb.V1SubTaskMeta{ + Op: pb.TaskOp_Start, + Name: testTask2.Name, + Stage: pb.Stage_New, + Task: []byte(testTask2Str), + } + + dir := c.MkDir() + dbDir := path.Join(dir, "kv") + db, err := openDB(dbDir, defaultKVConfig) + if err != nil { + c.Fatalf("fail to open leveldb %v", err) + } + + return db +} + +func (t *testMeta) TestNewMetaDB(c *C) { + db := testSetUpDB(c) + defer db.Close() + + metaDB, err := newMeta(db) + c.Assert(err, IsNil) + c.Assert(metaDB.tasks, HasLen, 0) + + // check nil db + metaDB, err = newMeta(nil) + c.Assert(terror.ErrWorkerLogInvalidHandler.Equal(err), IsTrue) + c.Assert(metaDB, IsNil) +} + +func (t *testMeta) TestTask(c *C) { + db := testSetUpDB(c) + defer db.Close() + + // set task meta + c.Assert(terror.ErrWorkerLogInvalidHandler.Equal(setTaskMeta(nil, nil)), IsTrue) + err := setTaskMeta(db, nil) + c.Assert(err, ErrorMatches, ".*empty task.*") + + err = setTaskMeta(db, &pb.V1SubTaskMeta{}) + c.Assert(err, ErrorMatches, ".*empty task.*") + + c.Assert(setTaskMeta(db, testTask1Meta), IsNil) + c.Assert(setTaskMeta(db, testTask2Meta), IsNil) + + // load task meta + metaDB, err := newMeta(db) + c.Assert(err, IsNil) + c.Assert(metaDB.tasks, DeepEquals, map[string]*pb.V1SubTaskMeta{ + "task1": testTask1Meta, + "task2": testTask2Meta, + }) + + // delete task meta + c.Assert(deleteTaskMeta(db, "task1"), IsNil) + + // load task meta + metaDB, err = newMeta(db) + c.Assert(err, IsNil) + c.Assert(metaDB.tasks, DeepEquals, map[string]*pb.V1SubTaskMeta{ + "task2": testTask2Meta, + }) + + // delete task meta + c.Assert(deleteTaskMeta(db, "task2"), IsNil) + + // load task meta + metaDB, err = newMeta(db) + c.Assert(err, IsNil) + c.Assert(metaDB.tasks, HasLen, 0) +} diff --git a/pkg/v1workermeta/v106_data_for_test/kv/000002.ldb b/pkg/v1workermeta/v106_data_for_test/kv/000002.ldb new file mode 100644 index 0000000000000000000000000000000000000000..76ada0df9a216be164cd8811b2fac1a34224e723 GIT binary patch literal 171 zcmWHHVUW^Mbn(?K&o9bOEmAB?Eh^5;&tqg{U}a3HR?5sPNiE7t%+bxuSF$qHQ7TH! zNlh$H)#cUnP_j}gGt@KCGgGQ%00Kr3UQ!#mnL`H7Wiy#SK}>{!lSzs3KPRIKgD+er YX)^1CAg)AFkN_bN{=1=DrPTd40Q{XF_W%F@ literal 0 HcmV?d00001 diff --git a/pkg/v1workermeta/v106_data_for_test/kv/000006.ldb b/pkg/v1workermeta/v106_data_for_test/kv/000006.ldb new file mode 100644 index 0000000000000000000000000000000000000000..16251dddc139c0d5197d7d9a01c8c3747a00d85a GIT binary patch literal 992 zcmZ`%&ub(_6z*cvX1biZYK6LS%_$LYJTi&lq{G<(L?sIQBeqStm&$rX{NfX zQ&m05%wcsE1eKL6>P-l^huw>N^yJZhKt&P!7ZgO$i-^7`?9D3b@ZR^TzIxyHzW27B zix0f!^VgfNFf-m&L&rlEgwA>1uX`1=bm~>+9)HvV)Hi89lp?(CrG}Uh(;VX9YLGB# z1Xj6Bb3r(l#Ka?!2|&US$IJ*~L~c@>PR?>(RLNQ9Hlx>_D$W#l>-U+IAvUViu^=fw zyO&MPp(I)qGL0FbEr5ld2u<84w!7_TF1I^dEs7J#CQ8@aeuy(+nRntav|Qm?A1wtT z)*@3ALC`||lQ(&4*gy(05=`5HU=~QME(NYH?vk?L%mQ<6frCkaT8%Xy$d$J3HK$6k z$gjQX(Es|hX(nbWcYk|2#Dg@KYDny~a2IP*#Z01mzGPFvQ}??{w5ic!MIS2QGpYm% zT}ol#{rv-+q!Q?&C1)jLMFB#(=e>2BO?jCW&}YHys9E!)O`zCZys#Q#JJN!2w71p8 z@uuZzt%Er^|w(#EYuAdanOgy|vbt%3)IQj#pRE3F=`f91|rcpn;O zQST2_0omLkx)U*`g*5Bdk~aHxGz<;Qr2Db znK7V(c*AeCJKf7YwA_p+%%(aL91Mxa0$roMD=oUU1&ZT+t8OZ%+NG4vl=D&QY!4(9 zk)u%xR?E~_bX4Pt@WD<}-4FTT&h6a;yz=!IpMC!2kEb6mJFw8%*=zhxDyt8}N4lpc t7ktM%7oxvCwBg*Ee+b=t_njZ!o5!Ed|9kl?{r~H=Ki~dvy?pVfe*ge57jOUo literal 0 HcmV?d00001 diff --git a/pkg/v1workermeta/v106_data_for_test/kv/000007.ldb b/pkg/v1workermeta/v106_data_for_test/kv/000007.ldb new file mode 100644 index 0000000000000000000000000000000000000000..04c8cbf4fb854789a6ce543d8eab48666ec87243 GIT binary patch literal 1093 zcmbVKO=u)V6z?YZsCJPa*PS4NIM#+L%6g_Of{Sk!_$C|F1nP#fH zI#tz4W)A*=2bGnqdK8v*54#sV>|sIhBJ3e2LA?li_M(D#@Synfa@nH?tBQhG->drS zec!t`zhRxa>o%U*YFwpyd{GW97dZ$OT=&<@4w}2^I)&0hCm%5Y_H>*M1^2JHu_k&% z6@%D2?+vKX9LrS1DJP5xqN5Q{I3T`{BdR&kJk_y@_qbOMoRlVZBY4>=;zTmLdWQ<( zV=Z$PaT2rRTggQ43Zi%>;)s&42{2cCToL>9MyK`U*;aeK8RCJUds02qp;#;Ba*YWX6`Ge!+?rv_N40I0dN zTmgEiOl#RHhM1=pUbG4W+Gy5Iobahk?cbj8aX(Il91=6h>~cxShzfMOBIty$*#6cD z))aa)>p=$mM&`hva=|q`zrBM8u>iJU&Z;Lg%Rona-dzck3CoiV3eBh)HA1|rv^;B_S0Ax`K4_+``tstYmAjfDRlkfC|@smIVZR8ksyxk9xD75FQaW~<#f+eNiT5JGdxea^s;Xw1=tuzRi@{k4NctfYj2br_@ xAUx5zakx;i+=qSikBe5VA7>swSB`!-`O^&kW2Sa|^xxy9Ki_z7C4cVwe*ugBLht|p literal 0 HcmV?d00001 diff --git a/pkg/v1workermeta/v106_data_for_test/kv/000009.ldb b/pkg/v1workermeta/v106_data_for_test/kv/000009.ldb new file mode 100644 index 0000000000000000000000000000000000000000..1818c70a80c670056b75b1db6efd6f6b1ab56f5f GIT binary patch literal 1041 zcmZ`%O>7%Q7~M&|#5>r+PS=S=a2qd|a3Uhp?oiHMtVAwD zM&bzVzM9O`At#b$JPs-Gd_b8zV$yozQYU!kLeSpyJv`*}NXS}XyEtK*S|1w}Ef=HY z04+H#mMjrRjG%JC*(zV(j$%azoRKl3QV$r_)n97WJ(6b;)gYQ`;HMmZ?KjqJ5EfDg zYevb#EWP}aVGP$7>N-x?T%_hd=UqIAQ!YkC&oZ-G;Uc6QePMGtBT;PrRBUZX^w{(O zZn$_DbKoX2=S%^8e;+3_%fLGGbb0CgEXtD%;Ed`qx^K5OfOw<2vg%?zmW)Pdd$WVX zah^^H5HS_cQLoeOU^R&|qUR*npyMiS=ip#hc%wRz(U;wb?iag=JC<35}xl z-@zdT$GK`$J=`Bkk?do~84HDOZo7VPvE{*pzHuCg64lPO+g=woxnkxEB`Jh9*KDd3 zxWM*oKWKL@bkTCNSNWa%JXzxx5vQF2ZGX@{NSpqrDt`#y`YZUZT)=Ei^m~Q=bD(Dzy!+aK9y{cWH z9dM8$$Kx3KkjF}+H!6`J(V+Khq3_nV_x5r9=WoBh`RUyo*Ov_#=)vmm{8%lnKHNUi txpA^$8`dco-M7#=zR$#1*%5tVrbaN8bg+C$JW^RC2WqNl1y`0hGx-Chf=0bb}{P1&d1^9}hU)6S5vS9!{C2_PYi} z4J%4_(75Yi$x^Y$2&$Ca<;sCAefOD#2bl+(&0P#X?V%ozxmW)Pd zWvPq9xX4BXh?q)_&}z5W#cGt~L?4kthn=#^4z#3%$|34agX_5voKym<)5G3owWb zc%kBUiuj@rH5@=ZS{_14KBk2h@V^5x)aTab56F9gV|4CSBc@r1-n5^nDmq|f<9&O) zvg}gm2C`cSJ^QLX)%vo`*&bVMI9`$sgl8Uaokzbyh{XP_)aI?PP`fIHrrK=IL1DQR z145%{_7`wS!F8dUH6L#cq)4~1>&8N%>nmO-INkPPLf^P9M2YGr78m^<916wEXUkFu zZO%AUDR6BsGfvK%tqzI!a_8fMdc z3T_p~2@>^Je=Kcz^_2_Tc=Ee1KD~bR&b2EI7g>!=V33wkbn#UTNi5Fx$xmnCWaMCGZ9JW#N#4bJ>f#EVG4_{$|n57x(_>J{(R z@4esO&KYC!UEF+fy?KGE(V7?-HnIw+WZOflFm@4J$0~(~um)^f4XKR0KkQf$^Zpxg zI&ha7leJEpR-XFiq{Z z4T|bklx(9h*Ta$}VwVwAF1kzQOUqHLXpb{8WK`-Nqq_P-t-40?ETS4jQw{u-!>`+o zX$ORb)WNh-@-a)#K5ZENnPU?=PS~MH%|B0ixEH5f42V9+%xZ;;kaF~i!|4HuV)I+8 zH80VF``hrs!~K{8H<3AK3g|bta6+>TtTT_7$4(wZd6EH~Q9VR=oYp)L&sWE%JgkS3 z(FiRsc5pb%(-8q8rs6}i(&=`v8pRpWha}fwyX3NcEh(XLfVxxQdL{%X<-lrpaqUy{ za3b1dN2 zN>T`IPCHa7aDlBk?O>sEs*CE)mJh8c_E-dggd>K|`rXrQe{m5U$D3NbB8*bU_x(d* zycHYHrWCnm=e{VaEu>#tG3d&T5@emuJYn?Se5nL-nw>9ZwALu`R!Mn(oOz#~P0R>zG+o17UKnOK?GS(w=w*dDM;1D&84l31MW zlb;T;8R&Xu2n(Ow+!bwm92gjxIat`(8Q70$|Vl#+|ksYUl;Bxbhy=?(Gh?|9roq_8Qc5^szJBSk^_3K`X zJjg-Z%)Bhz>