github.com/polarismesh/polaris@v1.17.8/common/eventhub/subscription.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package eventhub 19 20 import ( 21 "context" 22 23 "github.com/polarismesh/polaris/common/log" 24 ) 25 26 const ( 27 defaultQueueSize = 16384 28 ) 29 30 // Handler event handler 31 type Handler interface { 32 // PreProcess do preprocess logic for event 33 PreProcess(context.Context, any) any 34 // OnEvent event process logic 35 OnEvent(ctx context.Context, any2 any) error 36 } 37 38 type SubscribtionContext struct { 39 subID string 40 cancel context.CancelFunc 41 } 42 43 func (s *SubscribtionContext) Cancel() { 44 s.cancel() 45 } 46 47 // Subscription subscription info 48 type subscription struct { 49 name string 50 queue chan Event 51 closeCh chan struct{} 52 handler Handler 53 opts *SubOptions 54 } 55 56 func newSubscription(name string, handler Handler, opts ...SubOption) *subscription { 57 subOpts := &SubOptions{ 58 QueueSize: defaultQueueSize, 59 } 60 for _, o := range opts { 61 o(subOpts) 62 } 63 if subOpts.QueueSize == 0 { 64 subOpts.QueueSize = defaultQueueSize 65 } 66 sub := &subscription{ 67 name: name, 68 queue: make(chan Event, subOpts.QueueSize), 69 closeCh: make(chan struct{}), 70 handler: handler, 71 opts: subOpts, 72 } 73 return sub 74 } 75 76 func (s *subscription) send(ctx context.Context, event Event) { 77 select { 78 case s.queue <- event: 79 if log.DebugEnabled() { 80 log.Debugf("[EventHub] subscription:%s send event:%v", s.name, event) 81 } 82 case <-s.closeCh: 83 log.Infof("[EventHub] subscription:%s send close", s.name) 84 return 85 case <-ctx.Done(): 86 log.Infof("[EventHub] subscription:%s send close by context cancel", s.name) 87 return 88 } 89 return 90 } 91 92 func (s *subscription) receive(ctx context.Context) { 93 for { 94 select { 95 case event := <-s.queue: 96 if log.DebugEnabled() { 97 log.Debugf("[EventHub] subscription:%s receive event:%v", s.name, event) 98 } 99 event = s.handler.PreProcess(ctx, event) 100 if err := s.handler.OnEvent(ctx, event); err != nil { 101 log.Errorf("[EventHub] subscriptions:%s handler event error:%s", s.name, err.Error()) 102 } 103 case <-s.closeCh: 104 log.Infof("[EventHub] subscription:%s receive close", s.name) 105 return 106 case <-ctx.Done(): 107 log.Infof("[EventHub] subscription:%s receive close by context cancel", s.name) 108 return 109 } 110 } 111 } 112 113 func (s *subscription) close() { 114 close(s.closeCh) 115 } 116 117 // SubOption subscription option func 118 type SubOption func(s *SubOptions) 119 120 // SubOptions subscripion options 121 type SubOptions struct { 122 QueueSize int 123 } 124 125 // WithQueueSize set event queue size 126 func WithQueueSize(size int) SubOption { 127 return func(s *SubOptions) { 128 s.QueueSize = size 129 } 130 }