Files
mesh-host/internal/link/hearing.go
T

60 lines
2.2 KiB
Go

package link
import (
"context"
"fmt"
"time"
)
// What a host hears, as the host's own words for it.
//
// The outbound half is behind `Bus` (bus.go); this is the other half — dialling, and what the controller asks of this
// node. A node hears no declaration: it follows its wants (novox/hq ADR 0539).
//
// **The host still imports nothing of the mesh's own** (novox/hq ADR 0005). This is its own
// interface over its own libraries, and it agrees with the controller only because a conformance
// fixture holds both to one envelope.
// Link is this node's live connection to its mesh: what it hears, and what it says.
//
// One interface rather than two, because dialling once is what keeps both halves of a node on the
// same connection.
type Link interface {
// Bus is what this node says: its facts, and that it is here.
Bus
// Lost says the link ended, and why.
//
// **Read rather than discovered.** A node that finds out by noticing silence is a node that
// believed it was in the mesh for as long as the silence lasted, which is the one state ADR
// 0004 says must never look like being connected.
Lost() <-chan error
// Close lets go of whatever was dialled.
Close()
}
// Asked is a link that hears the mesh asking this node to say its facts again. Optional: a link without it is never
// asked.
type Asked interface {
AskedToReport() <-chan struct{}
}
// Open opens this node's link to its mesh.
//
// Named Open rather than Dial because Dial is this package's raw TLS dial, which the enrolment path
// uses to see a certificate before it trusts anything.
//
// **The mesh has one bus** (novox/hq ADR 0131): the one the broker seat delivers. A membership
// still records which transport it was minted for, so a host can say what it is dialling, and a
// membership recorded for anything else is a membership this host cannot use.
func Open(ctx context.Context, m Membership, timeout time.Duration) (Link, error) {
if m.Transport != OnNATS {
return nil, fmt.Errorf("this membership is for %q, and the mesh's bus is %s", m.Transport, OnNATS)
}
return dialNats(ctx, m, timeout)
}
// OnNATS is the bus a membership names: the mesh's own, and the only one.
const OnNATS = "nats"