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

arpreview

package
v1.3.97 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package arpreview pkg/deployment/ar/arpreview/arpreview.go c4-net-discovery

Preview-backed reads of the address resolver's CXO bindings feed: resolve one peer's transport addresses over an already-open CXO connection, holding nothing afterwards.

This is the consumer half of #4584. The AR's own feed (pkg/deployment/ar/api/cxo_publisher.go) publishes a dense 256-bucket level keyed by peer public key, which lets a lookup here be a FIXED walk — root TreeNode, then one indexed child fetch — regardless of how many peers the network holds. The reader never subscribes, so it costs no resident copy and no cold first sync.

It lives outside pkg/transport/network/addrresolver on purpose. The AR client is imported by pkg/cxo (through arfeed's VisorData), so it can never import CXO itself; the visor imports both and wires this in. Same dependency inversion as dmsg's EntryResolver seam.

Positioning: this is a FAST PATH, never an authority. Any miss, any error, any budget exhaustion returns "I don't know" and the caller falls through to the authenticated HTTP GET /resolve, which remains the source of truth. The feed lags the store by the publisher's flush plus batch window, so a binding created seconds ago may not be here yet — which is exactly why a miss must be cheap and must fall through rather than being cached as a negative.

Who should use this, measured

Over the live dmsg network against a 1711-peer feed, 40 lookups: this path runs at a p50 of 16.4 ms holding nothing, where the authenticated HTTP /resolve it fronts runs at 140.3 ms, and a warm subscription to the same feed answers in 119 us for 100 KB resident and a 0.8 s cold sync.

So it is the right tool for a caller that cannot hold the feed — a browser tab, a microcontroller, a short-lived CLI run, anything resolving a handful of peers — and the WRONG tool for a long-running visor that dials constantly and can spare 100 KB, which should subscribe instead. It is deliberately not wired into the visor dial path for that reason.

Index

Constants

View Source
const LookupTimeout = 500 * time.Millisecond

LookupTimeout is the budget a dial-path caller should give a lookup. It matches dmsg's resolverTimeout: a resolver that is cold, wedged or simply slower than the fallback must lose the race, not delay it.

Variables

View Source
var ErrNoEntry = errors.New("arpreview: no binding in the AR feed")

ErrNoEntry means the feed carried no binding of the requested type for that peer. It is deliberately the same shape of answer as a 404 from GET /resolve, but callers should treat it as "not here" and fall through rather than as a definitive absence: the feed lags the store.

Functions

This section is empty.

Types

type Config

type Config struct {
	Logger *logging.Logger
	// Port is the AR's bindings-feed dmsg port; zero means
	// skyenv.DmsgARBindingsCXOPort.
	Port uint16
	// MaxObjects bounds one lookup. A correctly-shaped bucket walk needs
	// single digits; zero takes the cxopreview default.
	MaxObjects int
}

Config tunes a Resolver.

type Resolver

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

Resolver reads one peer's bindings out of the AR's CXO feed.

func New

func New(dmsgC *dmsg.Client, sk cipher.SecKey, arPK cipher.PubKey, conf Config) (*Resolver, error)

New builds a Resolver against the address resolver at arPK. sk is the identity the reader's CXO node presents; pass the visor's own so the AR sees a known peer rather than a fresh key on every restart.

It does NOT dial. Call Connect once at setup — a lookup that has to dial first has given up the property that makes this worth doing.

func NewWithReader

func NewWithReader(reader *cxopreview.Reader, arPK cipher.PubKey, log *logging.Logger) *Resolver

NewWithReader builds a Resolver over an already-constructed preview reader. New is the normal entry point; this one exists so a caller that already owns a reader (or one running over the CXO node's native TCP transport, as the end-to-end test does) can reuse it.

func (*Resolver) Bindings

Bindings returns every binding the feed holds for pk, plus what the lookup cost. The walk is: preview the Root, read the root TreeNode, fetch the one bucket child at the index pk's own key names. Nothing else is touched and nothing is retained.

func (*Resolver) Close

func (r *Resolver) Close() error

Close releases the reader's CXO node.

func (*Resolver) Connect

func (r *Resolver) Connect(ctx context.Context) error

Connect opens the CXO connection to the address resolver, and keeps it open.

func (*Resolver) Connected

func (r *Resolver) Connected() bool

Connected reports whether the connection to the AR is up.

func (*Resolver) LastStats

func (r *Resolver) LastStats() cxopreview.Stats

LastStats reports the cost of the most recent lookup. Diagnostic only.

func (*Resolver) Reader

func (r *Resolver) Reader() *cxopreview.Reader

Reader exposes the underlying preview reader — for setup (dialing over a non-dmsg transport) and for assertions about what it is holding.

func (*Resolver) Resolve

func (r *Resolver) Resolve(ctx context.Context, tType string, pk cipher.PubKey) (addrresolver.VisorData, error)

Resolve returns one transport type's binding for pk, matching the shape of addrresolver.APIClient.Resolve so it can sit in front of it.

Jump to

Keyboard shortcuts

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