broker/memory: optimize

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2021-07-23 15:12:20 +03:00
parent 419cd486cf
commit 80e3d239ab

View File

@ -14,7 +14,6 @@ import (
type memoryBroker struct { type memoryBroker struct {
subscribers map[string][]*memorySubscriber subscribers map[string][]*memorySubscriber
batchsubscribers map[string][]*memorySubscriber
addr string addr string
opts Options opts Options
sync.RWMutex sync.RWMutex
@ -147,8 +146,7 @@ func (m *memoryBroker) BatchPublish(ctx context.Context, msgs []*Message, opts .
} }
func (m *memoryBroker) publish(ctx context.Context, vs []msgWrapper, opts ...PublishOption) error { func (m *memoryBroker) publish(ctx context.Context, vs []msgWrapper, opts ...PublishOption) error {
if len(m.batchsubscribers) > 0 { var err error
eh := m.opts.BatchErrorHandler
msgTopicMap := make(map[string]Events) msgTopicMap := make(map[string]Events)
for _, v := range vs { for _, v := range vs {
@ -160,51 +158,40 @@ func (m *memoryBroker) publish(ctx context.Context, vs []msgWrapper, opts ...Pub
msgTopicMap[p.topic] = append(msgTopicMap[p.topic], p) msgTopicMap[p.topic] = append(msgTopicMap[p.topic], p)
} }
beh := m.opts.BatchErrorHandler
eh := m.opts.ErrorHandler
for t, ms := range msgTopicMap { for t, ms := range msgTopicMap {
m.RLock() m.RLock()
subs, ok := m.batchsubscribers[t] subs, ok := m.subscribers[t]
m.RUnlock() m.RUnlock()
if !ok { if !ok {
continue continue
} }
for _, sub := range subs { for _, sub := range subs {
if err := sub.batchhandler(ms); err != nil { // batch processing
if sub.batchhandler != nil {
if err = sub.batchhandler(ms); err != nil {
ms.SetError(err) ms.SetError(err)
if sub.opts.BatchErrorHandler != nil { if sub.opts.BatchErrorHandler != nil {
eh = sub.opts.BatchErrorHandler beh = sub.opts.BatchErrorHandler
} }
if eh != nil { if beh != nil {
eh(ms) beh(ms)
} else if m.opts.Logger.V(logger.ErrorLevel) { } else if m.opts.Logger.V(logger.ErrorLevel) {
m.opts.Logger.Error(m.opts.Context, err.Error()) m.opts.Logger.Error(m.opts.Context, err.Error())
} }
} else if sub.opts.AutoAck { } else if sub.opts.AutoAck {
if err := ms.Ack(); err != nil { if err = ms.Ack(); err != nil {
m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err) m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err)
} }
} }
} }
} // single processing
if sub.handler != nil {
} for _, p := range ms {
if err = sub.handler(p); err != nil {
eh := m.opts.ErrorHandler
for _, v := range vs {
p := &memoryEvent{
topic: v.topic,
message: v.body,
opts: m.opts,
}
m.RLock()
subs, ok := m.subscribers[p.topic]
m.RUnlock()
if !ok {
continue
}
for _, sub := range subs {
if err := sub.handler(p); err != nil {
p.SetError(err) p.SetError(err)
if sub.opts.ErrorHandler != nil { if sub.opts.ErrorHandler != nil {
eh = sub.opts.ErrorHandler eh = sub.opts.ErrorHandler
@ -215,12 +202,14 @@ func (m *memoryBroker) publish(ctx context.Context, vs []msgWrapper, opts ...Pub
m.opts.Logger.Error(m.opts.Context, err.Error()) m.opts.Logger.Error(m.opts.Context, err.Error())
} }
} else if sub.opts.AutoAck { } else if sub.opts.AutoAck {
if err := p.Ack(); err != nil { if err = p.Ack(); err != nil {
m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err) m.opts.Logger.Errorf(m.opts.Context, "ack failed: %v", err)
} }
} }
} }
} }
}
}
return nil return nil
} }
@ -250,20 +239,20 @@ func (m *memoryBroker) BatchSubscribe(ctx context.Context, topic string, handler
} }
m.Lock() m.Lock()
m.batchsubscribers[topic] = append(m.batchsubscribers[topic], sub) m.subscribers[topic] = append(m.subscribers[topic], sub)
m.Unlock() m.Unlock()
go func() { go func() {
<-sub.exit <-sub.exit
m.Lock() m.Lock()
newSubscribers := make([]*memorySubscriber, 0, len(m.batchsubscribers)-1) newSubscribers := make([]*memorySubscriber, 0, len(m.subscribers)-1)
for _, sb := range m.batchsubscribers[topic] { for _, sb := range m.subscribers[topic] {
if sb.id == sub.id { if sb.id == sub.id {
continue continue
} }
newSubscribers = append(newSubscribers, sb) newSubscribers = append(newSubscribers, sb)
} }
m.batchsubscribers[topic] = newSubscribers m.subscribers[topic] = newSubscribers
m.Unlock() m.Unlock()
}() }()
@ -375,6 +364,5 @@ func NewBroker(opts ...Option) BatchBroker {
return &memoryBroker{ return &memoryBroker{
opts: NewOptions(opts...), opts: NewOptions(opts...),
subscribers: make(map[string][]*memorySubscriber), subscribers: make(map[string][]*memorySubscriber),
batchsubscribers: make(map[string][]*memorySubscriber),
} }
} }