github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/features/stats/stats.go (about)

     1  package stats
     2  
     3  //go:generate go run v2ray.com/core/common/errors/errorgen
     4  
     5  import (
     6  	"context"
     7      "net"
     8  	"v2ray.com/core/common"
     9  	"v2ray.com/core/features"
    10  )
    11  
    12  
    13  
    14  
    15  // Counter is the interface for stats counters.
    16  //
    17  // v2ray:api:stable
    18  type Counter interface {
    19  	// Value is the current value of the counter.
    20  	Value() int64
    21  	// Set sets a new value to the counter, and returns the previous one.
    22  	Set(int64) int64
    23  	// Add adds a value to the current counter value, and returns the previous value.
    24  	Add(int64) int64
    25  }
    26  
    27  
    28  type IPStorager interface {
    29  	Add(net.IP) bool
    30  	Empty()
    31  	Remove(net.IP) bool
    32  	All() []net.IP
    33  }
    34  // Channel is the interface for stats channel.
    35  //
    36  // v2ray:api:stable
    37  type Channel interface {
    38  	// Channel is a runnable unit.
    39  	common.Runnable
    40  	// Publish broadcasts a message through the channel with a controlling context.
    41  	Publish(context.Context, interface{})
    42  	// SubscriberCount returns the number of the subscribers.
    43  	Subscribers() []chan interface{}
    44  	// Subscribe registers for listening to channel stream and returns a new listener channel.
    45  	Subscribe() (chan interface{}, error)
    46  	// Unsubscribe unregisters a listener channel from current Channel object.
    47  	Unsubscribe(chan interface{}) error
    48  }
    49  
    50  // SubscribeRunnableChannel subscribes the channel and starts it if there is first subscriber coming.
    51  func SubscribeRunnableChannel(c Channel) (chan interface{}, error) {
    52  	if len(c.Subscribers()) == 0 {
    53  		if err := c.Start(); err != nil {
    54  			return nil, err
    55  		}
    56  	}
    57  	return c.Subscribe()
    58  }
    59  
    60  // UnsubscribeClosableChannel unsubcribes the channel and close it if there is no more subscriber.
    61  func UnsubscribeClosableChannel(c Channel, sub chan interface{}) error {
    62  	if err := c.Unsubscribe(sub); err != nil {
    63  		return err
    64  	}
    65  	if len(c.Subscribers()) == 0 {
    66  		return c.Close()
    67  	}
    68  	return nil
    69  }
    70  
    71  // Manager is the interface for stats manager.
    72  //
    73  // v2ray:api:stable
    74  type Manager interface {
    75  	features.Feature
    76  
    77  	// RegisterCounter registers a new counter to the manager. The identifier string must not be empty, and unique among other counters.
    78  	RegisterCounter(string) (Counter, error)
    79  	// UnregisterCounter unregisters a counter from the manager by its identifier.
    80  	UnregisterCounter(string) error
    81  	// GetCounter returns a counter by its identifier.
    82  	GetCounter(string) Counter
    83  
    84  	RegisterIPStorager(string) (IPStorager, error)
    85  	GetIPStorager(string) IPStorager
    86  
    87  	// RegisterChannel registers a new channel to the manager. The identifier string must not be empty, and unique among other channels.
    88  	RegisterChannel(string) (Channel, error)
    89  	// UnregisterCounter unregisters a channel from the manager by its identifier.
    90  	UnregisterChannel(string) error
    91  	// GetChannel returns a channel by its identifier.
    92  	GetChannel(string) Channel
    93  }
    94  
    95  // GetOrRegisterCounter tries to get the StatCounter first. If not exist, it then tries to create a new counter.
    96  func GetOrRegisterCounter(m Manager, name string) (Counter, error) {
    97  	counter := m.GetCounter(name)
    98  	if counter != nil {
    99  		return counter, nil
   100  	}
   101  
   102  	return m.RegisterCounter(name)
   103  }
   104  
   105  func GetOrRegisterIPStorager(m Manager, name string) (IPStorager, error) {
   106  	ipStorager := m.GetIPStorager(name)
   107  	if ipStorager != nil {
   108  		return ipStorager, nil
   109  	}
   110  
   111  	return m.RegisterIPStorager(name)
   112  }
   113  
   114  
   115  // GetOrRegisterChannel tries to get the StatChannel first. If not exist, it then tries to create a new channel.
   116  func GetOrRegisterChannel(m Manager, name string) (Channel, error) {
   117  	channel := m.GetChannel(name)
   118  	if channel != nil {
   119  		return channel, nil
   120  	}
   121  
   122  	return m.RegisterChannel(name)
   123  }
   124  
   125  // ManagerType returns the type of Manager interface. Can be used to implement common.HasType.
   126  //
   127  // v2ray:api:stable
   128  func ManagerType() interface{} {
   129  	return (*Manager)(nil)
   130  }
   131  
   132  // NoopManager is an implementation of Manager, which doesn't has actual functionalities.
   133  type NoopManager struct{}
   134  
   135  // Type implements common.HasType.
   136  func (NoopManager) Type() interface{} {
   137  	return ManagerType()
   138  }
   139  
   140  // RegisterCounter implements Manager.
   141  func (NoopManager) RegisterCounter(string) (Counter, error) {
   142  	return nil, newError("not implemented")
   143  }
   144  
   145  // UnregisterCounter implements Manager.
   146  func (NoopManager) UnregisterCounter(string) error {
   147  	return nil
   148  }
   149  
   150  // GetCounter implements Manager.
   151  func (NoopManager) GetCounter(string) Counter {
   152  	return nil
   153  }
   154  
   155  
   156  func (NoopManager) RegisterIPStorager(string) (IPStorager, error) {
   157  	return nil, newError("not implemented")
   158  }
   159  
   160  func (NoopManager) GetIPStorager(string) IPStorager {
   161  	return nil
   162  }
   163  
   164  // RegisterChannel implements Manager.
   165  func (NoopManager) RegisterChannel(string) (Channel, error) {
   166  	return nil, newError("not implemented")
   167  }
   168  
   169  // UnregisterChannel implements Manager.
   170  func (NoopManager) UnregisterChannel(string) error {
   171  	return nil
   172  }
   173  
   174  // GetChannel implements Manager.
   175  func (NoopManager) GetChannel(string) Channel {
   176  	return nil
   177  }
   178  
   179  // Start implements common.Runnable.
   180  func (NoopManager) Start() error { return nil }
   181  
   182  // Close implements common.Closable.
   183  func (NoopManager) Close() error { return nil }