...

Source file src/google.golang.org/grpc/internal/channelz/funcs.go

Documentation: google.golang.org/grpc/internal/channelz

     1  /*
     2   *
     3   * Copyright 2018 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * 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  
    19  // Package channelz defines internal APIs for enabling channelz service, entry
    20  // registration/deletion, and accessing channelz data. It also defines channelz
    21  // metric struct formats.
    22  package channelz
    23  
    24  import (
    25  	"sync/atomic"
    26  	"time"
    27  
    28  	"google.golang.org/grpc/internal"
    29  )
    30  
    31  var (
    32  	// IDGen is the global channelz entity ID generator.  It should not be used
    33  	// outside this package except by tests.
    34  	IDGen IDGenerator
    35  
    36  	db *channelMap = newChannelMap()
    37  	// EntriesPerPage defines the number of channelz entries to be shown on a web page.
    38  	EntriesPerPage = 50
    39  	curState       int32
    40  )
    41  
    42  // TurnOn turns on channelz data collection.
    43  func TurnOn() {
    44  	atomic.StoreInt32(&curState, 1)
    45  }
    46  
    47  func init() {
    48  	internal.ChannelzTurnOffForTesting = func() {
    49  		atomic.StoreInt32(&curState, 0)
    50  	}
    51  }
    52  
    53  // IsOn returns whether channelz data collection is on.
    54  func IsOn() bool {
    55  	return atomic.LoadInt32(&curState) == 1
    56  }
    57  
    58  // GetTopChannels returns a slice of top channel's ChannelMetric, along with a
    59  // boolean indicating whether there's more top channels to be queried for.
    60  //
    61  // The arg id specifies that only top channel with id at or above it will be
    62  // included in the result. The returned slice is up to a length of the arg
    63  // maxResults or EntriesPerPage if maxResults is zero, and is sorted in ascending
    64  // id order.
    65  func GetTopChannels(id int64, maxResults int) ([]*Channel, bool) {
    66  	return db.getTopChannels(id, maxResults)
    67  }
    68  
    69  // GetServers returns a slice of server's ServerMetric, along with a
    70  // boolean indicating whether there's more servers to be queried for.
    71  //
    72  // The arg id specifies that only server with id at or above it will be included
    73  // in the result. The returned slice is up to a length of the arg maxResults or
    74  // EntriesPerPage if maxResults is zero, and is sorted in ascending id order.
    75  func GetServers(id int64, maxResults int) ([]*Server, bool) {
    76  	return db.getServers(id, maxResults)
    77  }
    78  
    79  // GetServerSockets returns a slice of server's (identified by id) normal socket's
    80  // SocketMetrics, along with a boolean indicating whether there's more sockets to
    81  // be queried for.
    82  //
    83  // The arg startID specifies that only sockets with id at or above it will be
    84  // included in the result. The returned slice is up to a length of the arg maxResults
    85  // or EntriesPerPage if maxResults is zero, and is sorted in ascending id order.
    86  func GetServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) {
    87  	return db.getServerSockets(id, startID, maxResults)
    88  }
    89  
    90  // GetChannel returns the Channel for the channel (identified by id).
    91  func GetChannel(id int64) *Channel {
    92  	return db.getChannel(id)
    93  }
    94  
    95  // GetSubChannel returns the SubChannel for the subchannel (identified by id).
    96  func GetSubChannel(id int64) *SubChannel {
    97  	return db.getSubChannel(id)
    98  }
    99  
   100  // GetSocket returns the Socket for the socket (identified by id).
   101  func GetSocket(id int64) *Socket {
   102  	return db.getSocket(id)
   103  }
   104  
   105  // GetServer returns the ServerMetric for the server (identified by id).
   106  func GetServer(id int64) *Server {
   107  	return db.getServer(id)
   108  }
   109  
   110  // RegisterChannel registers the given channel c in the channelz database with
   111  // target as its target and reference name, and adds it to the child list of its
   112  // parent.  parent == nil means no parent.
   113  //
   114  // Returns a unique channelz identifier assigned to this channel.
   115  //
   116  // If channelz is not turned ON, the channelz database is not mutated.
   117  func RegisterChannel(parent *Channel, target string) *Channel {
   118  	id := IDGen.genID()
   119  
   120  	if !IsOn() {
   121  		return &Channel{ID: id}
   122  	}
   123  
   124  	isTopChannel := parent == nil
   125  
   126  	cn := &Channel{
   127  		ID:          id,
   128  		RefName:     target,
   129  		nestedChans: make(map[int64]string),
   130  		subChans:    make(map[int64]string),
   131  		Parent:      parent,
   132  		trace:       &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())},
   133  	}
   134  	cn.ChannelMetrics.Target.Store(&target)
   135  	db.addChannel(id, cn, isTopChannel, cn.getParentID())
   136  	return cn
   137  }
   138  
   139  // RegisterSubChannel registers the given subChannel c in the channelz database
   140  // with ref as its reference name, and adds it to the child list of its parent
   141  // (identified by pid).
   142  //
   143  // Returns a unique channelz identifier assigned to this subChannel.
   144  //
   145  // If channelz is not turned ON, the channelz database is not mutated.
   146  func RegisterSubChannel(parent *Channel, ref string) *SubChannel {
   147  	id := IDGen.genID()
   148  	sc := &SubChannel{
   149  		ID:      id,
   150  		RefName: ref,
   151  		parent:  parent,
   152  	}
   153  
   154  	if !IsOn() {
   155  		return sc
   156  	}
   157  
   158  	sc.sockets = make(map[int64]string)
   159  	sc.trace = &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())}
   160  	db.addSubChannel(id, sc, parent.ID)
   161  	return sc
   162  }
   163  
   164  // RegisterServer registers the given server s in channelz database. It returns
   165  // the unique channelz tracking id assigned to this server.
   166  //
   167  // If channelz is not turned ON, the channelz database is not mutated.
   168  func RegisterServer(ref string) *Server {
   169  	id := IDGen.genID()
   170  	if !IsOn() {
   171  		return &Server{ID: id}
   172  	}
   173  
   174  	svr := &Server{
   175  		RefName:       ref,
   176  		sockets:       make(map[int64]string),
   177  		listenSockets: make(map[int64]string),
   178  		ID:            id,
   179  	}
   180  	db.addServer(id, svr)
   181  	return svr
   182  }
   183  
   184  // RegisterSocket registers the given normal socket s in channelz database
   185  // with ref as its reference name, and adds it to the child list of its parent
   186  // (identified by skt.Parent, which must be set). It returns the unique channelz
   187  // tracking id assigned to this normal socket.
   188  //
   189  // If channelz is not turned ON, the channelz database is not mutated.
   190  func RegisterSocket(skt *Socket) *Socket {
   191  	skt.ID = IDGen.genID()
   192  	if IsOn() {
   193  		db.addSocket(skt)
   194  	}
   195  	return skt
   196  }
   197  
   198  // RemoveEntry removes an entry with unique channelz tracking id to be id from
   199  // channelz database.
   200  //
   201  // If channelz is not turned ON, this function is a no-op.
   202  func RemoveEntry(id int64) {
   203  	if !IsOn() {
   204  		return
   205  	}
   206  	db.removeEntry(id)
   207  }
   208  
   209  // IDGenerator is an incrementing atomic that tracks IDs for channelz entities.
   210  type IDGenerator struct {
   211  	id int64
   212  }
   213  
   214  // Reset resets the generated ID back to zero.  Should only be used at
   215  // initialization or by tests sensitive to the ID number.
   216  func (i *IDGenerator) Reset() {
   217  	atomic.StoreInt64(&i.id, 0)
   218  }
   219  
   220  func (i *IDGenerator) genID() int64 {
   221  	return atomic.AddInt64(&i.id, 1)
   222  }
   223  
   224  // Identifier is an opaque channelz identifier used to expose channelz symbols
   225  // outside of grpc.  Currently only implemented by Channel since no other
   226  // types require exposure outside grpc.
   227  type Identifier interface {
   228  	Entity
   229  	channelzIdentifier()
   230  }
   231  

View as plain text