github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/common/utils/sensor.go (about)

     1  // Copyright 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package utils
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"sync/atomic"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/container/types"
    23  )
    24  
    25  var sequence atomic.Uint64
    26  
    27  func MakeSensorName(
    28  	module string, name string,
    29  ) string {
    30  	return fmt.Sprintf("%s/%s:%d", module, name, sequence.Add(1))
    31  }
    32  
    33  func NewSensorRegistry() *SensorRegistry {
    34  	return &SensorRegistry{
    35  		sensors: make(map[string]Sensor),
    36  	}
    37  }
    38  
    39  func RegisterSensor(sensor Sensor) {
    40  	DefaultSensorRegistry.Lock()
    41  	defer DefaultSensorRegistry.Unlock()
    42  	if _, ok := DefaultSensorRegistry.sensors[sensor.Name()]; ok {
    43  		panic(fmt.Sprintf("sensor %s already exists", sensor.Name()))
    44  	}
    45  	DefaultSensorRegistry.sensors[sensor.Name()] = sensor
    46  }
    47  
    48  func UnregisterSensor(sensor Sensor) {
    49  	DefaultSensorRegistry.Lock()
    50  	defer DefaultSensorRegistry.Unlock()
    51  	if _, ok := DefaultSensorRegistry.sensors[sensor.Name()]; !ok {
    52  		panic(fmt.Sprintf("sensor %s does not exist", sensor.Name()))
    53  	}
    54  	delete(DefaultSensorRegistry.sensors, sensor.Name())
    55  }
    56  
    57  func (r *SensorRegistry) GetSensor(name string) Sensor {
    58  	r.RLock()
    59  	defer r.RUnlock()
    60  	return r.sensors[name]
    61  }
    62  
    63  func (r *SensorRegistry) ForEach(f func(sensor Sensor)) {
    64  	r.RLock()
    65  	defer r.RUnlock()
    66  	for _, sensor := range r.sensors {
    67  		f(sensor)
    68  	}
    69  }
    70  
    71  func WithGetStateSensorOption[T types.OrderedT](fn func(T) SensorState) SensorOption[T] {
    72  	return func(s *NumericSensor[T]) {
    73  		s.getStateFn = fn
    74  	}
    75  }
    76  
    77  func NewNumericSensor[T types.OrderedT](name string, opts ...SensorOption[T]) *NumericSensor[T] {
    78  	s := &NumericSensor[T]{
    79  		name: name,
    80  	}
    81  	for _, opt := range opts {
    82  		opt(s)
    83  	}
    84  	return s
    85  }
    86  
    87  func (s *NumericSensor[T]) Add(v T) T {
    88  	ptr := s.current.Load()
    89  	var newValue T
    90  	if ptr != nil {
    91  		newValue = v + *ptr
    92  	} else {
    93  		newValue = v
    94  	}
    95  	if !s.current.CompareAndSwap(ptr, &newValue) {
    96  		for {
    97  			ptr = s.current.Load()
    98  			if ptr != nil {
    99  				newValue = v + *ptr
   100  			} else {
   101  				newValue = v
   102  			}
   103  			if s.current.CompareAndSwap(ptr, &newValue) {
   104  				break
   105  			}
   106  		}
   107  	}
   108  
   109  	return newValue
   110  }
   111  
   112  func (s *NumericSensor[T]) GetCurrentValue() T {
   113  	ptr := s.current.Load()
   114  	if ptr == nil {
   115  		var v T
   116  		return v
   117  	}
   118  	return *ptr
   119  }
   120  
   121  func (s *NumericSensor[T]) IsRed() bool {
   122  	return s.State() == SensorStateRed
   123  }
   124  
   125  func (s *NumericSensor[T]) State() SensorState {
   126  	if s.getStateFn != nil {
   127  		return s.getStateFn(s.GetCurrentValue())
   128  	}
   129  	return SensorStateGreen
   130  }
   131  
   132  func (s *NumericSensor[T]) Reset() {
   133  	s.current.Store(nil)
   134  }
   135  
   136  func (s *NumericSensor[T]) Name() string {
   137  	return s.name
   138  }
   139  
   140  func (s *NumericSensor[T]) String() string {
   141  	var w bytes.Buffer
   142  	_, _ = w.WriteString(fmt.Sprintf("NumericSensor[\"%s\"]", s.name))
   143  	_, _ = w.WriteString(fmt.Sprintf(" Current:%v", s.GetCurrentValue()))
   144  	_, _ = w.WriteString(fmt.Sprintf(" State:%s", s.State()))
   145  	return w.String()
   146  }
   147  
   148  // SimpleSensor
   149  
   150  func NewSimpleSensor(name string) *SimpleSensor {
   151  	return &SimpleSensor{
   152  		name: name,
   153  	}
   154  }
   155  
   156  func (s *SimpleSensor) IsRed() bool {
   157  	return s.State() == SensorStateRed
   158  }
   159  
   160  func (s *SimpleSensor) State() SensorState {
   161  	state := s.state.Load()
   162  	return SensorState(state)
   163  }
   164  
   165  func (s *SimpleSensor) SetState(state SensorState) {
   166  	s.state.Store(int32(state))
   167  }
   168  
   169  func (s *SimpleSensor) Name() string {
   170  	return s.name
   171  }
   172  
   173  func (s *SimpleSensor) String() string {
   174  	var w bytes.Buffer
   175  	_, _ = w.WriteString(fmt.Sprintf("SimpleSensor[\"%s\"]", s.name))
   176  	_, _ = w.WriteString(fmt.Sprintf(" State:%s", s.State()))
   177  	return w.String()
   178  }