| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // 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
- }
|