Documentation
¶
Overview ¶
Package cloudrpc lets a caller reach this cluster's RPC server through Miren Cloud, over the same uplink the cluster already holds open.
It exists because the direct path assumes something that often is not true: that whoever wants to run `miren app list` can open a connection to the cluster. A cluster behind NAT can accept nothing, yet it is already talking to cloud. This turns that outbound link into a way in.
The cluster is a tenant of pkg/uplink here, in the same way Miren Anywhere is: it registers handlers and owns none of the link's lifecycle. What rides on top is pkg/rpc's message transport, which runs the whole RPC protocol over any pipe of discrete byte messages — see pkg/rpc/PROTOCOL.md. The uplink is such a pipe once its envelopes are unwrapped, so the frames go through untouched and cloud never parses one.
Authentication is unchanged by the detour, which is the point. Each operation still carries the caller's own bearer token, and this cluster's authenticator and RBAC judge it exactly as they would on a direct connection. Cloud authorizes the connection it is relaying and vouches for nothing beyond that.
Index ¶
Constants ¶
const ( TypeOpen = "rpc.open" TypeData = "rpc.data" TypeClose = "rpc.close" )
Control messages for a relayed RPC session, namespaced as their own family so the uplink stays a shared pipe. Cloud opens a session; either side may send data or close it.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Uplink is the control-plane link. The Server registers handlers on it but
// does not own its lifecycle; whoever created the link runs it.
Uplink Link
// State is the RPC state whose exposed objects relayed callers reach. It is
// the same one the cluster serves directly, deliberately: a call arriving
// this way must reach the same objects, under the same authorization, as one
// that arrived over the network.
State *rpc.State
Log *slog.Logger
}
Config wires a Server to the link it rides and the RPC server it exposes.
type Data ¶
Data carries one message of the session's byte pipe.
Payload is []byte rather than a string so encoding/json base64s it: the uplink's envelopes are JSON, and these frames are CBOR. The cost is the usual third again in size, which is why the session caps its frames well under the uplink's read limit.
type Link ¶
type Link interface {
OfferCapability(offer uplink.CapabilityOffer)
Handle(msgType string, handler uplink.MessageHandler)
SendContext(ctx context.Context, env *uplink.Envelope) error
Send(env *uplink.Envelope)
}
Link is the part of the control-plane link this package uses. *uplink.Client is the implementation; naming the methods keeps the dependency honest and lets the relay be exercised without a socket.
Both sends are here because the choice between them is not a preference. A session's frames cannot be lost, so they wait for room. Anything sent from a message handler cannot wait, because handlers run on the link's read loop and every other tenant is queued behind them — so those go best-effort or not at all.