server.go

  1/*
  2 *
  3 * Copyright 2024 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
 19package channelz
 20
 21import (
 22	"fmt"
 23	"sync/atomic"
 24)
 25
 26// Server is the channelz representation of a server.
 27type Server struct {
 28	Entity
 29	ID      int64
 30	RefName string
 31
 32	ServerMetrics ServerMetrics
 33
 34	closeCalled   bool
 35	sockets       map[int64]string
 36	listenSockets map[int64]string
 37	cm            *channelMap
 38}
 39
 40// ServerMetrics defines a struct containing metrics for servers.
 41type ServerMetrics struct {
 42	// The number of incoming calls started on the server.
 43	CallsStarted atomic.Int64
 44	// The number of incoming calls that have completed with an OK status.
 45	CallsSucceeded atomic.Int64
 46	// The number of incoming calls that have a completed with a non-OK status.
 47	CallsFailed atomic.Int64
 48	// The last time a call was started on the server.
 49	LastCallStartedTimestamp atomic.Int64
 50}
 51
 52// NewServerMetricsForTesting returns an initialized ServerMetrics.
 53func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *ServerMetrics {
 54	sm := &ServerMetrics{}
 55	sm.CallsStarted.Store(started)
 56	sm.CallsSucceeded.Store(succeeded)
 57	sm.CallsFailed.Store(failed)
 58	sm.LastCallStartedTimestamp.Store(timestamp)
 59	return sm
 60}
 61
 62// CopyFrom copies the metrics data from the provided ServerMetrics
 63// instance into the current instance.
 64func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) {
 65	sm.CallsStarted.Store(o.CallsStarted.Load())
 66	sm.CallsSucceeded.Store(o.CallsSucceeded.Load())
 67	sm.CallsFailed.Store(o.CallsFailed.Load())
 68	sm.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load())
 69}
 70
 71// ListenSockets returns the listening sockets for s.
 72func (s *Server) ListenSockets() map[int64]string {
 73	db.mu.RLock()
 74	defer db.mu.RUnlock()
 75	return copyMap(s.listenSockets)
 76}
 77
 78// String returns a printable description of s.
 79func (s *Server) String() string {
 80	return fmt.Sprintf("Server #%d", s.ID)
 81}
 82
 83func (s *Server) id() int64 {
 84	return s.ID
 85}
 86
 87func (s *Server) addChild(id int64, e entry) {
 88	switch v := e.(type) {
 89	case *Socket:
 90		switch v.SocketType {
 91		case SocketTypeNormal:
 92			s.sockets[id] = v.RefName
 93		case SocketTypeListen:
 94			s.listenSockets[id] = v.RefName
 95		}
 96	default:
 97		logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e)
 98	}
 99}
100
101func (s *Server) deleteChild(id int64) {
102	delete(s.sockets, id)
103	delete(s.listenSockets, id)
104	s.deleteSelfIfReady()
105}
106
107func (s *Server) triggerDelete() {
108	s.closeCalled = true
109	s.deleteSelfIfReady()
110}
111
112func (s *Server) deleteSelfIfReady() {
113	if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 {
114		return
115	}
116	s.cm.deleteEntry(s.ID)
117}
118
119func (s *Server) getParentID() int64 {
120	return 0
121}