2424package channelz
2525
2626import (
27- "context"
2827"errors"
29- "fmt"
3028"sort"
3129"sync"
3230"sync/atomic"
@@ -40,8 +38,11 @@ const (
4038)
4139
4240var (
43- db dbWrapper
44- idGen idGenerator
41+ // IDGen is the global channelz entity ID generator. It should not be used
42+ // outside this package except by tests.
43+ IDGen IDGenerator
44+
45+ db dbWrapper
4546// EntryPerPage defines the number of channelz entries to be shown on a web page.
4647EntryPerPage = int64 (50 )
4748curState int32
@@ -52,14 +53,14 @@ var (
5253func TurnOn () {
5354if ! IsOn () {
5455db .set (newChannelMap ())
55- idGen . reset ()
56+ IDGen . Reset ()
5657atomic .StoreInt32 (& curState , 1 )
5758}
5859}
5960
6061// IsOn returns whether channelz data collection is on.
6162func IsOn () bool {
62- return atomic .CompareAndSwapInt32 (& curState , 1 , 1 )
63+ return atomic .LoadInt32 (& curState ) == 1
6364}
6465
6566// SetMaxTraceEntry sets maximum number of trace entry per entity (i.e. channel/subchannel).
@@ -97,43 +98,6 @@ func (d *dbWrapper) get() *channelMap {
9798return d .DB
9899}
99100
100- // NewChannelzStorageForTesting initializes channelz data storage and id
101- // generator for testing purposes.
102- //
103- // Returns a cleanup function to be invoked by the test, which waits for up to
104- // 10s for all channelz state to be reset by the grpc goroutines when those
105- // entities get closed. This cleanup function helps with ensuring that tests
106- // don't mess up each other.
107- func NewChannelzStorageForTesting () (cleanup func () error ) {
108- db .set (newChannelMap ())
109- idGen .reset ()
110-
111- return func () error {
112- cm := db .get ()
113- if cm == nil {
114- return nil
115- }
116-
117- ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
118- defer cancel ()
119- ticker := time .NewTicker (10 * time .Millisecond )
120- defer ticker .Stop ()
121- for {
122- cm .mu .RLock ()
123- topLevelChannels , servers , channels , subChannels , listenSockets , normalSockets := len (cm .topLevelChannels ), len (cm .servers ), len (cm .channels ), len (cm .subChannels ), len (cm .listenSockets ), len (cm .normalSockets )
124- cm .mu .RUnlock ()
125-
126- if err := ctx .Err (); err != nil {
127- return fmt .Errorf ("after 10s the channelz map has not been cleaned up yet, topchannels: %d, servers: %d, channels: %d, subchannels: %d, listen sockets: %d, normal sockets: %d" , topLevelChannels , servers , channels , subChannels , listenSockets , normalSockets )
128- }
129- if topLevelChannels == 0 && servers == 0 && channels == 0 && subChannels == 0 && listenSockets == 0 && normalSockets == 0 {
130- return nil
131- }
132- <- ticker .C
133- }
134- }
135- }
136-
137101// GetTopChannels returns a slice of top channel's ChannelMetric, along with a
138102// boolean indicating whether there's more top channels to be queried for.
139103//
@@ -193,7 +157,7 @@ func GetServer(id int64) *ServerMetric {
193157//
194158// If channelz is not turned ON, the channelz database is not mutated.
195159func RegisterChannel (c Channel , pid * Identifier , ref string ) * Identifier {
196- id := idGen .genID ()
160+ id := IDGen .genID ()
197161var parent int64
198162isTopChannel := true
199163if pid != nil {
@@ -229,7 +193,7 @@ func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, er
229193if pid == nil {
230194return nil , errors .New ("a SubChannel's parent id cannot be nil" )
231195}
232- id := idGen .genID ()
196+ id := IDGen .genID ()
233197if ! IsOn () {
234198return newIdentifer (RefSubChannel , id , pid ), nil
235199}
@@ -251,7 +215,7 @@ func RegisterSubChannel(c Channel, pid *Identifier, ref string) (*Identifier, er
251215//
252216// If channelz is not turned ON, the channelz database is not mutated.
253217func RegisterServer (s Server , ref string ) * Identifier {
254- id := idGen .genID ()
218+ id := IDGen .genID ()
255219if ! IsOn () {
256220return newIdentifer (RefServer , id , nil )
257221}
@@ -277,7 +241,7 @@ func RegisterListenSocket(s Socket, pid *Identifier, ref string) (*Identifier, e
277241if pid == nil {
278242return nil , errors .New ("a ListenSocket's parent id cannot be 0" )
279243}
280- id := idGen .genID ()
244+ id := IDGen .genID ()
281245if ! IsOn () {
282246return newIdentifer (RefListenSocket , id , pid ), nil
283247}
@@ -297,7 +261,7 @@ func RegisterNormalSocket(s Socket, pid *Identifier, ref string) (*Identifier, e
297261if pid == nil {
298262return nil , errors .New ("a NormalSocket's parent id cannot be 0" )
299263}
300- id := idGen .genID ()
264+ id := IDGen .genID ()
301265if ! IsOn () {
302266return newIdentifer (RefNormalSocket , id , pid ), nil
303267}
@@ -776,14 +740,17 @@ func (c *channelMap) GetServer(id int64) *ServerMetric {
776740return sm
777741}
778742
779- type idGenerator struct {
743+ // IDGenerator is an incrementing atomic that tracks IDs for channelz entities.
744+ type IDGenerator struct {
780745id int64
781746}
782747
783- func (i * idGenerator ) reset () {
748+ // Reset resets the generated ID back to zero. Should only be used at
749+ // initialization or by tests sensitive to the ID number.
750+ func (i * IDGenerator ) Reset () {
784751atomic .StoreInt64 (& i .id , 0 )
785752}
786753
787- func (i * idGenerator ) genID () int64 {
754+ func (i * IDGenerator ) genID () int64 {
788755return atomic .AddInt64 (& i .id , 1 )
789756}
0 commit comments