| /* |
| * |
| * Copyright 2024 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| package channelz |
| |
| import ( |
| "fmt" |
| "sync/atomic" |
| ) |
| |
| // Server is the channelz representation of a server. |
| type Server struct { |
| Entity |
| ID int64 |
| RefName string |
| |
| ServerMetrics ServerMetrics |
| |
| closeCalled bool |
| sockets map[int64]string |
| listenSockets map[int64]string |
| cm *channelMap |
| } |
| |
| // ServerMetrics defines a struct containing metrics for servers. |
| type ServerMetrics struct { |
| // The number of incoming calls started on the server. |
| CallsStarted atomic.Int64 |
| // The number of incoming calls that have completed with an OK status. |
| CallsSucceeded atomic.Int64 |
| // The number of incoming calls that have a completed with a non-OK status. |
| CallsFailed atomic.Int64 |
| // The last time a call was started on the server. |
| LastCallStartedTimestamp atomic.Int64 |
| } |
| |
| // NewServerMetricsForTesting returns an initialized ServerMetrics. |
| func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *ServerMetrics { |
| sm := &ServerMetrics{} |
| sm.CallsStarted.Store(started) |
| sm.CallsSucceeded.Store(succeeded) |
| sm.CallsFailed.Store(failed) |
| sm.LastCallStartedTimestamp.Store(timestamp) |
| return sm |
| } |
| |
| // CopyFrom copies the metrics data from the provided ServerMetrics |
| // instance into the current instance. |
| func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) { |
| sm.CallsStarted.Store(o.CallsStarted.Load()) |
| sm.CallsSucceeded.Store(o.CallsSucceeded.Load()) |
| sm.CallsFailed.Store(o.CallsFailed.Load()) |
| sm.LastCallStartedTimestamp.Store(o.LastCallStartedTimestamp.Load()) |
| } |
| |
| // ListenSockets returns the listening sockets for s. |
| func (s *Server) ListenSockets() map[int64]string { |
| db.mu.RLock() |
| defer db.mu.RUnlock() |
| return copyMap(s.listenSockets) |
| } |
| |
| // String returns a printable description of s. |
| func (s *Server) String() string { |
| return fmt.Sprintf("Server #%d", s.ID) |
| } |
| |
| func (s *Server) id() int64 { |
| return s.ID |
| } |
| |
| func (s *Server) addChild(id int64, e entry) { |
| switch v := e.(type) { |
| case *Socket: |
| switch v.SocketType { |
| case SocketTypeNormal: |
| s.sockets[id] = v.RefName |
| case SocketTypeListen: |
| s.listenSockets[id] = v.RefName |
| } |
| default: |
| logger.Errorf("cannot add a child (id = %d) of type %T to a server", id, e) |
| } |
| } |
| |
| func (s *Server) deleteChild(id int64) { |
| delete(s.sockets, id) |
| delete(s.listenSockets, id) |
| s.deleteSelfIfReady() |
| } |
| |
| func (s *Server) triggerDelete() { |
| s.closeCalled = true |
| s.deleteSelfIfReady() |
| } |
| |
| func (s *Server) deleteSelfIfReady() { |
| if !s.closeCalled || len(s.sockets)+len(s.listenSockets) != 0 { |
| return |
| } |
| s.cm.deleteEntry(s.ID) |
| } |
| |
| func (s *Server) getParentID() int64 { |
| return 0 |
| } |