Ver Fonte

SVI Добавление статистики топика; 6.5%

SVI há 2 anos atrás
pai
commit
e76ca38653

+ 2 - 2
api/gobus.proto

@@ -69,8 +69,8 @@ message PublicRequest {
 message TopicMsg{
     int32 Source = 1; // Источник данных (0 -- клиент, другое -- реплика)
     string Topic = 2; // Где опубликовать запрос
-    bytes Msg    = 3; // Байтовое представление сообщения
-    string Uuid  = 4; // Уникальная метка сообщения
+    bytes BinMsg    = 3; // Байтовое представление сообщения
+    string StrUuid  = 4; // Уникальная метка сообщения
 }
 
 

+ 36 - 35
api/netapi/gobus.pb.go

@@ -414,10 +414,10 @@ type TopicMsg struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Source int32  `protobuf:"varint,1,opt,name=Source,proto3" json:"Source,omitempty"` // Источник данных (0 -- клиент, другое -- реплика)
-	Topic  string `protobuf:"bytes,2,opt,name=Topic,proto3" json:"Topic,omitempty"`    // Где опубликовать запрос
-	Msg    []byte `protobuf:"bytes,3,opt,name=Msg,proto3" json:"Msg,omitempty"`        // Байтовое представление сообщения
-	Uuid   string `protobuf:"bytes,4,opt,name=Uuid,proto3" json:"Uuid,omitempty"`      // Уникальная метка сообщения
+	Source  int32  `protobuf:"varint,1,opt,name=Source,proto3" json:"Source,omitempty"`  // Источник данных (0 -- клиент, другое -- реплика)
+	Topic   string `protobuf:"bytes,2,opt,name=Topic,proto3" json:"Topic,omitempty"`     // Где опубликовать запрос
+	BinMsg  []byte `protobuf:"bytes,3,opt,name=BinMsg,proto3" json:"BinMsg,omitempty"`   // Байтовое представление сообщения
+	StrUuid string `protobuf:"bytes,4,opt,name=StrUuid,proto3" json:"StrUuid,omitempty"` // Уникальная метка сообщения
 }
 
 func (x *TopicMsg) Reset() {
@@ -466,16 +466,16 @@ func (x *TopicMsg) GetTopic() string {
 	return ""
 }
 
-func (x *TopicMsg) GetMsg() []byte {
+func (x *TopicMsg) GetBinMsg() []byte {
 	if x != nil {
-		return x.Msg
+		return x.BinMsg
 	}
 	return nil
 }
 
-func (x *TopicMsg) GetUuid() string {
+func (x *TopicMsg) GetStrUuid() string {
 	if x != nil {
-		return x.Uuid
+		return x.StrUuid
 	}
 	return ""
 }
@@ -556,36 +556,37 @@ var file_api_gobus_proto_rawDesc = []byte{
 	0x69, 0x6e, 0x2e, 0x54, 0x6f, 0x70, 0x69, 0x63, 0x4d, 0x73, 0x67, 0x52, 0x08, 0x74, 0x6f, 0x70,
 	0x69, 0x63, 0x4d, 0x73, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, 0x73,
 	0x4c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0b, 0x52, 0x65, 0x70, 0x6c,
-	0x69, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x08, 0x54, 0x6f, 0x70, 0x69, 0x63,
+	0x69, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x08, 0x54, 0x6f, 0x70, 0x69, 0x63,
 	0x4d, 0x73, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20,
 	0x01, 0x28, 0x05, 0x52, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x54,
 	0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x6f, 0x70, 0x69,
-	0x63, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03,
-	0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x55, 0x75, 0x69, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x44, 0x65, 0x66, 0x61, 0x75,
-	0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xcc, 0x02, 0x0a, 0x05, 0x47,
-	0x6f, 0x42, 0x75, 0x73, 0x12, 0x3e, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x17,
-	0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72,
-	0x69, 0x6e, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x79, 0x6e, 0x63,
-	0x12, 0x15, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72,
-	0x69, 0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x43, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x1a,
-	0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
-	0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x61, 0x72,
-	0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x44, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
-	0x69, 0x62, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x70, 0x61, 0x72, 0x73,
-	0x65, 0x72, 0x69, 0x6e, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x16, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x42, 0x75, 0x66, 0x66,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x03,
-	0x47, 0x65, 0x74, 0x12, 0x1a, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53,
-	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x16, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x6e,
-	0x65, 0x74, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x63, 0x12, 0x16, 0x0a, 0x06, 0x42, 0x69, 0x6e, 0x4d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x0c, 0x52, 0x06, 0x42, 0x69, 0x6e, 0x4d, 0x73, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x74, 0x72,
+	0x55, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x74, 0x72, 0x55,
+	0x75, 0x69, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xcc, 0x02, 0x0a, 0x05, 0x47, 0x6f, 0x42, 0x75, 0x73,
+	0x12, 0x3e, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x17, 0x2e, 0x70, 0x61, 0x72,
+	0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x44,
+	0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x12, 0x3b, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x15, 0x2e, 0x70,
+	0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53,
+	0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a,
+	0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x61, 0x72,
+	0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69,
+	0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x30, 0x01, 0x12, 0x44, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x42,
+	0x75, 0x66, 0x66, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e,
+	0x2e, 0x42, 0x75, 0x66, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70,
+	0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x42, 0x75, 0x66, 0x66, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3b, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12,
+	0x1a, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63,
+	0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x61,
+	0x72, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x6e, 0x65, 0x74, 0x61, 0x70,
+	0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (

+ 2 - 2
internal/dict_topic/dict_topic.go

@@ -92,7 +92,7 @@ func (sf *DictTopic) Public(msg *netapi.TopicMsg) error {
 		var err error
 		top_, err = topic.NewTopic(msg)
 		if err != nil {
-			return fmt.Errorf("DictTopic.Add(): in create ITopic, err=\n\t%v\n", err)
+			return fmt.Errorf("DictTopic.Add(): in create ITopic, err=\n\t%w", err)
 		}
 		sf.dict[top_.Name()] = top_
 		{ // Теперь пройтись по все прокси-клиентам и подписать их на новый топик
@@ -126,7 +126,7 @@ func (sf *DictTopic) Size() int {
 	defer sf.block.RUnlock()
 	res := 0
 	for _, topic := range sf.dict {
-		res += topic.Size()
+		res += topic.Stat().Size()
 	}
 	return res
 }

+ 12 - 16
internal/dict_topic/topic/topic.go

@@ -6,25 +6,27 @@ import (
 	"sync"
 
 	"p78git.ddns.net/svi/gobus/api/netapi"
+	"p78git.ddns.net/svi/gobus/internal/dict_topic/topic/topic_stat"
 	"p78git.ddns.net/svi/gobus/pkg/alias"
 	"p78git.ddns.net/svi/gobus/pkg/types"
 )
 
 // Topic -- потокобезопасный топик шины данных
 type Topic struct {
-	name      alias.TopicName
 	dictProxy map[alias.ClientName]types.IClientProxy // Словарь подписок клиентов на топик
 	msg       *netapi.TopicMsg                        // Хранимое сообщение топика
+	stat      *topic_stat.TopicStat                   // Статистика топика
 	block     sync.RWMutex
 }
 
 // Newtopic -- возвращает новый топик
 func NewTopic(msg *netapi.TopicMsg) (*Topic, error) {
-	if msg == nil {
-		return nil, fmt.Errorf("NewTopic(): name is empty")
+	stat, err := topic_stat.NewTopicStat(msg)
+	if err != nil {
+		return nil, fmt.Errorf("NewTopic(): in create TopicStat, err=\n\t%w", err)
 	}
 	sf := &Topic{
-		name:      alias.TopicName(msg.Topic),
+		stat:      stat,
 		msg:       msg,
 		dictProxy: make(map[alias.ClientName]types.IClientProxy),
 	}
@@ -52,7 +54,7 @@ func (sf *Topic) Subscribe(clientProxy types.IClientProxy) error {
 
 // Name -- возвращает имя топика
 func (sf *Topic) Name() alias.TopicName {
-	return sf.name
+	return sf.stat.Name()
 }
 
 // Get -- возвращает содержимое топика
@@ -66,11 +68,8 @@ func (sf *Topic) Get() *netapi.TopicMsg {
 func (sf *Topic) Set(msg *netapi.TopicMsg) error {
 	sf.block.Lock()
 	defer sf.block.Unlock()
-	if msg == nil {
-		return fmt.Errorf("Topic.Set(): ERROR msg==nil\n")
-	}
-	if sf.name != alias.TopicName(msg.Topic) {
-		return fmt.Errorf("Topic.Set(): topic name(%q)!=msg.Topic(%v)\n", sf.name, msg.Topic)
+	if err := sf.stat.Update(msg); err != nil {
+		return fmt.Errorf("Topic.Set(): ERROR in update self stat, topic(%q), err==\n\t%w", sf.stat.Name(), err)
 	}
 	sf.msg = msg
 	for _, proxy := range sf.dictProxy {
@@ -83,10 +82,7 @@ func (sf *Topic) Set(msg *netapi.TopicMsg) error {
 	return nil
 }
 
-// Size -- возвращает размер топика
-func (sf *Topic) Size() int {
-	sf.block.RLock()
-	defer sf.block.RUnlock()
-	// *2 потому что имя хранится два раза
-	return len(sf.name)*2 + len(sf.msg.Msg)
+// Stat -- возвращает статистику топика
+func (sf *Topic) Stat() types.ITopicStat {
+	return sf.stat
 }

+ 105 - 0
internal/dict_topic/topic/topic_stat/topic_stat.go

@@ -0,0 +1,105 @@
+// package topic_stat -- небольшая статистика топика
+package topic_stat
+
+import (
+	"fmt"
+	"sync"
+
+	"p78git.ddns.net/svi/gobus/api/netapi"
+	"p78git.ddns.net/svi/gobus/pkg/alias"
+	"p78git.ddns.net/svi/gobus/pkg/types"
+)
+
+// TopicStat -- небольшая статистика топика
+type TopicStat struct {
+	countMsg   int             // Количество прокрученных сообщений
+	countTraff int             // Счётчик прокрученного траффика
+	countErr   int             // Количество ошибок топика
+	topicName  alias.TopicName // Имя топика
+	size       int             // Размер топика
+	block      sync.RWMutex
+}
+
+// NewTopicStat -- возвращает статистику топика
+func NewTopicStat(msg *netapi.TopicMsg) (*TopicStat, error) {
+	{ // Предусловия
+		if msg == nil {
+			return nil, fmt.Errorf("NewTopicStat(): TopicMsg==nil")
+		}
+		if msg.Topic == "" {
+			return nil, fmt.Errorf("NewTopicStat(): topicName is empty")
+		}
+	}
+
+	sf := &TopicStat{
+		topicName: alias.TopicName(msg.Topic),
+	}
+	_ = types.ITopicStat(sf)
+	return sf, nil
+}
+
+// Size -- возвращает текущий размер топика
+func (sf *TopicStat) Size() int {
+	sf.block.RLock()
+	defer sf.block.RUnlock()
+	return sf.size
+}
+
+// CountTraff -- возвращает количество траффика пропущенного через топик
+func (sf *TopicStat) CountTraff() int {
+	sf.block.RLock()
+	defer sf.block.RUnlock()
+	return sf.countTraff
+}
+
+// CountMsg -- возвращает количество сообщений пропущенных через топик
+func (sf *TopicStat) CountMsg() int {
+	sf.block.RLock()
+	defer sf.block.RUnlock()
+	return sf.countMsg
+}
+
+// CountErr -- возвращает количество ошибок счётчика
+func (sf *TopicStat) CountErr() int {
+	sf.block.RLock()
+	defer sf.block.RUnlock()
+	return sf.countErr
+}
+
+// Name -- возвращает имя топика
+func (sf *TopicStat) Name() alias.TopicName {
+	return sf.topicName
+}
+
+const (
+	lenHelper = 24 // Длина UUID и номера источника
+)
+
+// Update -- обновляет статистику
+func (sf *TopicStat) Update(msg *netapi.TopicMsg) error {
+	sf.block.Lock()
+	defer sf.block.Unlock()
+	sf.countMsg++
+	if msg == nil {
+		sf.countErr++
+		return fmt.Errorf("TopicStat.Update(): TopicMsg==nil")
+	}
+	if err := sf.check(msg); err != nil {
+		sf.countErr++
+		return fmt.Errorf("TopicStat.Update(): in check msg, err=\n\t%w", err)
+	}
+	sf.size = len(msg.BinMsg) + len(sf.topicName) + lenHelper
+	sf.countTraff += sf.size
+	return nil
+}
+
+// Проверяет под блокировкой верхнего уровня правильность сообщения
+func (sf *TopicStat) check(msg *netapi.TopicMsg) error {
+	if msg.Topic != string(sf.topicName) {
+		return fmt.Errorf("TopicStat.check(): msg.Topic(%q)!=%q", msg.Topic, sf.topicName)
+	}
+	if len(msg.StrUuid) != 20 {
+		return fmt.Errorf("TopicStat.check(): len msg.StrUuuid(%v)!=20", len(msg.StrUuid))
+	}
+	return nil
+}

+ 4 - 4
internal/dict_topic/topic/topic_test.go

@@ -31,10 +31,10 @@ func (sf *tester) create() {
 func (sf *tester) createGood1() {
 	sf.t.Logf("createGood1")
 	msg := &netapi.TopicMsg{
-		Source: 0,
-		Topic:  "test_topic",
-		Msg:    []byte{},
-		Uuid:   "",
+		Source:  0,
+		Topic:   "test_topic",
+		BinMsg:  []byte{},
+		StrUuid: "",
 	}
 	topic, err := NewTopic(msg)
 	if err != nil {

+ 1 - 1
internal/serv_grpc/serv_subcsribe/serv_subscribe.go

@@ -48,7 +48,7 @@ func (sf *ServSubscribe) Subscribe(req *netapi.SubscribeRequest, serv netapi.GoB
 			return fmt.Errorf("ServSubscribe.Subscribe(): in read ClientProxy, msg==nil")
 		}
 		err := serv.Send(&netapi.SyncResponse{
-			Msg: msg.Msg,
+			Msg: msg.BinMsg,
 		})
 		if err != nil {
 			fnEndWork()

+ 2 - 2
pkg/types/itopic.go

@@ -13,8 +13,8 @@ type ITopic interface {
 	Set(*netapi.TopicMsg) error
 	// Get -- возвращает содержимое топика
 	Get() *netapi.TopicMsg
-	// Size -- возвращает размер топика
-	Size() int
+	// Stat -- возвращает статистику топика
+	Stat() ITopicStat
 	// Subscribe -- подписывает клиента
 	Subscribe(IClientProxy) error
 	// Unsubscribe -- отписывает клиента

+ 17 - 0
pkg/types/itopic_stat.go

@@ -0,0 +1,17 @@
+package types
+
+import "p78git.ddns.net/svi/gobus/pkg/alias"
+
+// ITopicStat -- возвращает статистику топика
+type ITopicStat interface {
+	// Name -- имя топика
+	Name() alias.TopicName
+	// Size -- размер топика
+	Size() int
+	// CountTraff -- общий счётчик траффика
+	CountTraff() int
+	// CountMsg -- количество сообщений
+	CountMsg() int
+	// CountErr -- количество ошибок топика
+	CountErr() int
+}