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  }