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 19 package channelz
20 21 import (
22 "fmt"
23 "sync/atomic"
24 )
25 26 // Server is the channelz representation of a server.
27 type 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.
41 type 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.
53 func 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.
64 func (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.
72 func (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.
79 func (s *Server) String() string {
80 return fmt.Sprintf("Server #%d", s.ID)
81 }
82 83 func (s *Server) id() int64 {
84 return s.ID
85 }
86 87 func (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 101 func (s *Server) deleteChild(id int64) {
102 delete(s.sockets, id)
103 delete(s.listenSockets, id)
104 s.deleteSelfIfReady()
105 }
106 107 func (s *Server) triggerDelete() {
108 s.closeCalled = true
109 s.deleteSelfIfReady()
110 }
111 112 func (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 119 func (s *Server) getParentID() int64 {
120 return 0
121 }
122