Help us shape the future of Go! Take the 2026 Go Developer Survey

tpviz

package
v1.3.104 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 35 Imported by: 0

Documentation

Overview

Package tpviz pkg/tpviz/cxo_latency.go c4-vis-latency

The latency graph behind the latency-space view: an undirected, weighted graph over visor public keys where an edge weight is the measured round-trip time between the two visors.

Source is TPD's metrics CXO feed (metrics/day/<YYYY-MM-DD>), NOT the HTTP /metrics endpoint. The publisher writes []TransportMetric there every 60s and content-addressing means a subscriber pays the delta rather than the whole dataset — 85k transport rows is ~31MB over HTTP, and re-fetching that to move a few edges is what the feed exists to avoid. There is deliberately no HTTP fallback: a view that silently starts polling a rate-limited endpoint when the feed is cold is worse than a view that says the feed is cold.

Only the CURRENT day's leaf is read. Latency is transport-level current state, so that is the only leaf carrying it — and it is also the most representative of the network as it is now, which is what a positional embedding wants. Reading the whole 30-day window would decode ~30 multi-megabyte bodies to find latency in one of them.

Package tpviz pkg/tpviz/cxo_standalone.go c4-app-rewards

Standalone CXO wiring. When tp-viz runs OUTSIDE a visor (the reward server serving theskywirenetwork.net over dmsg), it has no visor to hand it a CXOSubMgr. SetCXOSubMgrFromDmsg builds an intermittent CXO subscriber (pkg/cxo/cxosub) over the server's own dmsg client and wires it in — so the standalone server sources TPD/SD/DMSG-D data from the same CXO feeds the hypervisor uses, instead of HTTP-over-dmsg polling. Feed publisher PKs are resolved from the config's dmsg:// service URLs (TPDURLDmsg / SDURLDmsg / DMSGURLDmsg).

Package tpviz pkg/tpviz/cxo_subscriber.go c4-app-rewards

Optional integration with the visor's on-demand CXO subscription manager. When the hypervisor wires one in via SetCXOSubMgr, /api/services and /api/dmsg/entries try the manager's local snapshot first and fall through to the existing HTTP fetcher on cache miss. AcquireFor / ReleaseFor on each request scopes the underlying CXO subscription to active UI traffic (with the manager's own 10s grace handling multi-fetch tab loads).

Tab and feed identifiers are int constants here that mirror the values defined on the visor side (CXOTab / CXOFeed). The hypervisor's wiring is responsible for matching them; this is a minimal compromise to keep tpviz independent of pkg/visor (which would create an import cycle).

Package tpviz pkg/tpviz/tpviz.go c4-app-rewards

Package tpviz pkg/tpviz/tpviz_legacy_on.go c4-app-rewards

Index

Constants

View Source
const (
	CXOTabNetworkVisualizer = 0
	CXOTabUptime            = 2 // TPD uptime feed
	CXOTabCLITransports     = 5 // TPD routing feed
)

Tab identifiers used in calls to CXOSubMgr.AcquireForTab / ReleaseForTab. Values match pkg/visor.CXOTab / cxosub.Tab; the hypervisor adapter and the standalone adapter pass them through.

View Source
const (
	CXOFeedTPDMetrics           = 0 // metrics/day/<YYYY-MM-DD> (legacy: metrics/days/<n>)
	CXOFeedTPDUptime            = 1 // uptimes/days/<n> — []VisorSummary
	CXOFeedSDServices           = 2 // services/<type>/all (batched; legacy .../<pk>/entry)
	CXOFeedDMSGDClientsByServer = 3 // clients-by-server/<server> (batched; legacy .../<client>/entry)
	CXOFeedTPDAllTransports     = 4 // transports/all/{with-self,without-self}
	CXOFeedTPDStats             = 5 // stats/{network,versions} — network aggregates
	CXOFeedTPDRouting           = 6 // routing/<pk> — the routing feed, one leaf per visor
)

Feed identifiers used in calls to CXOSubMgr.Walk. Values match pkg/visor.CXOFeed / cxosub.Feed; the adapters pass them through.

Variables

This section is empty.

Functions

func CacheDirFromURL

func CacheDirFromURL(serviceURL string) string

CacheDirFromURL returns a cache directory path based on the service URL host. For example, "dmsg://02b307…095ae:80" -> "/tmp/02b307…095ae".

func CacheFilePath

func CacheFilePath(cacheDir, fullURL string) string

CacheFilePath returns the full cache file path for a given URL. If cacheDir is empty, returns "" (disables caching). Creates the cache directory if it doesn't exist. Generates simple, descriptive filenames based on URL path/query.

func GetEmbeddedIndexWithNavLinks(navLinks []NavLink) (string, error)

GetEmbeddedIndexWithNavLinks returns the full embedded legacy index.html with navigation links. This is for the legacy JavaScript UI.

Types

type AppState

type AppState struct {
	Name           string   `json:"name"`
	Status         int      `json:"status"`          // 0=stopped, 1=running, 2=errored, 3=starting
	DetailedStatus string   `json:"detailed_status"` // Human-readable status
	AutoStart      bool     `json:"auto_start"`
	Port           uint16   `json:"port"`
	Args           []string `json:"args,omitempty"`
}

AppState represents the state of an application running on the visor.

type CXOSubMgr

type CXOSubMgr interface {
	AcquireForTab(tab int)
	ReleaseForTab(tab int)
	Walk(feed int, prefix string, fn func(path string, body []byte) bool) bool
}

CXOSubMgr is the minimal slice of pkg/visor.CXOSubscriptionManager tpviz needs. Defined as an interface so tpviz can be built and tested without importing pkg/visor (which would close an import cycle: visor → tpviz → visor). The hypervisor wires a thin adapter in pkg/visor/hypervisor.go.

type Config

type Config struct {
	// Addr is the address to bind to (default: 127.0.0.1)
	Addr string
	// Port is the port to listen on (default: 8080)
	Port int
	// CacheDirTPD is the cache directory for TPD data (default: /tmp/{tpd-host})
	// Set to "" to disable caching
	CacheDirTPD string
	// CacheDirUT is the cache directory for uptime tracker data (default: /tmp/{ut-host})
	// Set to "" to disable caching
	CacheDirUT string
	// CacheDirSD is the cache directory for service discovery data (default: /tmp/{sd-host})
	// Set to "" to disable caching
	CacheDirSD string
	// CacheDirDMSG is the cache directory for DMSG discovery data (default: /tmp/{dmsg-host})
	// Set to "" to disable caching
	CacheDirDMSG string
	// CacheMaxAge is the cache max age in minutes (default: 5)
	CacheMaxAge int
	// TPDURL is the transport discovery URL
	TPDURL string
	// SDURL is the service discovery URL
	SDURL string
	// DMSGURL is the DMSG discovery URL
	DMSGURL string
	// TPDURLDmsg / SDURLDmsg / DMSGURLDmsg are the dmsg:// forms of the
	// deployment-discovery URLs (default from deployment.Prod.*Dmsg). When a
	// dmsg HTTP client is set (SetDmsgHTTPClient), deployment discovery is
	// fetched over dmsg using these instead of the clearnet URLs above —
	// required on a dmsg-only deployment.
	TPDURLDmsg  string
	SDURLDmsg   string
	DMSGURLDmsg string
	// AllowClearnetDisc forces the legacy clearnet deployment-discovery fetches
	// even with no dmsg client / visor API. Default false: on a dmsg-only
	// deployment the clearnet HTTP frontends are dead (404), so the fetches are
	// gated to avoid spamming them.
	AllowClearnetDisc bool
	// NoCache disables caching when true
	NoCache bool
	// AutoRefresh enables auto-refresh of cache at specified interval
	AutoRefresh bool
	// SurveyDir is the directory containing visor surveys (node-info.json files)
	// Used for IP-based grouping without exposing actual IP addresses
	SurveyDir string
	// GeoIPURL is the URL of the geoip service (default from deployment.Prod.GeoIP)
	GeoIPURL string
}

Config holds the configuration for the visualizer server

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a Config with default values

type DMSGData

type DMSGData struct {
	Servers      []DMSGServer `json:"servers"`
	EntriesCount int          `json:"entries_count"`
	Entries      []string     `json:"entries"` // list of all entry PKs
	LastUpdated  time.Time    `json:"last_updated"`
}

DMSGData holds cached DMSG discovery data

type DMSGHealthResponse

type DMSGHealthResponse struct {
	Status    string `json:"status"`
	BuildInfo string `json:"build_info,omitempty"`
	Message   string `json:"message,omitempty"`
	Error     string `json:"error,omitempty"`
}

DMSGHealthResponse contains the response from a DMSG health check.

type DMSGServer

type DMSGServer struct {
	PK                string   `json:"pk"`
	Address           string   `json:"address"`
	AvailableSessions int      `json:"available_sessions"`
	ServerType        string   `json:"server_type"`
	IP                string   `json:"ip,omitempty"`
	Country           string   `json:"country,omitempty"`
	Clients           []string `json:"clients,omitempty"` // PKs of clients connected to this server
}

DMSGServer represents a DMSG server entry

type LatencyEdge

type LatencyEdge struct {
	A string `json:"a"`
	B string `json:"b"`
	// MS is the round-trip time in milliseconds.
	MS float64 `json:"ms"`
	// N is how many transports between this pair were sampled.
	N int `json:"n"`
	// Type is the transport type that produced MS (the fastest one).
	Type string `json:"type"`
}

LatencyEdge is one visor pair and the round-trip time between them.

type LatencyGraph

type LatencyGraph struct {
	Edges []LatencyEdge `json:"edges"`
	// Visors is every public key that appears in Edges, sorted, so the
	// client can index points without a second pass.
	Visors []string `json:"visors"`
	Days   int      `json:"days"`
}

LatencyGraph is what the view consumes.

type LocalRoute

type LocalRoute struct {
	RouteID     uint32 `json:"route_id"`
	Type        string `json:"type"` // "forward", "consume", "intermediary"
	SrcPK       string `json:"src_pk,omitempty"`
	DstPK       string `json:"dst_pk,omitempty"`
	NextHopPK   string `json:"next_hop_pk,omitempty"` // For forward/intermediary routes
	TransportID string `json:"transport_id,omitempty"`
}

LocalRoute represents a routing rule from the local visor

type LocalTransport

type LocalTransport struct {
	ID        string `json:"id"`
	RemotePK  string `json:"remote_pk"`
	Type      string `json:"type"`
	Label     string `json:"label,omitempty"`
	IsSetup   bool   `json:"is_setup"`
	SentBytes uint64 `json:"sent_bytes"`
	RecvBytes uint64 `json:"recv_bytes"`
	// Bandwidth deltas for animation
	SentDelta uint64 `json:"sent_delta"`
	RecvDelta uint64 `json:"recv_delta"`
}

LocalTransport represents a transport from the local visor with traffic stats

type LocalVisorData

type LocalVisorData struct {
	Connected   bool             `json:"connected"`
	PubKey      string           `json:"pub_key,omitempty"`
	Country     string           `json:"country,omitempty"`
	IP          string           `json:"ip,omitempty"`
	Transports  []LocalTransport `json:"transports,omitempty"`
	Routes      []LocalRoute     `json:"routes,omitempty"`
	RoutesCount int              `json:"routes_count"`
	LastUpdated time.Time        `json:"last_updated"`
	// Bandwidth deltas for animation (bytes since last update)
	TotalSentDelta uint64 `json:"total_sent_delta"`
	TotalRecvDelta uint64 `json:"total_recv_delta"`
}

LocalVisorData holds data from the local visor for overlay display

type NavLink struct {
	URL   string
	Label string
}

NavLink represents a navigation link

type PingResponse

type PingResponse struct {
	Status     string  `json:"status"`
	LatencyMs  float64 `json:"latency_ms,omitempty"`
	Latencies  []int64 `json:"latencies,omitempty"` // Individual latencies in ms
	MinMs      float64 `json:"min_ms,omitempty"`
	MaxMs      float64 `json:"max_ms,omitempty"`
	AvgMs      float64 `json:"avg_ms,omitempty"`
	PacketLoss float64 `json:"packet_loss,omitempty"`
	Error      string  `json:"error,omitempty"`
	Mode       string  `json:"mode"` // "route" or "dmsg"
}

PingResponse contains the response from a ping operation.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the transport visualizer HTTP server

func NewServer

func NewServer(cfg Config) *Server

NewServer creates a new visualizer server with the given config

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the HTTP handler for the server.

gzipped on the way out: this mux is mounted on two dmsg listeners (init_services.go) as well as TCP, and /api/transports writes the TPD all-transports snapshot verbatim — the ~3 MB body TPD itself caches pre-gzipped (all_transports_response_cache.go) and then serves raw from here. The content-type gate leaves the wasm blob (application/wasm) and the websocket upgrade alone.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe starts the HTTP server

func (*Server) SetCXOSubMgr

func (s *Server) SetCXOSubMgr(m CXOSubMgr)

SetCXOSubMgr installs (or replaces, with nil to clear) the CXO subscription manager. Idempotent. Safe to call before or after the server is serving.

func (*Server) SetCXOSubMgrFromDmsg

func (s *Server) SetCXOSubMgrFromDmsg(dmsgC *dmsg.Client)

SetCXOSubMgrFromDmsg wires an intermittent CXO subscriber over dmsgC so a STANDALONE tp-viz sources deployment data from the TPD/SD/DMSG-D CXO feeds. No-op when dmsgC is nil. Keep any HTTP-over-dmsg client set via SetDmsgHTTPClient as the fallback: tp-viz tries CXO first and falls through on a cache miss (feed not yet synced), so the two compose safely.

func (*Server) SetDmsgHTTPClient

func (s *Server) SetDmsgHTTPClient(c *http.Client)

SetDmsgHTTPClient installs an HTTP-over-dmsg client so deployment discovery (TPD/SD/DMSG) is fetched over dmsg instead of the (now-dead) clearnet HTTP frontends. Standalone tpviz embeds (e.g. the reward UI) call this with a dmsg-backed client; the deployment URLs are then resolved to their dmsg:// forms. Pass nil to disable.

func (*Server) SetTPSAPI

func (s *Server) SetTPSAPI(api TPSAPI)

SetTPSAPI sets the embedded Transport Setup Node API. When set, the UI will show transport creation controls.

func (*Server) SetVisorAPI

func (s *Server) SetVisorAPI(api VisorAPI, pubKey string)

SetVisorAPI sets the visor API directly, bypassing RPC connection. This is used when the tp-viz server is embedded in the visor itself.

func (*Server) Start

func (s *Server) Start()

Start initializes the cache and starts auto-refresh without starting the HTTP server. Use this when embedding the tpviz server in another HTTP server.

func (*Server) Stop

func (s *Server) Stop()

Stop stops the server and cleans up resources

type ServiceInfo

type ServiceInfo struct {
	PK       string   `json:"pk"`
	Services []string `json:"services"`
	Country  string   `json:"country,omitempty"`
}

ServiceInfo holds service information for a visor

type TPSAPI

type TPSAPI interface {
	AddTransport(ctx context.Context, targetPK, remotePK, tpType string) (*TPSTransportResponse, error)
	RemoveTransport(ctx context.Context, targetPK, tpID string) error
	GetTransports(ctx context.Context, targetPK string) ([]TPSTransportResponse, error)
	PK() string
}

TPSAPI defines the interface for the embedded Transport Setup Node. Used to create/remove transports on remote visors and query their transport lists.

type TPSTransportResponse

type TPSTransportResponse struct {
	ID     string `json:"id"`
	Local  string `json:"local_pk"`
	Remote string `json:"remote_pk"`
	Type   string `json:"type"`
}

TPSTransportResponse represents a transport returned from TPS RPC operations.

type TransportSummary

type TransportSummary struct {
	ID      uuid.UUID           `json:"id"`
	Local   cipher.PubKey       `json:"local_pk"`
	Remote  cipher.PubKey       `json:"remote_pk"`
	Type    tptypes.Type        `json:"type"`
	Log     *transport.LogEntry `json:"log,omitempty"`
	IsSetup bool                `json:"is_setup"`
	Label   transport.Label     `json:"label"`
}

TransportSummary contains transport summary data. This mirrors visor.TransportSummary but is defined locally.

type VisorAPI

type VisorAPI interface {
	Overview() (*VisorOverview, error)
	RoutingRules() ([]routing.Rule, error)
	// AllTransports returns the network-wide all-transports JSON snapshot the
	// visor holds via its dmsg/CXO-backed transport-discovery feed — the same
	// payload TPD's HTTP /all-transports serves, but obtained over dmsg with no
	// clearnet request. Returns an error on a CXO cache miss (feed not yet
	// populated); the caller surfaces that rather than falling back to clearnet.
	AllTransports(ctx context.Context) ([]byte, error)
	AddTransport(ctx context.Context, remotePK, tpType string) (*TransportSummary, error)
	RemoveTransport(ctx context.Context, tpID string) error
	DMSGHealth(ctx context.Context, pk string) (*DMSGHealthResponse, error)
	Ping(ctx context.Context, pk string, useDMSG, localRoute bool, tries, sizeKB int) (*PingResponse, error)
	// App management
	Apps() ([]*AppState, error)
	StartApp(appName string) error
	StopApp(appName string) error
	SetAutoStart(appName string, autoStart bool) error
	SetAppPK(appName, pk string) error
	Close() error
}

VisorAPI defines the interface for accessing visor data. This is defined locally to avoid import cycles with the visor package.

type VisorOverview

type VisorOverview struct {
	PubKey      cipher.PubKey       `json:"local_pk"`
	Transports  []*TransportSummary `json:"transports"`
	RoutesCount int                 `json:"routes_count"`
}

VisorOverview contains visor overview data. This mirrors visor.Overview but is defined locally to avoid import cycles.

Directories

Path Synopsis
Package netview pkg/tpviz/netview/netview.go c3-vis-api
Package netview pkg/tpviz/netview/netview.go c3-vis-api
Package wasmgl pkg/tpviz/wasmgl/latencyoverlay.go c4-vis-latency Draws the spherical Voronoi cells over the latency view.
Package wasmgl pkg/tpviz/wasmgl/latencyoverlay.go c4-vis-latency Draws the spherical Voronoi cells over the latency view.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL