github.com/zly-app/zapp@v1.3.3/component/msgbus/subscriber.go (about)

     1  /*
     2  -------------------------------------------------
     3     Author :       zlyuancn
     4     date:         2021/3/19
     5     Description :
     6  -------------------------------------------------
     7  */
     8  
     9  package msgbus
    10  
    11  import (
    12  	"runtime"
    13  	"sync/atomic"
    14  
    15  	"go.uber.org/zap"
    16  
    17  	"github.com/zly-app/zapp/consts"
    18  	"github.com/zly-app/zapp/core"
    19  	"github.com/zly-app/zapp/pkg/utils"
    20  )
    21  
    22  // 全局自增订阅者id
    23  var autoIncrSubscriberId uint32
    24  
    25  // 生成下一个订阅者id
    26  func nextSubscriberId() uint32 {
    27  	return atomic.AddUint32(&autoIncrSubscriberId, 1)
    28  }
    29  
    30  // 订阅者
    31  type subscriber struct {
    32  	handler core.MsgbusHandler
    33  	queue   chan *channelMsg
    34  
    35  	isClose uint32
    36  }
    37  
    38  func newSubscriber(threadCount int, handler core.MsgbusHandler) *subscriber {
    39  	if threadCount < 1 {
    40  		threadCount = runtime.NumCPU() >> 1
    41  		if threadCount < 1 {
    42  			threadCount = 1
    43  		}
    44  	}
    45  	// 创建订阅者
    46  	sub := &subscriber{
    47  		handler: handler,
    48  		queue:   make(chan *channelMsg, consts.DefaultMsgbusQueueSize),
    49  	}
    50  
    51  	// 开始消费
    52  	for i := 0; i < threadCount; i++ {
    53  		go sub.start()
    54  	}
    55  
    56  	return sub
    57  }
    58  
    59  func (s *subscriber) start() {
    60  	for msg := range s.queue {
    61  		s.process(msg)
    62  	}
    63  }
    64  
    65  func (s *subscriber) process(msg *channelMsg) {
    66  	ctx := newContext(msg)
    67  
    68  	ctx.Debug("msgbus.receive")
    69  
    70  	err := utils.Recover.WrapCall(func() error {
    71  		return s.handler(ctx)
    72  	})
    73  
    74  	if err == nil {
    75  		ctx.Debug("msgbus.success")
    76  		return
    77  	}
    78  
    79  	ctx.Error("msgbus.error!", zap.String("error", utils.Recover.GetRecoverErrorDetail(err)))
    80  }
    81  
    82  // 关闭
    83  func (s *subscriber) Close() {
    84  	if atomic.CompareAndSwapUint32(&s.isClose, 0, 1) {
    85  		close(s.queue)
    86  	}
    87  }