diff --git a/flow/cmd/peer_data.go b/flow/cmd/peer_data.go new file mode 100644 index 0000000000..284dac309c --- /dev/null +++ b/flow/cmd/peer_data.go @@ -0,0 +1,118 @@ +package main + +import ( + "context" + "database/sql" + + "github.com/PeerDB-io/peer-flow/connectors/utils" + "github.com/PeerDB-io/peer-flow/generated/protos" + "github.com/jackc/pgx/v5/pgxpool" + "google.golang.org/protobuf/proto" +) + +func (h *FlowRequestHandler) getPoolForPGPeer(ctx context.Context, peerName string) (*pgxpool.Pool, error) { + var pgPeerOptions sql.RawBytes + var pgPeerConfig protos.PostgresConfig + err := h.pool.QueryRow(ctx, + "SELECT options FROM peers WHERE name = $1 AND type=3", peerName).Scan(&pgPeerOptions) + if err != nil { + return nil, err + } + + unmarshalErr := proto.Unmarshal(pgPeerOptions, &pgPeerConfig) + if err != nil { + return nil, unmarshalErr + } + + connStr := utils.GetPGConnectionString(&pgPeerConfig) + peerPool, err := pgxpool.New(ctx, connStr) + if err != nil { + return nil, unmarshalErr + } + return peerPool, nil +} + +func (h *FlowRequestHandler) GetSlotInfo( + ctx context.Context, + req *protos.PostgresPeerActivityInfoRequest, +) (*protos.PeerSlotResponse, error) { + peerPool, err := h.getPoolForPGPeer(ctx, req.PeerName) + if err != nil { + return &protos.PeerSlotResponse{SlotData: nil}, err + } + defer peerPool.Close() + rows, err := peerPool.Query(ctx, "SELECT slot_name, redo_lsn::Text,restart_lsn::text,active,"+ + "round((redo_lsn-restart_lsn) / 1024 / 1024 , 2) AS MB_Behind"+ + " FROM pg_control_checkpoint(), pg_replication_slots;") + if err != nil { + return &protos.PeerSlotResponse{SlotData: nil}, err + } + defer rows.Close() + var slotInfoRows []*protos.SlotInfo + for rows.Next() { + var redoLSN string + var slotName string + var restartLSN string + var active bool + var lagInMB float32 + err := rows.Scan(&slotName, &redoLSN, &restartLSN, &active, &lagInMB) + if err != nil { + return &protos.PeerSlotResponse{SlotData: nil}, err + } + + slotInfoRows = append(slotInfoRows, &protos.SlotInfo{ + RedoLSN: redoLSN, + RestartLSN: restartLSN, + SlotName: slotName, + Active: active, + LagInMb: lagInMB, + }) + } + return &protos.PeerSlotResponse{ + SlotData: slotInfoRows, + }, nil +} + +func (h *FlowRequestHandler) GetStatInfo( + ctx context.Context, + req *protos.PostgresPeerActivityInfoRequest, +) (*protos.PeerStatResponse, error) { + peerPool, err := h.getPoolForPGPeer(ctx, req.PeerName) + if err != nil { + return &protos.PeerStatResponse{StatData: nil}, err + } + defer peerPool.Close() + rows, err := peerPool.Query(ctx, "SELECT pid, wait_event, wait_event_type, query_start::text, query,"+ + "EXTRACT(epoch FROM(now()-query_start)) AS dur"+ + " FROM pg_stat_activity WHERE usename='peerdb_user' AND state != 'idle' AND query_start IS NOT NULL;") + if err != nil { + return &protos.PeerStatResponse{StatData: nil}, err + } + defer rows.Close() + var statInfoRows []*protos.StatInfo + for rows.Next() { + var pid int64 + var waitEvent string + var waitEventType string + var queryStart string + var query string + var duration float32 + + err := rows.Scan(&pid, &waitEvent, &waitEventType, &queryStart, &query, &duration) + if err != nil { + return &protos.PeerStatResponse{StatData: nil}, err + } + + statInfoRows = append(statInfoRows, &protos.StatInfo{ + Pid: pid, + WaitEvent: waitEvent, + WaitEventType: waitEventType, + QueryStart: queryStart, + Query: query, + Duration: duration, + }) + } + return &protos.PeerStatResponse{ + StatData: statInfoRows, + }, nil +} diff --git a/flow/generated/protos/route.pb.go b/flow/generated/protos/route.pb.go index 1372382d3c..aadcff8680 100644 --- a/flow/generated/protos/route.pb.go +++ b/flow/generated/protos/route.pb.go @@ -906,6 +906,313 @@ func (x *CDCSyncStatus) GetEndTime() *timestamppb.Timestamp { return nil } +type PostgresPeerActivityInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PeerName string `protobuf:"bytes,1,opt,name=peer_name,json=peerName,proto3" json:"peer_name,omitempty"` +} + +func (x *PostgresPeerActivityInfoRequest) Reset() { + *x = PostgresPeerActivityInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_route_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PostgresPeerActivityInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PostgresPeerActivityInfoRequest) ProtoMessage() {} + +func (x *PostgresPeerActivityInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_route_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PostgresPeerActivityInfoRequest.ProtoReflect.Descriptor instead. +func (*PostgresPeerActivityInfoRequest) Descriptor() ([]byte, []int) { + return file_route_proto_rawDescGZIP(), []int{14} +} + +func (x *PostgresPeerActivityInfoRequest) GetPeerName() string { + if x != nil { + return x.PeerName + } + return "" +} + +type SlotInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SlotName string `protobuf:"bytes,1,opt,name=slot_name,json=slotName,proto3" json:"slot_name,omitempty"` + RedoLSN string `protobuf:"bytes,2,opt,name=redo_lSN,json=redoLSN,proto3" json:"redo_lSN,omitempty"` + RestartLSN string `protobuf:"bytes,3,opt,name=restart_lSN,json=restartLSN,proto3" json:"restart_lSN,omitempty"` + Active bool `protobuf:"varint,4,opt,name=active,proto3" json:"active,omitempty"` + LagInMb float32 `protobuf:"fixed32,5,opt,name=lag_in_mb,json=lagInMb,proto3" json:"lag_in_mb,omitempty"` +} + +func (x *SlotInfo) Reset() { + *x = SlotInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_route_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SlotInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SlotInfo) ProtoMessage() {} + +func (x *SlotInfo) ProtoReflect() protoreflect.Message { + mi := &file_route_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SlotInfo.ProtoReflect.Descriptor instead. +func (*SlotInfo) Descriptor() ([]byte, []int) { + return file_route_proto_rawDescGZIP(), []int{15} +} + +func (x *SlotInfo) GetSlotName() string { + if x != nil { + return x.SlotName + } + return "" +} + +func (x *SlotInfo) GetRedoLSN() string { + if x != nil { + return x.RedoLSN + } + return "" +} + +func (x *SlotInfo) GetRestartLSN() string { + if x != nil { + return x.RestartLSN + } + return "" +} + +func (x *SlotInfo) GetActive() bool { + if x != nil { + return x.Active + } + return false +} + +func (x *SlotInfo) GetLagInMb() float32 { + if x != nil { + return x.LagInMb + } + return 0 +} + +type StatInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pid int64 `protobuf:"varint,1,opt,name=pid,proto3" json:"pid,omitempty"` + WaitEvent string `protobuf:"bytes,2,opt,name=wait_event,json=waitEvent,proto3" json:"wait_event,omitempty"` + WaitEventType string `protobuf:"bytes,3,opt,name=wait_event_type,json=waitEventType,proto3" json:"wait_event_type,omitempty"` + QueryStart string `protobuf:"bytes,4,opt,name=query_start,json=queryStart,proto3" json:"query_start,omitempty"` + Query string `protobuf:"bytes,5,opt,name=query,proto3" json:"query,omitempty"` + Duration float32 `protobuf:"fixed32,6,opt,name=duration,proto3" json:"duration,omitempty"` +} + +func (x *StatInfo) Reset() { + *x = StatInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_route_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatInfo) ProtoMessage() {} + +func (x *StatInfo) ProtoReflect() protoreflect.Message { + mi := &file_route_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatInfo.ProtoReflect.Descriptor instead. +func (*StatInfo) Descriptor() ([]byte, []int) { + return file_route_proto_rawDescGZIP(), []int{16} +} + +func (x *StatInfo) GetPid() int64 { + if x != nil { + return x.Pid + } + return 0 +} + +func (x *StatInfo) GetWaitEvent() string { + if x != nil { + return x.WaitEvent + } + return "" +} + +func (x *StatInfo) GetWaitEventType() string { + if x != nil { + return x.WaitEventType + } + return "" +} + +func (x *StatInfo) GetQueryStart() string { + if x != nil { + return x.QueryStart + } + return "" +} + +func (x *StatInfo) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *StatInfo) GetDuration() float32 { + if x != nil { + return x.Duration + } + return 0 +} + +type PeerSlotResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SlotData []*SlotInfo `protobuf:"bytes,1,rep,name=slot_data,json=slotData,proto3" json:"slot_data,omitempty"` +} + +func (x *PeerSlotResponse) Reset() { + *x = PeerSlotResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_route_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeerSlotResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerSlotResponse) ProtoMessage() {} + +func (x *PeerSlotResponse) ProtoReflect() protoreflect.Message { + mi := &file_route_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeerSlotResponse.ProtoReflect.Descriptor instead. +func (*PeerSlotResponse) Descriptor() ([]byte, []int) { + return file_route_proto_rawDescGZIP(), []int{17} +} + +func (x *PeerSlotResponse) GetSlotData() []*SlotInfo { + if x != nil { + return x.SlotData + } + return nil +} + +type PeerStatResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StatData []*StatInfo `protobuf:"bytes,1,rep,name=stat_data,json=statData,proto3" json:"stat_data,omitempty"` +} + +func (x *PeerStatResponse) Reset() { + *x = PeerStatResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_route_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeerStatResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeerStatResponse) ProtoMessage() {} + +func (x *PeerStatResponse) ProtoReflect() protoreflect.Message { + mi := &file_route_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeerStatResponse.ProtoReflect.Descriptor instead. +func (*PeerStatResponse) Descriptor() ([]byte, []int) { + return file_route_proto_rawDescGZIP(), []int{18} +} + +func (x *PeerStatResponse) GetStatData() []*StatInfo { + if x != nil { + return x.StatData + } + return nil +} + type SnapshotStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -917,7 +1224,7 @@ type SnapshotStatus struct { func (x *SnapshotStatus) Reset() { *x = SnapshotStatus{} if protoimpl.UnsafeEnabled { - mi := &file_route_proto_msgTypes[14] + mi := &file_route_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -930,7 +1237,7 @@ func (x *SnapshotStatus) String() string { func (*SnapshotStatus) ProtoMessage() {} func (x *SnapshotStatus) ProtoReflect() protoreflect.Message { - mi := &file_route_proto_msgTypes[14] + mi := &file_route_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -943,7 +1250,7 @@ func (x *SnapshotStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotStatus.ProtoReflect.Descriptor instead. func (*SnapshotStatus) Descriptor() ([]byte, []int) { - return file_route_proto_rawDescGZIP(), []int{14} + return file_route_proto_rawDescGZIP(), []int{19} } func (x *SnapshotStatus) GetClones() []*QRepMirrorStatus { @@ -966,7 +1273,7 @@ type CDCMirrorStatus struct { func (x *CDCMirrorStatus) Reset() { *x = CDCMirrorStatus{} if protoimpl.UnsafeEnabled { - mi := &file_route_proto_msgTypes[15] + mi := &file_route_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -979,7 +1286,7 @@ func (x *CDCMirrorStatus) String() string { func (*CDCMirrorStatus) ProtoMessage() {} func (x *CDCMirrorStatus) ProtoReflect() protoreflect.Message { - mi := &file_route_proto_msgTypes[15] + mi := &file_route_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -992,7 +1299,7 @@ func (x *CDCMirrorStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use CDCMirrorStatus.ProtoReflect.Descriptor instead. func (*CDCMirrorStatus) Descriptor() ([]byte, []int) { - return file_route_proto_rawDescGZIP(), []int{15} + return file_route_proto_rawDescGZIP(), []int{20} } func (x *CDCMirrorStatus) GetConfig() *FlowConnectionConfigs { @@ -1033,7 +1340,7 @@ type MirrorStatusResponse struct { func (x *MirrorStatusResponse) Reset() { *x = MirrorStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_route_proto_msgTypes[16] + mi := &file_route_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1046,7 +1353,7 @@ func (x *MirrorStatusResponse) String() string { func (*MirrorStatusResponse) ProtoMessage() {} func (x *MirrorStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_route_proto_msgTypes[16] + mi := &file_route_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1059,7 +1366,7 @@ func (x *MirrorStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MirrorStatusResponse.ProtoReflect.Descriptor instead. func (*MirrorStatusResponse) Descriptor() ([]byte, []int) { - return file_route_proto_rawDescGZIP(), []int{16} + return file_route_proto_rawDescGZIP(), []int{21} } func (x *MirrorStatusResponse) GetFlowJobName() string { @@ -1224,100 +1531,151 @@ var file_route_proto_rawDesc = []byte{ 0x12, 0x35, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, - 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x48, 0x0a, 0x0e, 0x53, 0x6e, 0x61, 0x70, 0x73, - 0x68, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x36, 0x0a, 0x06, 0x63, 0x6c, 0x6f, - 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x65, 0x72, + 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x3e, 0x0a, 0x1f, 0x50, 0x6f, 0x73, 0x74, 0x67, + 0x72, 0x65, 0x73, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x65, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x08, 0x53, 0x6c, 0x6f, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x6c, 0x6f, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x6f, 0x5f, 0x6c, 0x53, 0x4e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x64, 0x6f, 0x4c, 0x53, 0x4e, 0x12, 0x1f, 0x0a, 0x0b, + 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x53, 0x4e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x53, 0x4e, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1a, 0x0a, 0x09, 0x6c, 0x61, 0x67, 0x5f, 0x69, 0x6e, 0x5f, + 0x6d, 0x62, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x6c, 0x61, 0x67, 0x49, 0x6e, 0x4d, + 0x62, 0x22, 0xb6, 0x01, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, + 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x70, 0x69, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x77, 0x61, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x26, 0x0a, 0x0f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1a, + 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x02, + 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x47, 0x0a, 0x10, 0x50, 0x65, + 0x65, 0x72, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, + 0x0a, 0x09, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x73, 0x6c, 0x6f, 0x74, 0x44, + 0x61, 0x74, 0x61, 0x22, 0x47, 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x65, 0x65, + 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x44, 0x61, 0x74, 0x61, 0x22, 0x48, 0x0a, 0x0e, + 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x36, + 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x51, 0x52, + 0x65, 0x70, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x22, 0xce, 0x01, 0x0a, 0x0f, 0x43, 0x44, 0x43, 0x4d, 0x69, + 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x65, + 0x72, 0x64, 0x62, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x06, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x45, 0x0a, 0x0f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0e, 0x73, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x38, 0x0a, + 0x09, 0x63, 0x64, 0x63, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x43, 0x44, 0x43, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x63, + 0x64, 0x63, 0x53, 0x79, 0x6e, 0x63, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x14, 0x4d, 0x69, 0x72, 0x72, + 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x22, 0x0a, 0x0d, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x6c, 0x6f, 0x77, 0x4a, 0x6f, 0x62, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x71, 0x72, 0x65, 0x70, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x51, 0x52, 0x65, 0x70, 0x4d, 0x69, 0x72, - 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, - 0x73, 0x22, 0xce, 0x01, 0x0a, 0x0f, 0x43, 0x44, 0x43, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x66, - 0x6c, 0x6f, 0x77, 0x2e, 0x46, 0x6c, 0x6f, 0x77, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x45, 0x0a, 0x0f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x63, 0x64, 0x63, 0x5f, - 0x73, 0x79, 0x6e, 0x63, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x65, - 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x44, 0x43, 0x53, 0x79, - 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x63, 0x64, 0x63, 0x53, 0x79, 0x6e, - 0x63, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x14, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x66, - 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x66, 0x6c, 0x6f, 0x77, 0x4a, 0x6f, 0x62, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x41, 0x0a, 0x0b, 0x71, 0x72, 0x65, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x2e, 0x51, 0x52, 0x65, 0x70, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x71, 0x72, 0x65, 0x70, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x64, 0x63, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, - 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x44, 0x43, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x09, 0x63, 0x64, 0x63, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x2a, 0x42, 0x0a, 0x12, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x52, 0x45, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, - 0x05, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x10, 0x02, 0x2a, 0x43, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, - 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, - 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x32, 0xb8, 0x05, 0x0a, 0x0b, 0x46, - 0x6c, 0x6f, 0x77, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x0c, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, - 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x76, - 0x31, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x6c, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1f, - 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x76, - 0x31, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x79, - 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x44, 0x43, 0x46, 0x6c, 0x6f, 0x77, 0x12, - 0x22, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x44, 0x43, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x44, 0x43, 0x46, 0x6c, 0x6f, 0x77, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, - 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x63, - 0x64, 0x63, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x51, 0x52, 0x65, 0x70, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x23, 0x2e, 0x70, 0x65, - 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x51, 0x52, 0x65, 0x70, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x24, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x71, 0x72, 0x65, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x63, 0x64, 0x63, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x65, + 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x44, 0x43, 0x4d, 0x69, + 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x09, 0x63, 0x64, + 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x08, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0x42, 0x0a, 0x12, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x10, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, + 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x02, 0x2a, 0x43, 0x0a, 0x10, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, + 0x0a, 0x12, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x32, + 0xc0, 0x07, 0x0a, 0x0b, 0x46, 0x6c, 0x6f, 0x77, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x74, 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x12, + 0x21, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, + 0x2a, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, + 0x65, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, + 0x2a, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x12, 0x79, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x44, 0x43, + 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x22, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x44, 0x43, 0x46, 0x6c, 0x6f, + 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, + 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x44, + 0x43, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x6c, + 0x6f, 0x77, 0x73, 0x2f, 0x63, 0x64, 0x63, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x7d, + 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x51, 0x52, 0x65, 0x70, 0x46, 0x6c, 0x6f, 0x77, + 0x12, 0x23, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x51, 0x52, 0x65, 0x70, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, - 0x2a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x2f, 0x71, 0x72, 0x65, - 0x70, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x53, 0x68, 0x75, 0x74, - 0x64, 0x6f, 0x77, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1d, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, - 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, - 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0c, 0x4d, 0x69, 0x72, - 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x65, 0x65, 0x72, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x51, 0x52, 0x65, 0x70, 0x46, + 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x66, 0x6c, 0x6f, 0x77, + 0x73, 0x2f, 0x71, 0x72, 0x65, 0x70, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x81, 0x01, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x6c, 0x6f, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x2e, + 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x50, 0x6f, 0x73, + 0x74, 0x67, 0x72, 0x65, 0x73, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, + 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x50, 0x65, 0x65, 0x72, + 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x2f, + 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x7d, 0x12, 0x81, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x2d, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x50, 0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, + 0x65, 0x72, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x65, 0x65, 0x72, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x4f, 0x0a, 0x0c, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1d, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0c, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, - 0x65, 0x65, 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x4d, 0x69, 0x72, 0x72, - 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x69, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x42, 0x7c, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x65, 0x65, - 0x72, 0x64, 0x62, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x42, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, - 0x02, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x64, 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, 0xca, 0x02, 0x0b, - 0x50, 0x65, 0x65, 0x72, 0x64, 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, 0xe2, 0x02, 0x17, 0x50, 0x65, - 0x65, 0x72, 0x64, 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x64, 0x62, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x69, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x2f, 0x7b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x7d, 0x42, 0x7c, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x65, 0x65, 0x72, 0x64, 0x62, + 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x42, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x10, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x0b, 0x50, + 0x65, 0x65, 0x72, 0x64, 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, 0xca, 0x02, 0x0b, 0x50, 0x65, 0x65, + 0x72, 0x64, 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, 0xe2, 0x02, 0x17, 0x50, 0x65, 0x65, 0x72, 0x64, + 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x64, 0x62, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1333,70 +1691,81 @@ func file_route_proto_rawDescGZIP() []byte { } var file_route_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_route_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_route_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_route_proto_goTypes = []interface{}{ - (ValidatePeerStatus)(0), // 0: peerdb_route.ValidatePeerStatus - (CreatePeerStatus)(0), // 1: peerdb_route.CreatePeerStatus - (*CreateCDCFlowRequest)(nil), // 2: peerdb_route.CreateCDCFlowRequest - (*CreateCDCFlowResponse)(nil), // 3: peerdb_route.CreateCDCFlowResponse - (*CreateQRepFlowRequest)(nil), // 4: peerdb_route.CreateQRepFlowRequest - (*CreateQRepFlowResponse)(nil), // 5: peerdb_route.CreateQRepFlowResponse - (*ShutdownRequest)(nil), // 6: peerdb_route.ShutdownRequest - (*ShutdownResponse)(nil), // 7: peerdb_route.ShutdownResponse - (*ValidatePeerRequest)(nil), // 8: peerdb_route.ValidatePeerRequest - (*CreatePeerRequest)(nil), // 9: peerdb_route.CreatePeerRequest - (*ValidatePeerResponse)(nil), // 10: peerdb_route.ValidatePeerResponse - (*CreatePeerResponse)(nil), // 11: peerdb_route.CreatePeerResponse - (*MirrorStatusRequest)(nil), // 12: peerdb_route.MirrorStatusRequest - (*PartitionStatus)(nil), // 13: peerdb_route.PartitionStatus - (*QRepMirrorStatus)(nil), // 14: peerdb_route.QRepMirrorStatus - (*CDCSyncStatus)(nil), // 15: peerdb_route.CDCSyncStatus - (*SnapshotStatus)(nil), // 16: peerdb_route.SnapshotStatus - (*CDCMirrorStatus)(nil), // 17: peerdb_route.CDCMirrorStatus - (*MirrorStatusResponse)(nil), // 18: peerdb_route.MirrorStatusResponse - (*FlowConnectionConfigs)(nil), // 19: peerdb_flow.FlowConnectionConfigs - (*QRepConfig)(nil), // 20: peerdb_flow.QRepConfig - (*Peer)(nil), // 21: peerdb_peers.Peer - (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp + (ValidatePeerStatus)(0), // 0: peerdb_route.ValidatePeerStatus + (CreatePeerStatus)(0), // 1: peerdb_route.CreatePeerStatus + (*CreateCDCFlowRequest)(nil), // 2: peerdb_route.CreateCDCFlowRequest + (*CreateCDCFlowResponse)(nil), // 3: peerdb_route.CreateCDCFlowResponse + (*CreateQRepFlowRequest)(nil), // 4: peerdb_route.CreateQRepFlowRequest + (*CreateQRepFlowResponse)(nil), // 5: peerdb_route.CreateQRepFlowResponse + (*ShutdownRequest)(nil), // 6: peerdb_route.ShutdownRequest + (*ShutdownResponse)(nil), // 7: peerdb_route.ShutdownResponse + (*ValidatePeerRequest)(nil), // 8: peerdb_route.ValidatePeerRequest + (*CreatePeerRequest)(nil), // 9: peerdb_route.CreatePeerRequest + (*ValidatePeerResponse)(nil), // 10: peerdb_route.ValidatePeerResponse + (*CreatePeerResponse)(nil), // 11: peerdb_route.CreatePeerResponse + (*MirrorStatusRequest)(nil), // 12: peerdb_route.MirrorStatusRequest + (*PartitionStatus)(nil), // 13: peerdb_route.PartitionStatus + (*QRepMirrorStatus)(nil), // 14: peerdb_route.QRepMirrorStatus + (*CDCSyncStatus)(nil), // 15: peerdb_route.CDCSyncStatus + (*PostgresPeerActivityInfoRequest)(nil), // 16: peerdb_route.PostgresPeerActivityInfoRequest + (*SlotInfo)(nil), // 17: peerdb_route.SlotInfo + (*StatInfo)(nil), // 18: peerdb_route.StatInfo + (*PeerSlotResponse)(nil), // 19: peerdb_route.PeerSlotResponse + (*PeerStatResponse)(nil), // 20: peerdb_route.PeerStatResponse + (*SnapshotStatus)(nil), // 21: peerdb_route.SnapshotStatus + (*CDCMirrorStatus)(nil), // 22: peerdb_route.CDCMirrorStatus + (*MirrorStatusResponse)(nil), // 23: peerdb_route.MirrorStatusResponse + (*FlowConnectionConfigs)(nil), // 24: peerdb_flow.FlowConnectionConfigs + (*QRepConfig)(nil), // 25: peerdb_flow.QRepConfig + (*Peer)(nil), // 26: peerdb_peers.Peer + (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp } var file_route_proto_depIdxs = []int32{ - 19, // 0: peerdb_route.CreateCDCFlowRequest.connection_configs:type_name -> peerdb_flow.FlowConnectionConfigs - 20, // 1: peerdb_route.CreateQRepFlowRequest.qrep_config:type_name -> peerdb_flow.QRepConfig - 21, // 2: peerdb_route.ShutdownRequest.source_peer:type_name -> peerdb_peers.Peer - 21, // 3: peerdb_route.ShutdownRequest.destination_peer:type_name -> peerdb_peers.Peer - 21, // 4: peerdb_route.ValidatePeerRequest.peer:type_name -> peerdb_peers.Peer - 21, // 5: peerdb_route.CreatePeerRequest.peer:type_name -> peerdb_peers.Peer + 24, // 0: peerdb_route.CreateCDCFlowRequest.connection_configs:type_name -> peerdb_flow.FlowConnectionConfigs + 25, // 1: peerdb_route.CreateQRepFlowRequest.qrep_config:type_name -> peerdb_flow.QRepConfig + 26, // 2: peerdb_route.ShutdownRequest.source_peer:type_name -> peerdb_peers.Peer + 26, // 3: peerdb_route.ShutdownRequest.destination_peer:type_name -> peerdb_peers.Peer + 26, // 4: peerdb_route.ValidatePeerRequest.peer:type_name -> peerdb_peers.Peer + 26, // 5: peerdb_route.CreatePeerRequest.peer:type_name -> peerdb_peers.Peer 0, // 6: peerdb_route.ValidatePeerResponse.status:type_name -> peerdb_route.ValidatePeerStatus 1, // 7: peerdb_route.CreatePeerResponse.status:type_name -> peerdb_route.CreatePeerStatus - 22, // 8: peerdb_route.PartitionStatus.start_time:type_name -> google.protobuf.Timestamp - 22, // 9: peerdb_route.PartitionStatus.end_time:type_name -> google.protobuf.Timestamp - 20, // 10: peerdb_route.QRepMirrorStatus.config:type_name -> peerdb_flow.QRepConfig + 27, // 8: peerdb_route.PartitionStatus.start_time:type_name -> google.protobuf.Timestamp + 27, // 9: peerdb_route.PartitionStatus.end_time:type_name -> google.protobuf.Timestamp + 25, // 10: peerdb_route.QRepMirrorStatus.config:type_name -> peerdb_flow.QRepConfig 13, // 11: peerdb_route.QRepMirrorStatus.partitions:type_name -> peerdb_route.PartitionStatus - 22, // 12: peerdb_route.CDCSyncStatus.start_time:type_name -> google.protobuf.Timestamp - 22, // 13: peerdb_route.CDCSyncStatus.end_time:type_name -> google.protobuf.Timestamp - 14, // 14: peerdb_route.SnapshotStatus.clones:type_name -> peerdb_route.QRepMirrorStatus - 19, // 15: peerdb_route.CDCMirrorStatus.config:type_name -> peerdb_flow.FlowConnectionConfigs - 16, // 16: peerdb_route.CDCMirrorStatus.snapshot_status:type_name -> peerdb_route.SnapshotStatus - 15, // 17: peerdb_route.CDCMirrorStatus.cdc_syncs:type_name -> peerdb_route.CDCSyncStatus - 14, // 18: peerdb_route.MirrorStatusResponse.qrep_status:type_name -> peerdb_route.QRepMirrorStatus - 17, // 19: peerdb_route.MirrorStatusResponse.cdc_status:type_name -> peerdb_route.CDCMirrorStatus - 8, // 20: peerdb_route.FlowService.ValidatePeer:input_type -> peerdb_route.ValidatePeerRequest - 9, // 21: peerdb_route.FlowService.CreatePeer:input_type -> peerdb_route.CreatePeerRequest - 2, // 22: peerdb_route.FlowService.CreateCDCFlow:input_type -> peerdb_route.CreateCDCFlowRequest - 4, // 23: peerdb_route.FlowService.CreateQRepFlow:input_type -> peerdb_route.CreateQRepFlowRequest - 6, // 24: peerdb_route.FlowService.ShutdownFlow:input_type -> peerdb_route.ShutdownRequest - 12, // 25: peerdb_route.FlowService.MirrorStatus:input_type -> peerdb_route.MirrorStatusRequest - 10, // 26: peerdb_route.FlowService.ValidatePeer:output_type -> peerdb_route.ValidatePeerResponse - 11, // 27: peerdb_route.FlowService.CreatePeer:output_type -> peerdb_route.CreatePeerResponse - 3, // 28: peerdb_route.FlowService.CreateCDCFlow:output_type -> peerdb_route.CreateCDCFlowResponse - 5, // 29: peerdb_route.FlowService.CreateQRepFlow:output_type -> peerdb_route.CreateQRepFlowResponse - 7, // 30: peerdb_route.FlowService.ShutdownFlow:output_type -> peerdb_route.ShutdownResponse - 18, // 31: peerdb_route.FlowService.MirrorStatus:output_type -> peerdb_route.MirrorStatusResponse - 26, // [26:32] is the sub-list for method output_type - 20, // [20:26] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 27, // 12: peerdb_route.CDCSyncStatus.start_time:type_name -> google.protobuf.Timestamp + 27, // 13: peerdb_route.CDCSyncStatus.end_time:type_name -> google.protobuf.Timestamp + 17, // 14: peerdb_route.PeerSlotResponse.slot_data:type_name -> peerdb_route.SlotInfo + 18, // 15: peerdb_route.PeerStatResponse.stat_data:type_name -> peerdb_route.StatInfo + 14, // 16: peerdb_route.SnapshotStatus.clones:type_name -> peerdb_route.QRepMirrorStatus + 24, // 17: peerdb_route.CDCMirrorStatus.config:type_name -> peerdb_flow.FlowConnectionConfigs + 21, // 18: peerdb_route.CDCMirrorStatus.snapshot_status:type_name -> peerdb_route.SnapshotStatus + 15, // 19: peerdb_route.CDCMirrorStatus.cdc_syncs:type_name -> peerdb_route.CDCSyncStatus + 14, // 20: peerdb_route.MirrorStatusResponse.qrep_status:type_name -> peerdb_route.QRepMirrorStatus + 22, // 21: peerdb_route.MirrorStatusResponse.cdc_status:type_name -> peerdb_route.CDCMirrorStatus + 8, // 22: peerdb_route.FlowService.ValidatePeer:input_type -> peerdb_route.ValidatePeerRequest + 9, // 23: peerdb_route.FlowService.CreatePeer:input_type -> peerdb_route.CreatePeerRequest + 2, // 24: peerdb_route.FlowService.CreateCDCFlow:input_type -> peerdb_route.CreateCDCFlowRequest + 4, // 25: peerdb_route.FlowService.CreateQRepFlow:input_type -> peerdb_route.CreateQRepFlowRequest + 16, // 26: peerdb_route.FlowService.GetSlotInfo:input_type -> peerdb_route.PostgresPeerActivityInfoRequest + 16, // 27: peerdb_route.FlowService.GetStatInfo:input_type -> peerdb_route.PostgresPeerActivityInfoRequest + 6, // 28: peerdb_route.FlowService.ShutdownFlow:input_type -> peerdb_route.ShutdownRequest + 12, // 29: peerdb_route.FlowService.MirrorStatus:input_type -> peerdb_route.MirrorStatusRequest + 10, // 30: peerdb_route.FlowService.ValidatePeer:output_type -> peerdb_route.ValidatePeerResponse + 11, // 31: peerdb_route.FlowService.CreatePeer:output_type -> peerdb_route.CreatePeerResponse + 3, // 32: peerdb_route.FlowService.CreateCDCFlow:output_type -> peerdb_route.CreateCDCFlowResponse + 5, // 33: peerdb_route.FlowService.CreateQRepFlow:output_type -> peerdb_route.CreateQRepFlowResponse + 19, // 34: peerdb_route.FlowService.GetSlotInfo:output_type -> peerdb_route.PeerSlotResponse + 20, // 35: peerdb_route.FlowService.GetStatInfo:output_type -> peerdb_route.PeerStatResponse + 7, // 36: peerdb_route.FlowService.ShutdownFlow:output_type -> peerdb_route.ShutdownResponse + 23, // 37: peerdb_route.FlowService.MirrorStatus:output_type -> peerdb_route.MirrorStatusResponse + 30, // [30:38] is the sub-list for method output_type + 22, // [22:30] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_route_proto_init() } @@ -1576,7 +1945,7 @@ func file_route_proto_init() { } } file_route_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SnapshotStatus); i { + switch v := v.(*PostgresPeerActivityInfoRequest); i { case 0: return &v.state case 1: @@ -1588,7 +1957,7 @@ func file_route_proto_init() { } } file_route_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CDCMirrorStatus); i { + switch v := v.(*SlotInfo); i { case 0: return &v.state case 1: @@ -1600,6 +1969,66 @@ func file_route_proto_init() { } } file_route_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_route_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeerSlotResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_route_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeerStatResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_route_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SnapshotStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_route_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CDCMirrorStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_route_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MirrorStatusResponse); i { case 0: return &v.state @@ -1612,7 +2041,7 @@ func file_route_proto_init() { } } } - file_route_proto_msgTypes[16].OneofWrappers = []interface{}{ + file_route_proto_msgTypes[21].OneofWrappers = []interface{}{ (*MirrorStatusResponse_QrepStatus)(nil), (*MirrorStatusResponse_CdcStatus)(nil), } @@ -1622,7 +2051,7 @@ func file_route_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_route_proto_rawDesc, NumEnums: 2, - NumMessages: 17, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, diff --git a/flow/generated/protos/route.pb.gw.go b/flow/generated/protos/route.pb.gw.go index 173576be92..15bf685de7 100644 --- a/flow/generated/protos/route.pb.gw.go +++ b/flow/generated/protos/route.pb.gw.go @@ -167,6 +167,110 @@ func local_request_FlowService_CreateQRepFlow_0(ctx context.Context, marshaler r } +func request_FlowService_GetSlotInfo_0(ctx context.Context, marshaler runtime.Marshaler, client FlowServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PostgresPeerActivityInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["peer_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "peer_name") + } + + protoReq.PeerName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "peer_name", err) + } + + msg, err := client.GetSlotInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_FlowService_GetSlotInfo_0(ctx context.Context, marshaler runtime.Marshaler, server FlowServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PostgresPeerActivityInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["peer_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "peer_name") + } + + protoReq.PeerName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "peer_name", err) + } + + msg, err := server.GetSlotInfo(ctx, &protoReq) + return msg, metadata, err + +} + +func request_FlowService_GetStatInfo_0(ctx context.Context, marshaler runtime.Marshaler, client FlowServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PostgresPeerActivityInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["peer_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "peer_name") + } + + protoReq.PeerName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "peer_name", err) + } + + msg, err := client.GetStatInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_FlowService_GetStatInfo_0(ctx context.Context, marshaler runtime.Marshaler, server FlowServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq PostgresPeerActivityInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["peer_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "peer_name") + } + + protoReq.PeerName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "peer_name", err) + } + + msg, err := server.GetStatInfo(ctx, &protoReq) + return msg, metadata, err + +} + func request_FlowService_MirrorStatus_0(ctx context.Context, marshaler runtime.Marshaler, client FlowServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq MirrorStatusRequest var metadata runtime.ServerMetadata @@ -325,6 +429,56 @@ func RegisterFlowServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("GET", pattern_FlowService_GetSlotInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/peerdb_route.FlowService/GetSlotInfo", runtime.WithHTTPPathPattern("/v1/peers/slots/{peer_name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_FlowService_GetSlotInfo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_FlowService_GetSlotInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_FlowService_GetStatInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/peerdb_route.FlowService/GetStatInfo", runtime.WithHTTPPathPattern("/v1/peers/stats/{peer_name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_FlowService_GetStatInfo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_FlowService_GetStatInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_FlowService_MirrorStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -479,6 +633,50 @@ func RegisterFlowServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("GET", pattern_FlowService_GetSlotInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/peerdb_route.FlowService/GetSlotInfo", runtime.WithHTTPPathPattern("/v1/peers/slots/{peer_name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_FlowService_GetSlotInfo_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_FlowService_GetSlotInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_FlowService_GetStatInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/peerdb_route.FlowService/GetStatInfo", runtime.WithHTTPPathPattern("/v1/peers/stats/{peer_name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_FlowService_GetStatInfo_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_FlowService_GetStatInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_FlowService_MirrorStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -513,6 +711,10 @@ var ( pattern_FlowService_CreateQRepFlow_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "flows", "qrep", "create"}, "")) + pattern_FlowService_GetSlotInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "peers", "slots", "peer_name"}, "")) + + pattern_FlowService_GetStatInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "peers", "stats", "peer_name"}, "")) + pattern_FlowService_MirrorStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "mirrors", "flow_job_name"}, "")) ) @@ -525,5 +727,9 @@ var ( forward_FlowService_CreateQRepFlow_0 = runtime.ForwardResponseMessage + forward_FlowService_GetSlotInfo_0 = runtime.ForwardResponseMessage + + forward_FlowService_GetStatInfo_0 = runtime.ForwardResponseMessage + forward_FlowService_MirrorStatus_0 = runtime.ForwardResponseMessage ) diff --git a/flow/generated/protos/route_grpc.pb.go b/flow/generated/protos/route_grpc.pb.go index bee5b224b4..70852f0024 100644 --- a/flow/generated/protos/route_grpc.pb.go +++ b/flow/generated/protos/route_grpc.pb.go @@ -23,6 +23,8 @@ const ( FlowService_CreatePeer_FullMethodName = "/peerdb_route.FlowService/CreatePeer" FlowService_CreateCDCFlow_FullMethodName = "/peerdb_route.FlowService/CreateCDCFlow" FlowService_CreateQRepFlow_FullMethodName = "/peerdb_route.FlowService/CreateQRepFlow" + FlowService_GetSlotInfo_FullMethodName = "/peerdb_route.FlowService/GetSlotInfo" + FlowService_GetStatInfo_FullMethodName = "/peerdb_route.FlowService/GetStatInfo" FlowService_ShutdownFlow_FullMethodName = "/peerdb_route.FlowService/ShutdownFlow" FlowService_MirrorStatus_FullMethodName = "/peerdb_route.FlowService/MirrorStatus" ) @@ -35,6 +37,8 @@ type FlowServiceClient interface { CreatePeer(ctx context.Context, in *CreatePeerRequest, opts ...grpc.CallOption) (*CreatePeerResponse, error) CreateCDCFlow(ctx context.Context, in *CreateCDCFlowRequest, opts ...grpc.CallOption) (*CreateCDCFlowResponse, error) CreateQRepFlow(ctx context.Context, in *CreateQRepFlowRequest, opts ...grpc.CallOption) (*CreateQRepFlowResponse, error) + GetSlotInfo(ctx context.Context, in *PostgresPeerActivityInfoRequest, opts ...grpc.CallOption) (*PeerSlotResponse, error) + GetStatInfo(ctx context.Context, in *PostgresPeerActivityInfoRequest, opts ...grpc.CallOption) (*PeerStatResponse, error) ShutdownFlow(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error) MirrorStatus(ctx context.Context, in *MirrorStatusRequest, opts ...grpc.CallOption) (*MirrorStatusResponse, error) } @@ -83,6 +87,24 @@ func (c *flowServiceClient) CreateQRepFlow(ctx context.Context, in *CreateQRepFl return out, nil } +func (c *flowServiceClient) GetSlotInfo(ctx context.Context, in *PostgresPeerActivityInfoRequest, opts ...grpc.CallOption) (*PeerSlotResponse, error) { + out := new(PeerSlotResponse) + err := c.cc.Invoke(ctx, FlowService_GetSlotInfo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *flowServiceClient) GetStatInfo(ctx context.Context, in *PostgresPeerActivityInfoRequest, opts ...grpc.CallOption) (*PeerStatResponse, error) { + out := new(PeerStatResponse) + err := c.cc.Invoke(ctx, FlowService_GetStatInfo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *flowServiceClient) ShutdownFlow(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error) { out := new(ShutdownResponse) err := c.cc.Invoke(ctx, FlowService_ShutdownFlow_FullMethodName, in, out, opts...) @@ -109,6 +131,8 @@ type FlowServiceServer interface { CreatePeer(context.Context, *CreatePeerRequest) (*CreatePeerResponse, error) CreateCDCFlow(context.Context, *CreateCDCFlowRequest) (*CreateCDCFlowResponse, error) CreateQRepFlow(context.Context, *CreateQRepFlowRequest) (*CreateQRepFlowResponse, error) + GetSlotInfo(context.Context, *PostgresPeerActivityInfoRequest) (*PeerSlotResponse, error) + GetStatInfo(context.Context, *PostgresPeerActivityInfoRequest) (*PeerStatResponse, error) ShutdownFlow(context.Context, *ShutdownRequest) (*ShutdownResponse, error) MirrorStatus(context.Context, *MirrorStatusRequest) (*MirrorStatusResponse, error) mustEmbedUnimplementedFlowServiceServer() @@ -130,6 +154,12 @@ func (UnimplementedFlowServiceServer) CreateCDCFlow(context.Context, *CreateCDCF func (UnimplementedFlowServiceServer) CreateQRepFlow(context.Context, *CreateQRepFlowRequest) (*CreateQRepFlowResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateQRepFlow not implemented") } +func (UnimplementedFlowServiceServer) GetSlotInfo(context.Context, *PostgresPeerActivityInfoRequest) (*PeerSlotResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSlotInfo not implemented") +} +func (UnimplementedFlowServiceServer) GetStatInfo(context.Context, *PostgresPeerActivityInfoRequest) (*PeerStatResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetStatInfo not implemented") +} func (UnimplementedFlowServiceServer) ShutdownFlow(context.Context, *ShutdownRequest) (*ShutdownResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ShutdownFlow not implemented") } @@ -221,6 +251,42 @@ func _FlowService_CreateQRepFlow_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _FlowService_GetSlotInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PostgresPeerActivityInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FlowServiceServer).GetSlotInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FlowService_GetSlotInfo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FlowServiceServer).GetSlotInfo(ctx, req.(*PostgresPeerActivityInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _FlowService_GetStatInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PostgresPeerActivityInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FlowServiceServer).GetStatInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FlowService_GetStatInfo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FlowServiceServer).GetStatInfo(ctx, req.(*PostgresPeerActivityInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _FlowService_ShutdownFlow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ShutdownRequest) if err := dec(in); err != nil { @@ -280,6 +346,14 @@ var FlowService_ServiceDesc = grpc.ServiceDesc{ MethodName: "CreateQRepFlow", Handler: _FlowService_CreateQRepFlow_Handler, }, + { + MethodName: "GetSlotInfo", + Handler: _FlowService_GetSlotInfo_Handler, + }, + { + MethodName: "GetStatInfo", + Handler: _FlowService_GetStatInfo_Handler, + }, { MethodName: "ShutdownFlow", Handler: _FlowService_ShutdownFlow_Handler, diff --git a/nexus/pt/src/peerdb_route.rs b/nexus/pt/src/peerdb_route.rs index ca15178fff..f9905ba487 100644 --- a/nexus/pt/src/peerdb_route.rs +++ b/nexus/pt/src/peerdb_route.rs @@ -119,6 +119,54 @@ pub struct CdcSyncStatus { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct PostgresPeerActivityInfoRequest { + #[prost(string, tag="1")] + pub peer_name: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SlotInfo { + #[prost(string, tag="1")] + pub slot_name: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub redo_l_sn: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub restart_l_sn: ::prost::alloc::string::String, + #[prost(bool, tag="4")] + pub active: bool, + #[prost(float, tag="5")] + pub lag_in_mb: f32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StatInfo { + #[prost(int64, tag="1")] + pub pid: i64, + #[prost(string, tag="2")] + pub wait_event: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub wait_event_type: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub query_start: ::prost::alloc::string::String, + #[prost(string, tag="5")] + pub query: ::prost::alloc::string::String, + #[prost(float, tag="6")] + pub duration: f32, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PeerSlotResponse { + #[prost(message, repeated, tag="1")] + pub slot_data: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PeerStatResponse { + #[prost(message, repeated, tag="1")] + pub stat_data: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SnapshotStatus { #[prost(message, repeated, tag="1")] pub clones: ::prost::alloc::vec::Vec, diff --git a/nexus/pt/src/peerdb_route.serde.rs b/nexus/pt/src/peerdb_route.serde.rs index f26486a6ab..da3c57cbba 100644 --- a/nexus/pt/src/peerdb_route.serde.rs +++ b/nexus/pt/src/peerdb_route.serde.rs @@ -1408,6 +1408,294 @@ impl<'de> serde::Deserialize<'de> for PartitionStatus { deserializer.deserialize_struct("peerdb_route.PartitionStatus", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for PeerSlotResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.slot_data.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("peerdb_route.PeerSlotResponse", len)?; + if !self.slot_data.is_empty() { + struct_ser.serialize_field("slotData", &self.slot_data)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for PeerSlotResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "slot_data", + "slotData", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + SlotData, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "slotData" | "slot_data" => Ok(GeneratedField::SlotData), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = PeerSlotResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct peerdb_route.PeerSlotResponse") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut slot_data__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::SlotData => { + if slot_data__.is_some() { + return Err(serde::de::Error::duplicate_field("slotData")); + } + slot_data__ = Some(map.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map.next_value::()?; + } + } + } + Ok(PeerSlotResponse { + slot_data: slot_data__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("peerdb_route.PeerSlotResponse", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for PeerStatResponse { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.stat_data.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("peerdb_route.PeerStatResponse", len)?; + if !self.stat_data.is_empty() { + struct_ser.serialize_field("statData", &self.stat_data)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for PeerStatResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "stat_data", + "statData", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + StatData, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "statData" | "stat_data" => Ok(GeneratedField::StatData), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = PeerStatResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct peerdb_route.PeerStatResponse") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut stat_data__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::StatData => { + if stat_data__.is_some() { + return Err(serde::de::Error::duplicate_field("statData")); + } + stat_data__ = Some(map.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map.next_value::()?; + } + } + } + Ok(PeerStatResponse { + stat_data: stat_data__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("peerdb_route.PeerStatResponse", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for PostgresPeerActivityInfoRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.peer_name.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("peerdb_route.PostgresPeerActivityInfoRequest", len)?; + if !self.peer_name.is_empty() { + struct_ser.serialize_field("peerName", &self.peer_name)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for PostgresPeerActivityInfoRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "peer_name", + "peerName", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + PeerName, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "peerName" | "peer_name" => Ok(GeneratedField::PeerName), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = PostgresPeerActivityInfoRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct peerdb_route.PostgresPeerActivityInfoRequest") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut peer_name__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::PeerName => { + if peer_name__.is_some() { + return Err(serde::de::Error::duplicate_field("peerName")); + } + peer_name__ = Some(map.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map.next_value::()?; + } + } + } + Ok(PostgresPeerActivityInfoRequest { + peer_name: peer_name__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("peerdb_route.PostgresPeerActivityInfoRequest", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for QRepMirrorStatus { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -1783,6 +2071,175 @@ impl<'de> serde::Deserialize<'de> for ShutdownResponse { deserializer.deserialize_struct("peerdb_route.ShutdownResponse", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for SlotInfo { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.slot_name.is_empty() { + len += 1; + } + if !self.redo_l_sn.is_empty() { + len += 1; + } + if !self.restart_l_sn.is_empty() { + len += 1; + } + if self.active { + len += 1; + } + if self.lag_in_mb != 0. { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("peerdb_route.SlotInfo", len)?; + if !self.slot_name.is_empty() { + struct_ser.serialize_field("slotName", &self.slot_name)?; + } + if !self.redo_l_sn.is_empty() { + struct_ser.serialize_field("redoLSN", &self.redo_l_sn)?; + } + if !self.restart_l_sn.is_empty() { + struct_ser.serialize_field("restartLSN", &self.restart_l_sn)?; + } + if self.active { + struct_ser.serialize_field("active", &self.active)?; + } + if self.lag_in_mb != 0. { + struct_ser.serialize_field("lagInMb", &self.lag_in_mb)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for SlotInfo { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "slot_name", + "slotName", + "redo_lSN", + "redoLSN", + "restart_lSN", + "restartLSN", + "active", + "lag_in_mb", + "lagInMb", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + SlotName, + RedoLSn, + RestartLSn, + Active, + LagInMb, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "slotName" | "slot_name" => Ok(GeneratedField::SlotName), + "redoLSN" | "redo_lSN" => Ok(GeneratedField::RedoLSn), + "restartLSN" | "restart_lSN" => Ok(GeneratedField::RestartLSn), + "active" => Ok(GeneratedField::Active), + "lagInMb" | "lag_in_mb" => Ok(GeneratedField::LagInMb), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SlotInfo; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct peerdb_route.SlotInfo") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut slot_name__ = None; + let mut redo_l_sn__ = None; + let mut restart_l_sn__ = None; + let mut active__ = None; + let mut lag_in_mb__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::SlotName => { + if slot_name__.is_some() { + return Err(serde::de::Error::duplicate_field("slotName")); + } + slot_name__ = Some(map.next_value()?); + } + GeneratedField::RedoLSn => { + if redo_l_sn__.is_some() { + return Err(serde::de::Error::duplicate_field("redoLSN")); + } + redo_l_sn__ = Some(map.next_value()?); + } + GeneratedField::RestartLSn => { + if restart_l_sn__.is_some() { + return Err(serde::de::Error::duplicate_field("restartLSN")); + } + restart_l_sn__ = Some(map.next_value()?); + } + GeneratedField::Active => { + if active__.is_some() { + return Err(serde::de::Error::duplicate_field("active")); + } + active__ = Some(map.next_value()?); + } + GeneratedField::LagInMb => { + if lag_in_mb__.is_some() { + return Err(serde::de::Error::duplicate_field("lagInMb")); + } + lag_in_mb__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::__SkipField__ => { + let _ = map.next_value::()?; + } + } + } + Ok(SlotInfo { + slot_name: slot_name__.unwrap_or_default(), + redo_l_sn: redo_l_sn__.unwrap_or_default(), + restart_l_sn: restart_l_sn__.unwrap_or_default(), + active: active__.unwrap_or_default(), + lag_in_mb: lag_in_mb__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("peerdb_route.SlotInfo", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for SnapshotStatus { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -1878,6 +2335,193 @@ impl<'de> serde::Deserialize<'de> for SnapshotStatus { deserializer.deserialize_struct("peerdb_route.SnapshotStatus", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for StatInfo { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.pid != 0 { + len += 1; + } + if !self.wait_event.is_empty() { + len += 1; + } + if !self.wait_event_type.is_empty() { + len += 1; + } + if !self.query_start.is_empty() { + len += 1; + } + if !self.query.is_empty() { + len += 1; + } + if self.duration != 0. { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("peerdb_route.StatInfo", len)?; + if self.pid != 0 { + struct_ser.serialize_field("pid", ToString::to_string(&self.pid).as_str())?; + } + if !self.wait_event.is_empty() { + struct_ser.serialize_field("waitEvent", &self.wait_event)?; + } + if !self.wait_event_type.is_empty() { + struct_ser.serialize_field("waitEventType", &self.wait_event_type)?; + } + if !self.query_start.is_empty() { + struct_ser.serialize_field("queryStart", &self.query_start)?; + } + if !self.query.is_empty() { + struct_ser.serialize_field("query", &self.query)?; + } + if self.duration != 0. { + struct_ser.serialize_field("duration", &self.duration)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for StatInfo { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "pid", + "wait_event", + "waitEvent", + "wait_event_type", + "waitEventType", + "query_start", + "queryStart", + "query", + "duration", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Pid, + WaitEvent, + WaitEventType, + QueryStart, + Query, + Duration, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "pid" => Ok(GeneratedField::Pid), + "waitEvent" | "wait_event" => Ok(GeneratedField::WaitEvent), + "waitEventType" | "wait_event_type" => Ok(GeneratedField::WaitEventType), + "queryStart" | "query_start" => Ok(GeneratedField::QueryStart), + "query" => Ok(GeneratedField::Query), + "duration" => Ok(GeneratedField::Duration), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = StatInfo; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct peerdb_route.StatInfo") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut pid__ = None; + let mut wait_event__ = None; + let mut wait_event_type__ = None; + let mut query_start__ = None; + let mut query__ = None; + let mut duration__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::Pid => { + if pid__.is_some() { + return Err(serde::de::Error::duplicate_field("pid")); + } + pid__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::WaitEvent => { + if wait_event__.is_some() { + return Err(serde::de::Error::duplicate_field("waitEvent")); + } + wait_event__ = Some(map.next_value()?); + } + GeneratedField::WaitEventType => { + if wait_event_type__.is_some() { + return Err(serde::de::Error::duplicate_field("waitEventType")); + } + wait_event_type__ = Some(map.next_value()?); + } + GeneratedField::QueryStart => { + if query_start__.is_some() { + return Err(serde::de::Error::duplicate_field("queryStart")); + } + query_start__ = Some(map.next_value()?); + } + GeneratedField::Query => { + if query__.is_some() { + return Err(serde::de::Error::duplicate_field("query")); + } + query__ = Some(map.next_value()?); + } + GeneratedField::Duration => { + if duration__.is_some() { + return Err(serde::de::Error::duplicate_field("duration")); + } + duration__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::__SkipField__ => { + let _ = map.next_value::()?; + } + } + } + Ok(StatInfo { + pid: pid__.unwrap_or_default(), + wait_event: wait_event__.unwrap_or_default(), + wait_event_type: wait_event_type__.unwrap_or_default(), + query_start: query_start__.unwrap_or_default(), + query: query__.unwrap_or_default(), + duration: duration__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("peerdb_route.StatInfo", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for ValidatePeerRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result diff --git a/nexus/pt/src/peerdb_route.tonic.rs b/nexus/pt/src/peerdb_route.tonic.rs index 33c035e715..8023085ca0 100644 --- a/nexus/pt/src/peerdb_route.tonic.rs +++ b/nexus/pt/src/peerdb_route.tonic.rs @@ -190,6 +190,58 @@ pub mod flow_service_client { self.inner.unary(req, path, codec).await } /// + pub async fn get_slot_info( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/peerdb_route.FlowService/GetSlotInfo", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("peerdb_route.FlowService", "GetSlotInfo")); + self.inner.unary(req, path, codec).await + } + /// + pub async fn get_stat_info( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/peerdb_route.FlowService/GetStatInfo", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("peerdb_route.FlowService", "GetStatInfo")); + self.inner.unary(req, path, codec).await + } + /// pub async fn shutdown_flow( &mut self, request: impl tonic::IntoRequest, @@ -283,6 +335,22 @@ pub mod flow_service_server { tonic::Status, >; /// + async fn get_slot_info( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// + async fn get_stat_info( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + /// async fn shutdown_flow( &self, request: tonic::Request, @@ -561,6 +629,102 @@ pub mod flow_service_server { }; Box::pin(fut) } + "/peerdb_route.FlowService/GetSlotInfo" => { + #[allow(non_camel_case_types)] + struct GetSlotInfoSvc(pub Arc); + impl< + T: FlowService, + > tonic::server::UnaryService + for GetSlotInfoSvc { + type Response = super::PeerSlotResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::PostgresPeerActivityInfoRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + (*inner).get_slot_info(request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = GetSlotInfoSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/peerdb_route.FlowService/GetStatInfo" => { + #[allow(non_camel_case_types)] + struct GetStatInfoSvc(pub Arc); + impl< + T: FlowService, + > tonic::server::UnaryService + for GetStatInfoSvc { + type Response = super::PeerStatResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request< + super::PostgresPeerActivityInfoRequest, + >, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + (*inner).get_stat_info(request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = GetStatInfoSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/peerdb_route.FlowService/ShutdownFlow" => { #[allow(non_camel_case_types)] struct ShutdownFlowSvc(pub Arc); diff --git a/protos/route.proto b/protos/route.proto index 96c1649ea2..abf14deb87 100644 --- a/protos/route.proto +++ b/protos/route.proto @@ -94,6 +94,35 @@ message CDCSyncStatus { google.protobuf.Timestamp end_time = 5; } +message PostgresPeerActivityInfoRequest { + string peer_name = 1; +} + +message SlotInfo { + string slot_name = 1; + string redo_lSN = 2; + string restart_lSN = 3; + bool active = 4; + float lag_in_mb = 5; +} + +message StatInfo { + int64 pid = 1; + string wait_event = 2; + string wait_event_type = 3; + string query_start = 4; + string query = 5; + float duration = 6; +} + +message PeerSlotResponse { + repeated SlotInfo slot_data = 1; +} + +message PeerStatResponse { + repeated StatInfo stat_data = 1; +} + message SnapshotStatus { repeated QRepMirrorStatus clones = 1; } @@ -138,6 +167,12 @@ service FlowService { body: "*" }; } + rpc GetSlotInfo(PostgresPeerActivityInfoRequest) returns (PeerSlotResponse) { + option (google.api.http) = { get: "/v1/peers/slots/{peer_name}" }; + } + rpc GetStatInfo(PostgresPeerActivityInfoRequest) returns (PeerStatResponse) { + option (google.api.http) = { get: "/v1/peers/stats/{peer_name}" }; + } rpc ShutdownFlow(ShutdownRequest) returns (ShutdownResponse) {} rpc MirrorStatus(MirrorStatusRequest) returns (MirrorStatusResponse) { option (google.api.http) = { get: "/v1/mirrors/{flow_job_name}" }; diff --git a/ui/app/dto/MirrorsDTO.ts b/ui/app/dto/MirrorsDTO.ts index 792ad4a93f..16a6995b47 100644 --- a/ui/app/dto/MirrorsDTO.ts +++ b/ui/app/dto/MirrorsDTO.ts @@ -1,3 +1,11 @@ +import { FlowConnectionConfigs, QRepConfig } from '@/grpc_generated/flow'; +import { Dispatch, SetStateAction } from 'react'; + export type UCreateMirrorResponse = { created: boolean; }; + +export type CDCConfig = FlowConnectionConfigs; +export type MirrorConfig = CDCConfig | QRepConfig; +export type MirrorSetter = Dispatch>; +export type TableMapRow = { source: string; destination: string }; diff --git a/ui/app/mirrors/create/cdc.tsx b/ui/app/mirrors/create/cdc.tsx index 0619e7cf69..d21dacdf7b 100644 --- a/ui/app/mirrors/create/cdc.tsx +++ b/ui/app/mirrors/create/cdc.tsx @@ -8,7 +8,7 @@ import { Select, SelectItem } from '@/lib/Select'; import { Switch } from '@/lib/Switch'; import { TextField } from '@/lib/TextField'; import { InfoPopover } from '../../../components/InfoPopover'; -import { CDCConfig, MirrorSetter } from '../types'; +import { CDCConfig, MirrorSetter } from '../../dto/MirrorsDTO'; import { MirrorSetting } from './helpers/common'; interface MirrorConfigProps { settings: MirrorSetting[]; diff --git a/ui/app/mirrors/create/handlers.ts b/ui/app/mirrors/create/handlers.ts index c901c16734..b21f35ea37 100644 --- a/ui/app/mirrors/create/handlers.ts +++ b/ui/app/mirrors/create/handlers.ts @@ -1,7 +1,7 @@ import { UCreateMirrorResponse } from '@/app/dto/MirrorsDTO'; import { QRepConfig } from '@/grpc_generated/flow'; import { Dispatch, SetStateAction } from 'react'; -import { CDCConfig, TableMapRow } from '../types'; +import { CDCConfig, TableMapRow } from '../../dto/MirrorsDTO'; import { cdcSchema, qrepSchema, tableMappingSchema } from './schema'; const validateCDCFields = ( diff --git a/ui/app/mirrors/create/helpers/cdc.ts b/ui/app/mirrors/create/helpers/cdc.ts index 6e2eaec877..f0b1958dbe 100644 --- a/ui/app/mirrors/create/helpers/cdc.ts +++ b/ui/app/mirrors/create/helpers/cdc.ts @@ -1,6 +1,6 @@ import { QRepSyncMode } from '@/grpc_generated/flow'; import { Peer } from '@/grpc_generated/peers'; -import { CDCConfig } from '../../types'; +import { CDCConfig } from '../../../dto/MirrorsDTO'; import { MirrorSetting } from './common'; export const cdcSettings: MirrorSetting[] = [ { diff --git a/ui/app/mirrors/create/page.tsx b/ui/app/mirrors/create/page.tsx index 811f9114c8..09f0ba12cb 100644 --- a/ui/app/mirrors/create/page.tsx +++ b/ui/app/mirrors/create/page.tsx @@ -12,7 +12,7 @@ import { Divider } from '@tremor/react'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; -import { CDCConfig, TableMapRow } from '../types'; +import { CDCConfig, TableMapRow } from '../../dto/MirrorsDTO'; import CDCConfigForm from './cdc'; import { handleCreateCDC, handleCreateQRep } from './handlers'; import { cdcSettings } from './helpers/cdc'; diff --git a/ui/app/mirrors/create/qrep.tsx b/ui/app/mirrors/create/qrep.tsx index 0d0d75c2f2..139b37e07a 100644 --- a/ui/app/mirrors/create/qrep.tsx +++ b/ui/app/mirrors/create/qrep.tsx @@ -9,7 +9,7 @@ import { Switch } from '@/lib/Switch'; import { TextField } from '@/lib/TextField'; import { Tooltip } from '@/lib/Tooltip'; import { InfoPopover } from '../../../components/InfoPopover'; -import { MirrorSetter } from '../types'; +import { MirrorSetter } from '../../dto/MirrorsDTO'; import { MirrorSetting } from './helpers/common'; interface QRepConfigProps { settings: MirrorSetting[]; diff --git a/ui/app/mirrors/create/tablemapping.tsx b/ui/app/mirrors/create/tablemapping.tsx index b1893ef8ba..99cca34db2 100644 --- a/ui/app/mirrors/create/tablemapping.tsx +++ b/ui/app/mirrors/create/tablemapping.tsx @@ -4,7 +4,7 @@ import { Icon } from '@/lib/Icon'; import { Label } from '@/lib/Label'; import { TextField } from '@/lib/TextField'; import { Dispatch, SetStateAction } from 'react'; -import { TableMapRow } from '../types'; +import { TableMapRow } from '../../dto/MirrorsDTO'; interface TableMappingProps { rows: TableMapRow[]; diff --git a/ui/app/mirrors/page.tsx b/ui/app/mirrors/page.tsx index 9cbb00035b..663a9cd3cf 100644 --- a/ui/app/mirrors/page.tsx +++ b/ui/app/mirrors/page.tsx @@ -75,10 +75,18 @@ async function CDCFlows() { - +
+ +
- +
+ +
- +
+ +
- +
+ +
- diff --git a/ui/components/CopyButton.tsx b/ui/components/CopyButton.tsx new file mode 100644 index 0000000000..b5d10de1e1 --- /dev/null +++ b/ui/components/CopyButton.tsx @@ -0,0 +1,20 @@ +'use client'; +import { Button } from '@/lib/Button'; +import { Icon } from '@/lib/Icon'; +import { useState } from 'react'; + +export const CopyButton = ({ text }: { text: string }) => { + const [copied, setCopied] = useState(false); + const handleClick = () => { + navigator.clipboard.writeText(text); + setCopied(true); + }; + return ( + + ); +}; diff --git a/ui/components/ReloadButton.tsx b/ui/components/ReloadButton.tsx new file mode 100644 index 0000000000..f8701d3d69 --- /dev/null +++ b/ui/components/ReloadButton.tsx @@ -0,0 +1,16 @@ +'use client'; +import { Button } from '@/lib/Button'; +import { Icon } from '@/lib/Icon'; + +const ReloadButton = () => { + return ( + + ); +}; + +export default ReloadButton; diff --git a/ui/grpc_generated/route.ts b/ui/grpc_generated/route.ts index 236f7e0928..4be3e25b40 100644 --- a/ui/grpc_generated/route.ts +++ b/ui/grpc_generated/route.ts @@ -175,6 +175,35 @@ export interface CDCSyncStatus { endTime: Date | undefined; } +export interface PostgresPeerActivityInfoRequest { + peerName: string; +} + +export interface SlotInfo { + slotName: string; + redoLSN: string; + restartLSN: string; + active: boolean; + lagInMb: number; +} + +export interface StatInfo { + pid: number; + waitEvent: string; + waitEventType: string; + queryStart: string; + query: string; + duration: number; +} + +export interface PeerSlotResponse { + slotData: SlotInfo[]; +} + +export interface PeerStatResponse { + statData: StatInfo[]; +} + export interface SnapshotStatus { clones: QRepMirrorStatus[]; } @@ -1262,6 +1291,432 @@ export const CDCSyncStatus = { }, }; +function createBasePostgresPeerActivityInfoRequest(): PostgresPeerActivityInfoRequest { + return { peerName: "" }; +} + +export const PostgresPeerActivityInfoRequest = { + encode(message: PostgresPeerActivityInfoRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.peerName !== "") { + writer.uint32(10).string(message.peerName); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PostgresPeerActivityInfoRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePostgresPeerActivityInfoRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.peerName = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PostgresPeerActivityInfoRequest { + return { peerName: isSet(object.peerName) ? String(object.peerName) : "" }; + }, + + toJSON(message: PostgresPeerActivityInfoRequest): unknown { + const obj: any = {}; + if (message.peerName !== "") { + obj.peerName = message.peerName; + } + return obj; + }, + + create, I>>(base?: I): PostgresPeerActivityInfoRequest { + return PostgresPeerActivityInfoRequest.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>( + object: I, + ): PostgresPeerActivityInfoRequest { + const message = createBasePostgresPeerActivityInfoRequest(); + message.peerName = object.peerName ?? ""; + return message; + }, +}; + +function createBaseSlotInfo(): SlotInfo { + return { slotName: "", redoLSN: "", restartLSN: "", active: false, lagInMb: 0 }; +} + +export const SlotInfo = { + encode(message: SlotInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.slotName !== "") { + writer.uint32(10).string(message.slotName); + } + if (message.redoLSN !== "") { + writer.uint32(18).string(message.redoLSN); + } + if (message.restartLSN !== "") { + writer.uint32(26).string(message.restartLSN); + } + if (message.active === true) { + writer.uint32(32).bool(message.active); + } + if (message.lagInMb !== 0) { + writer.uint32(45).float(message.lagInMb); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): SlotInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSlotInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.slotName = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.redoLSN = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.restartLSN = reader.string(); + continue; + case 4: + if (tag !== 32) { + break; + } + + message.active = reader.bool(); + continue; + case 5: + if (tag !== 45) { + break; + } + + message.lagInMb = reader.float(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): SlotInfo { + return { + slotName: isSet(object.slotName) ? String(object.slotName) : "", + redoLSN: isSet(object.redoLSN) ? String(object.redoLSN) : "", + restartLSN: isSet(object.restartLSN) ? String(object.restartLSN) : "", + active: isSet(object.active) ? Boolean(object.active) : false, + lagInMb: isSet(object.lagInMb) ? Number(object.lagInMb) : 0, + }; + }, + + toJSON(message: SlotInfo): unknown { + const obj: any = {}; + if (message.slotName !== "") { + obj.slotName = message.slotName; + } + if (message.redoLSN !== "") { + obj.redoLSN = message.redoLSN; + } + if (message.restartLSN !== "") { + obj.restartLSN = message.restartLSN; + } + if (message.active === true) { + obj.active = message.active; + } + if (message.lagInMb !== 0) { + obj.lagInMb = message.lagInMb; + } + return obj; + }, + + create, I>>(base?: I): SlotInfo { + return SlotInfo.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): SlotInfo { + const message = createBaseSlotInfo(); + message.slotName = object.slotName ?? ""; + message.redoLSN = object.redoLSN ?? ""; + message.restartLSN = object.restartLSN ?? ""; + message.active = object.active ?? false; + message.lagInMb = object.lagInMb ?? 0; + return message; + }, +}; + +function createBaseStatInfo(): StatInfo { + return { pid: 0, waitEvent: "", waitEventType: "", queryStart: "", query: "", duration: 0 }; +} + +export const StatInfo = { + encode(message: StatInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.pid !== 0) { + writer.uint32(8).int64(message.pid); + } + if (message.waitEvent !== "") { + writer.uint32(18).string(message.waitEvent); + } + if (message.waitEventType !== "") { + writer.uint32(26).string(message.waitEventType); + } + if (message.queryStart !== "") { + writer.uint32(34).string(message.queryStart); + } + if (message.query !== "") { + writer.uint32(42).string(message.query); + } + if (message.duration !== 0) { + writer.uint32(53).float(message.duration); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): StatInfo { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStatInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 8) { + break; + } + + message.pid = longToNumber(reader.int64() as Long); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.waitEvent = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.waitEventType = reader.string(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.queryStart = reader.string(); + continue; + case 5: + if (tag !== 42) { + break; + } + + message.query = reader.string(); + continue; + case 6: + if (tag !== 53) { + break; + } + + message.duration = reader.float(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): StatInfo { + return { + pid: isSet(object.pid) ? Number(object.pid) : 0, + waitEvent: isSet(object.waitEvent) ? String(object.waitEvent) : "", + waitEventType: isSet(object.waitEventType) ? String(object.waitEventType) : "", + queryStart: isSet(object.queryStart) ? String(object.queryStart) : "", + query: isSet(object.query) ? String(object.query) : "", + duration: isSet(object.duration) ? Number(object.duration) : 0, + }; + }, + + toJSON(message: StatInfo): unknown { + const obj: any = {}; + if (message.pid !== 0) { + obj.pid = Math.round(message.pid); + } + if (message.waitEvent !== "") { + obj.waitEvent = message.waitEvent; + } + if (message.waitEventType !== "") { + obj.waitEventType = message.waitEventType; + } + if (message.queryStart !== "") { + obj.queryStart = message.queryStart; + } + if (message.query !== "") { + obj.query = message.query; + } + if (message.duration !== 0) { + obj.duration = message.duration; + } + return obj; + }, + + create, I>>(base?: I): StatInfo { + return StatInfo.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): StatInfo { + const message = createBaseStatInfo(); + message.pid = object.pid ?? 0; + message.waitEvent = object.waitEvent ?? ""; + message.waitEventType = object.waitEventType ?? ""; + message.queryStart = object.queryStart ?? ""; + message.query = object.query ?? ""; + message.duration = object.duration ?? 0; + return message; + }, +}; + +function createBasePeerSlotResponse(): PeerSlotResponse { + return { slotData: [] }; +} + +export const PeerSlotResponse = { + encode(message: PeerSlotResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.slotData) { + SlotInfo.encode(v!, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PeerSlotResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeerSlotResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.slotData.push(SlotInfo.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeerSlotResponse { + return { slotData: Array.isArray(object?.slotData) ? object.slotData.map((e: any) => SlotInfo.fromJSON(e)) : [] }; + }, + + toJSON(message: PeerSlotResponse): unknown { + const obj: any = {}; + if (message.slotData?.length) { + obj.slotData = message.slotData.map((e) => SlotInfo.toJSON(e)); + } + return obj; + }, + + create, I>>(base?: I): PeerSlotResponse { + return PeerSlotResponse.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PeerSlotResponse { + const message = createBasePeerSlotResponse(); + message.slotData = object.slotData?.map((e) => SlotInfo.fromPartial(e)) || []; + return message; + }, +}; + +function createBasePeerStatResponse(): PeerStatResponse { + return { statData: [] }; +} + +export const PeerStatResponse = { + encode(message: PeerStatResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.statData) { + StatInfo.encode(v!, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PeerStatResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeerStatResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.statData.push(StatInfo.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeerStatResponse { + return { statData: Array.isArray(object?.statData) ? object.statData.map((e: any) => StatInfo.fromJSON(e)) : [] }; + }, + + toJSON(message: PeerStatResponse): unknown { + const obj: any = {}; + if (message.statData?.length) { + obj.statData = message.statData.map((e) => StatInfo.toJSON(e)); + } + return obj; + }, + + create, I>>(base?: I): PeerStatResponse { + return PeerStatResponse.fromPartial(base ?? ({} as any)); + }, + fromPartial, I>>(object: I): PeerStatResponse { + const message = createBasePeerStatResponse(); + message.statData = object.statData?.map((e) => StatInfo.fromPartial(e)) || []; + return message; + }, +}; + function createBaseSnapshotStatus(): SnapshotStatus { return { clones: [] }; } @@ -1558,6 +2013,26 @@ export const FlowServiceService = { responseSerialize: (value: CreateQRepFlowResponse) => Buffer.from(CreateQRepFlowResponse.encode(value).finish()), responseDeserialize: (value: Buffer) => CreateQRepFlowResponse.decode(value), }, + getSlotInfo: { + path: "/peerdb_route.FlowService/GetSlotInfo", + requestStream: false, + responseStream: false, + requestSerialize: (value: PostgresPeerActivityInfoRequest) => + Buffer.from(PostgresPeerActivityInfoRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => PostgresPeerActivityInfoRequest.decode(value), + responseSerialize: (value: PeerSlotResponse) => Buffer.from(PeerSlotResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => PeerSlotResponse.decode(value), + }, + getStatInfo: { + path: "/peerdb_route.FlowService/GetStatInfo", + requestStream: false, + responseStream: false, + requestSerialize: (value: PostgresPeerActivityInfoRequest) => + Buffer.from(PostgresPeerActivityInfoRequest.encode(value).finish()), + requestDeserialize: (value: Buffer) => PostgresPeerActivityInfoRequest.decode(value), + responseSerialize: (value: PeerStatResponse) => Buffer.from(PeerStatResponse.encode(value).finish()), + responseDeserialize: (value: Buffer) => PeerStatResponse.decode(value), + }, shutdownFlow: { path: "/peerdb_route.FlowService/ShutdownFlow", requestStream: false, @@ -1583,6 +2058,8 @@ export interface FlowServiceServer extends UntypedServiceImplementation { createPeer: handleUnaryCall; createCdcFlow: handleUnaryCall; createQRepFlow: handleUnaryCall; + getSlotInfo: handleUnaryCall; + getStatInfo: handleUnaryCall; shutdownFlow: handleUnaryCall; mirrorStatus: handleUnaryCall; } @@ -1648,6 +2125,36 @@ export interface FlowServiceClient extends Client { options: Partial, callback: (error: ServiceError | null, response: CreateQRepFlowResponse) => void, ): ClientUnaryCall; + getSlotInfo( + request: PostgresPeerActivityInfoRequest, + callback: (error: ServiceError | null, response: PeerSlotResponse) => void, + ): ClientUnaryCall; + getSlotInfo( + request: PostgresPeerActivityInfoRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: PeerSlotResponse) => void, + ): ClientUnaryCall; + getSlotInfo( + request: PostgresPeerActivityInfoRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: PeerSlotResponse) => void, + ): ClientUnaryCall; + getStatInfo( + request: PostgresPeerActivityInfoRequest, + callback: (error: ServiceError | null, response: PeerStatResponse) => void, + ): ClientUnaryCall; + getStatInfo( + request: PostgresPeerActivityInfoRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: PeerStatResponse) => void, + ): ClientUnaryCall; + getStatInfo( + request: PostgresPeerActivityInfoRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: PeerStatResponse) => void, + ): ClientUnaryCall; shutdownFlow( request: ShutdownRequest, callback: (error: ServiceError | null, response: ShutdownResponse) => void, diff --git a/ui/lib/Table/TableCell.styles.ts b/ui/lib/Table/TableCell.styles.ts index da48a6cb0e..301a4287e4 100644 --- a/ui/lib/Table/TableCell.styles.ts +++ b/ui/lib/Table/TableCell.styles.ts @@ -20,7 +20,5 @@ type BaseTableCellProps = { export const BaseTableCell = styled.td` border-collapse: collapse; overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; ${({ $variant }) => variants[$variant]} `;