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 }