mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 08:42:24 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			230 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
 *
 | 
						|
 * Copyright 2018 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 defines internal APIs for enabling channelz service, entry
 | 
						|
// registration/deletion, and accessing channelz data. It also defines channelz
 | 
						|
// metric struct formats.
 | 
						|
package channelz
 | 
						|
 | 
						|
import (
 | 
						|
	"sync/atomic"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"google.golang.org/grpc/internal"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	// IDGen is the global channelz entity ID generator.  It should not be used
 | 
						|
	// outside this package except by tests.
 | 
						|
	IDGen IDGenerator
 | 
						|
 | 
						|
	db *channelMap = newChannelMap()
 | 
						|
	// EntriesPerPage defines the number of channelz entries to be shown on a web page.
 | 
						|
	EntriesPerPage = 50
 | 
						|
	curState       int32
 | 
						|
)
 | 
						|
 | 
						|
// TurnOn turns on channelz data collection.
 | 
						|
func TurnOn() {
 | 
						|
	atomic.StoreInt32(&curState, 1)
 | 
						|
}
 | 
						|
 | 
						|
func init() {
 | 
						|
	internal.ChannelzTurnOffForTesting = func() {
 | 
						|
		atomic.StoreInt32(&curState, 0)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// IsOn returns whether channelz data collection is on.
 | 
						|
func IsOn() bool {
 | 
						|
	return atomic.LoadInt32(&curState) == 1
 | 
						|
}
 | 
						|
 | 
						|
// GetTopChannels returns a slice of top channel's ChannelMetric, along with a
 | 
						|
// boolean indicating whether there's more top channels to be queried for.
 | 
						|
//
 | 
						|
// The arg id specifies that only top channel with id at or above it will be
 | 
						|
// included in the result. The returned slice is up to a length of the arg
 | 
						|
// maxResults or EntriesPerPage if maxResults is zero, and is sorted in ascending
 | 
						|
// id order.
 | 
						|
func GetTopChannels(id int64, maxResults int) ([]*Channel, bool) {
 | 
						|
	return db.getTopChannels(id, maxResults)
 | 
						|
}
 | 
						|
 | 
						|
// GetServers returns a slice of server's ServerMetric, along with a
 | 
						|
// boolean indicating whether there's more servers to be queried for.
 | 
						|
//
 | 
						|
// The arg id specifies that only server with id at or above it will be included
 | 
						|
// in the result. The returned slice is up to a length of the arg maxResults or
 | 
						|
// EntriesPerPage if maxResults is zero, and is sorted in ascending id order.
 | 
						|
func GetServers(id int64, maxResults int) ([]*Server, bool) {
 | 
						|
	return db.getServers(id, maxResults)
 | 
						|
}
 | 
						|
 | 
						|
// GetServerSockets returns a slice of server's (identified by id) normal socket's
 | 
						|
// SocketMetrics, along with a boolean indicating whether there's more sockets to
 | 
						|
// be queried for.
 | 
						|
//
 | 
						|
// The arg startID specifies that only sockets with id at or above it will be
 | 
						|
// included in the result. The returned slice is up to a length of the arg maxResults
 | 
						|
// or EntriesPerPage if maxResults is zero, and is sorted in ascending id order.
 | 
						|
func GetServerSockets(id int64, startID int64, maxResults int) ([]*Socket, bool) {
 | 
						|
	return db.getServerSockets(id, startID, maxResults)
 | 
						|
}
 | 
						|
 | 
						|
// GetChannel returns the Channel for the channel (identified by id).
 | 
						|
func GetChannel(id int64) *Channel {
 | 
						|
	return db.getChannel(id)
 | 
						|
}
 | 
						|
 | 
						|
// GetSubChannel returns the SubChannel for the subchannel (identified by id).
 | 
						|
func GetSubChannel(id int64) *SubChannel {
 | 
						|
	return db.getSubChannel(id)
 | 
						|
}
 | 
						|
 | 
						|
// GetSocket returns the Socket for the socket (identified by id).
 | 
						|
func GetSocket(id int64) *Socket {
 | 
						|
	return db.getSocket(id)
 | 
						|
}
 | 
						|
 | 
						|
// GetServer returns the ServerMetric for the server (identified by id).
 | 
						|
func GetServer(id int64) *Server {
 | 
						|
	return db.getServer(id)
 | 
						|
}
 | 
						|
 | 
						|
// RegisterChannel registers the given channel c in the channelz database with
 | 
						|
// target as its target and reference name, and adds it to the child list of its
 | 
						|
// parent.  parent == nil means no parent.
 | 
						|
//
 | 
						|
// Returns a unique channelz identifier assigned to this channel.
 | 
						|
//
 | 
						|
// If channelz is not turned ON, the channelz database is not mutated.
 | 
						|
func RegisterChannel(parent *Channel, target string) *Channel {
 | 
						|
	id := IDGen.genID()
 | 
						|
 | 
						|
	if !IsOn() {
 | 
						|
		return &Channel{ID: id}
 | 
						|
	}
 | 
						|
 | 
						|
	isTopChannel := parent == nil
 | 
						|
 | 
						|
	cn := &Channel{
 | 
						|
		ID:          id,
 | 
						|
		RefName:     target,
 | 
						|
		nestedChans: make(map[int64]string),
 | 
						|
		subChans:    make(map[int64]string),
 | 
						|
		Parent:      parent,
 | 
						|
		trace:       &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())},
 | 
						|
	}
 | 
						|
	cn.ChannelMetrics.Target.Store(&target)
 | 
						|
	db.addChannel(id, cn, isTopChannel, cn.getParentID())
 | 
						|
	return cn
 | 
						|
}
 | 
						|
 | 
						|
// RegisterSubChannel registers the given subChannel c in the channelz database
 | 
						|
// with ref as its reference name, and adds it to the child list of its parent
 | 
						|
// (identified by pid).
 | 
						|
//
 | 
						|
// Returns a unique channelz identifier assigned to this subChannel.
 | 
						|
//
 | 
						|
// If channelz is not turned ON, the channelz database is not mutated.
 | 
						|
func RegisterSubChannel(parent *Channel, ref string) *SubChannel {
 | 
						|
	id := IDGen.genID()
 | 
						|
	sc := &SubChannel{
 | 
						|
		ID:      id,
 | 
						|
		RefName: ref,
 | 
						|
		parent:  parent,
 | 
						|
	}
 | 
						|
 | 
						|
	if !IsOn() {
 | 
						|
		return sc
 | 
						|
	}
 | 
						|
 | 
						|
	sc.sockets = make(map[int64]string)
 | 
						|
	sc.trace = &ChannelTrace{CreationTime: time.Now(), Events: make([]*traceEvent, 0, getMaxTraceEntry())}
 | 
						|
	db.addSubChannel(id, sc, parent.ID)
 | 
						|
	return sc
 | 
						|
}
 | 
						|
 | 
						|
// RegisterServer registers the given server s in channelz database. It returns
 | 
						|
// the unique channelz tracking id assigned to this server.
 | 
						|
//
 | 
						|
// If channelz is not turned ON, the channelz database is not mutated.
 | 
						|
func RegisterServer(ref string) *Server {
 | 
						|
	id := IDGen.genID()
 | 
						|
	if !IsOn() {
 | 
						|
		return &Server{ID: id}
 | 
						|
	}
 | 
						|
 | 
						|
	svr := &Server{
 | 
						|
		RefName:       ref,
 | 
						|
		sockets:       make(map[int64]string),
 | 
						|
		listenSockets: make(map[int64]string),
 | 
						|
		ID:            id,
 | 
						|
	}
 | 
						|
	db.addServer(id, svr)
 | 
						|
	return svr
 | 
						|
}
 | 
						|
 | 
						|
// RegisterSocket registers the given normal socket s in channelz database
 | 
						|
// with ref as its reference name, and adds it to the child list of its parent
 | 
						|
// (identified by skt.Parent, which must be set). It returns the unique channelz
 | 
						|
// tracking id assigned to this normal socket.
 | 
						|
//
 | 
						|
// If channelz is not turned ON, the channelz database is not mutated.
 | 
						|
func RegisterSocket(skt *Socket) *Socket {
 | 
						|
	skt.ID = IDGen.genID()
 | 
						|
	if IsOn() {
 | 
						|
		db.addSocket(skt)
 | 
						|
	}
 | 
						|
	return skt
 | 
						|
}
 | 
						|
 | 
						|
// RemoveEntry removes an entry with unique channelz tracking id to be id from
 | 
						|
// channelz database.
 | 
						|
//
 | 
						|
// If channelz is not turned ON, this function is a no-op.
 | 
						|
func RemoveEntry(id int64) {
 | 
						|
	if !IsOn() {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	db.removeEntry(id)
 | 
						|
}
 | 
						|
 | 
						|
// IDGenerator is an incrementing atomic that tracks IDs for channelz entities.
 | 
						|
type IDGenerator struct {
 | 
						|
	id int64
 | 
						|
}
 | 
						|
 | 
						|
// Reset resets the generated ID back to zero.  Should only be used at
 | 
						|
// initialization or by tests sensitive to the ID number.
 | 
						|
func (i *IDGenerator) Reset() {
 | 
						|
	atomic.StoreInt64(&i.id, 0)
 | 
						|
}
 | 
						|
 | 
						|
func (i *IDGenerator) genID() int64 {
 | 
						|
	return atomic.AddInt64(&i.id, 1)
 | 
						|
}
 | 
						|
 | 
						|
// Identifier is an opaque channelz identifier used to expose channelz symbols
 | 
						|
// outside of grpc.  Currently only implemented by Channel since no other
 | 
						|
// types require exposure outside grpc.
 | 
						|
type Identifier interface {
 | 
						|
	Entity
 | 
						|
	channelzIdentifier()
 | 
						|
}
 |