Documentation
¶
Overview ¶
Package remote implements the contract dispatcher's HTTP forwarding layer. When a contributor's handlers live in another service, the host dashboard records its RemoteEndpoint via Registry.RegisterRemote; the ForwardingDispatcher reads that endpoint at dispatch time and forwards the verbatim envelope over HTTP. Slice (m) introduced this so a single dashboard can aggregate contributors from multiple upstream services without the transport layer caring whether a handler is local or remote.
Index ¶
Constants ¶
const DefaultDispatchPath = "/_forge/contract/dispatch"
DefaultDispatchPath is appended to a RemoteEndpoint.BaseURL when forwarding a request envelope.
const DefaultManifestPath = "/_forge/contract/manifest"
DefaultManifestPath is appended to a RemoteEndpoint.BaseURL when fetching a contributor manifest during registration.
const DefaultTimeout = 10 * time.Second
DefaultTimeout is the HTTP client timeout used when RemoteEndpoint.Client is nil. Chosen to stay well below typical proxy / load-balancer idle cuts while leaving room for cold-path handlers.
Variables ¶
This section is empty.
Functions ¶
func FetchManifest ¶
func FetchManifest(ctx context.Context, baseURL, apiKey string, client *http.Client) (*contract.ContractManifest, error)
FetchManifest pulls a contributor's contract manifest from the upstream service's manifest endpoint. The caller typically follows this with Registry.RegisterRemote(manifest, RemoteEndpoint{BaseURL: baseURL, ...}).
baseURL is the service root (e.g. https://svc:8443/svc); the function appends DefaultManifestPath. apiKey, when non-empty, is sent as Authorization: Bearer. A nil client falls back to a 10s-timeout client.
On non-2xx the upstream's status + body excerpt are surfaced so config mistakes (wrong port, wrong path) are diagnosable.
Types ¶
type ForwardingDispatcher ¶
type ForwardingDispatcher struct {
// contains filtered or unexported fields
}
ForwardingDispatcher implements dispatcher.RemoteDispatcher by POSTing the verbatim contract envelope to the contributor's RemoteEndpoint.
It looks the endpoint up via Registry.Remote, so registering a contributor (Registry.RegisterRemote) and wiring this dispatcher into the dispatcher (Dispatcher.SetRemoteDispatcher) are the two halves of the integration — nothing further is needed at the transport layer.
func NewForwardingDispatcher ¶
func NewForwardingDispatcher(reg contract.Registry, opts ...Option) *ForwardingDispatcher
NewForwardingDispatcher returns a dispatcher that reads endpoints from the supplied registry. The registry is the source of truth for which contributors are remote — local contributors fall through with CodeNotFound so the host dispatcher's own NotFound handling kicks in.
func (*ForwardingDispatcher) Dispatch ¶
func (f *ForwardingDispatcher) Dispatch( ctx context.Context, req contract.Request, _ contract.Principal, ) (json.RawMessage, contract.ResponseMeta, error)
Dispatch implements dispatcher.RemoteDispatcher. Returns CodeNotFound when the contributor is not registered as a remote (the host dispatcher then surfaces its own NotFound). Network and decode failures are reported as CodeInternal; upstream-returned error envelopes are surfaced verbatim with their original code/message.
type Option ¶
type Option func(*ForwardingDispatcher)
Option configures a ForwardingDispatcher.
func WithDispatchPath ¶
WithDispatchPath overrides the path appended to a RemoteEndpoint.BaseURL when forwarding envelopes. Useful when the upstream service mounts the contract server at a non-default location.