dubbo.apache.org/dubbo-go/v3@v3.1.1/registry/mock_registry.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package registry
    19  
    20  import (
    21  	"fmt"
    22  	"time"
    23  )
    24  
    25  import (
    26  	"github.com/dubbogo/gost/log/logger"
    27  
    28  	"go.uber.org/atomic"
    29  )
    30  
    31  import (
    32  	"dubbo.apache.org/dubbo-go/v3/common"
    33  )
    34  
    35  // MockRegistry is used as mock registry
    36  type MockRegistry struct {
    37  	listener   *listener
    38  	destroyed  *atomic.Bool
    39  	allAddress chan []*ServiceEvent
    40  }
    41  
    42  // NewMockRegistry creates a mock registry
    43  func NewMockRegistry(url *common.URL) (Registry, error) {
    44  	registry := &MockRegistry{
    45  		destroyed:  atomic.NewBool(false),
    46  		allAddress: make(chan []*ServiceEvent),
    47  	}
    48  	listener := &listener{count: 0, registry: registry, listenChan: make(chan *ServiceEvent)}
    49  	registry.listener = listener
    50  	return registry, nil
    51  }
    52  
    53  // Register is used as a mock registry
    54  func (*MockRegistry) Register(url *common.URL) error {
    55  	return nil
    56  }
    57  
    58  // nolint
    59  func (r *MockRegistry) UnRegister(conf *common.URL) error {
    60  	return nil
    61  }
    62  
    63  // nolint
    64  func (r *MockRegistry) Destroy() {
    65  	if r.destroyed.CAS(false, true) {
    66  	}
    67  }
    68  
    69  // IsAvailable is use for determine a mock registry available
    70  func (r *MockRegistry) IsAvailable() bool {
    71  	return !r.destroyed.Load()
    72  }
    73  
    74  // nolint
    75  func (r *MockRegistry) GetURL() *common.URL {
    76  	return nil
    77  }
    78  
    79  func (r *MockRegistry) subscribe(*common.URL) (Listener, error) {
    80  	return r.listener, nil
    81  }
    82  
    83  // nolint
    84  func (r *MockRegistry) Subscribe(url *common.URL, notifyListener NotifyListener) error {
    85  	go func() {
    86  		for {
    87  			t, listener := r.checkLoopSubscribe(url)
    88  			if t == 0 {
    89  				continue
    90  			} else if t == -1 {
    91  				return
    92  			}
    93  			for {
    94  				serviceEvent, err := listener.Next()
    95  				if err != nil {
    96  					listener.Close()
    97  					time.Sleep(time.Duration(3) * time.Second)
    98  					return
    99  				}
   100  
   101  				logger.Infof("[Mock Registry] update begin, service event: %v", serviceEvent.String())
   102  				notifyListener.Notify(serviceEvent)
   103  			}
   104  		}
   105  	}()
   106  	go func() {
   107  		for {
   108  			t, _ := r.checkLoopSubscribe(url)
   109  			if t == 0 {
   110  				continue
   111  			} else if t == -1 {
   112  				return
   113  			}
   114  
   115  			for {
   116  				select {
   117  				case e := <-r.allAddress:
   118  					notifyListener.NotifyAll(e, func() {
   119  						fmt.Print("notify all ok")
   120  					})
   121  					break
   122  				}
   123  			}
   124  		}
   125  	}()
   126  	return nil
   127  }
   128  
   129  // UnSubscribe :
   130  func (r *MockRegistry) UnSubscribe(url *common.URL, notifyListener NotifyListener) error {
   131  	return nil
   132  }
   133  
   134  // LoadSubscribeInstances load subscribe instance
   135  func (r *MockRegistry) LoadSubscribeInstances(_ *common.URL, _ NotifyListener) error {
   136  	return nil
   137  }
   138  
   139  type listener struct {
   140  	count      int64
   141  	registry   *MockRegistry
   142  	listenChan chan *ServiceEvent
   143  }
   144  
   145  func (l *listener) Next() (*ServiceEvent, error) {
   146  	return <-l.listenChan, nil
   147  }
   148  
   149  func (*listener) Close() {
   150  }
   151  
   152  // nolint
   153  func (r *MockRegistry) MockEvent(event *ServiceEvent) {
   154  	r.listener.listenChan <- event
   155  }
   156  
   157  // nolint
   158  func (r *MockRegistry) MockEvents(events []*ServiceEvent) {
   159  	r.allAddress <- events
   160  }
   161  
   162  func (r *MockRegistry) checkLoopSubscribe(url *common.URL) (int, Listener) {
   163  	if !r.IsAvailable() {
   164  		logger.Warnf("event listener game over.")
   165  		time.Sleep(time.Duration(3) * time.Second)
   166  		return -1, nil
   167  	}
   168  
   169  	listener, err := r.subscribe(url)
   170  	if err != nil {
   171  		if !r.IsAvailable() {
   172  			logger.Warnf("event listener game over.")
   173  			return -1, nil
   174  		}
   175  		time.Sleep(time.Duration(3) * time.Second)
   176  		return 0, nil
   177  	}
   178  	return 1, listener
   179  }