multi

package
v0.24.1 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package multi routes N named instances of the same type behind a single .Using(name) dispatcher. The canonical case is multiple databases:

dbs := multi.New[*gorm.DB]().
    Register("main",      mainDB,  multi.AsDefault()).
    Register("questions", qbDB).
    Register("uaa",       uaaDB)

// Inside a resolver / handler:
dbs.Using("main").Find(&rows)           // explicit
dbs.Using("").Find(&rows)               // "" = default ("main" here)
dbs.Using("questions").Find(&rows)

The package is transport-agnostic: T can be *gorm.DB, *sql.DB, an HTTP client, a Redis client — anything you'd route by name. nexus uses it in examples/graphapp and you can pair it with resource.NewDatabase to show every instance on the dashboard:

dbs.Each(func(name string, db *gorm.DB) {
    app.Register(resource.NewDatabase(name, "Postgres", nil,
        func() bool { sql, _ := db.DB(); return sql.Ping() == nil }))
})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option[T any] func(*entry[T])

Option configures an entry at Register time.

func AsDefault

func AsDefault[T any]() Option[T]

AsDefault marks this instance as the one returned for .Using("") and .Default(). If multiple entries are marked, the first wins. If none is marked, the first Register call sets the default implicitly.

type Registry

type Registry[T any] struct {
	// contains filtered or unexported fields
}

Registry is the dispatcher. Thread-safe for concurrent Register and Using.

func New

func New[T any]() *Registry[T]

New returns an empty Registry. Type parameter T is the instance type.

func (*Registry[T]) Default

func (r *Registry[T]) Default() T

Default is shorthand for Using("").

func (*Registry[T]) DefaultName

func (r *Registry[T]) DefaultName() string

DefaultName returns the name currently marked default, or "" if empty.

func (*Registry[T]) Each

func (r *Registry[T]) Each(fn func(name string, v T))

Each invokes fn(name, instance) for every registered entry, in lexical order. fn must not call back into the Registry's mutating methods — doing so deadlocks. For registration-side work, copy the names via Names() first.

func (*Registry[T]) Has

func (r *Registry[T]) Has(name string) bool

Has reports whether an instance is registered under name. Empty string checks for a default.

func (*Registry[T]) Len

func (r *Registry[T]) Len() int

Len returns the number of registered instances.

func (*Registry[T]) Names

func (r *Registry[T]) Names() []string

Names returns the registered names in lexical order. Useful for iterating to register each instance as a nexus.Resource or for health dashboards.

func (*Registry[T]) OnUse

func (r *Registry[T]) OnUse(h func(ctx context.Context, name string))

OnUse installs a callback fired every time UsingCtx is called. nexus uses this to auto-attach service→resource edges on the dashboard — the hook receives the caller's context.Context, and whatever the integrator reads out of it (e.g. trace.SpanFromCtx → service name) decides attribution.

Setting the hook is idempotent — a second OnUse call replaces the first. Returns no value so the method satisfies a structural interface for the hook-installer side (nexus.UseReporter), at the cost of not chaining.

func (*Registry[T]) Register

func (r *Registry[T]) Register(name string, v T, opts ...Option[T]) *Registry[T]

Register stores v under name. Calling Register with an existing name overwrites the entry. Returns the Registry so calls chain.

func (*Registry[T]) SetDefault

func (r *Registry[T]) SetDefault(name string) *Registry[T]

SetDefault explicitly marks an already-registered name as the default. Panics if the name isn't registered — that's a programmer bug.

func (*Registry[T]) Using

func (r *Registry[T]) Using(name string) T

Using returns the instance registered under name. An empty string resolves to the default. Returns the zero value of T when the name isn't known — rather than panicking — so optional lookups can chain .Has() first.

func (*Registry[T]) UsingCtx

func (r *Registry[T]) UsingCtx(ctx context.Context, name string) T

UsingCtx is Using with a context. When a hook is installed via OnUse, it fires before the lookup; otherwise this is exactly Using(name). Context-aware code paths (GraphQL resolvers, HTTP handlers) should prefer UsingCtx so dashboards can correlate lookups with the current request.

Jump to

Keyboard shortcuts

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