Documentation ¶
Overview ¶
Package rpc defines interfaces for communication via remote procedure call.
Concept: https://vanadium.github.io/concepts/rpc.html Tutorial: (forthcoming)
There are two actors in the system, clients and servers. Clients invoke methods on Servers, using the StartCall method provided by the Client interface. Servers implement methods on named objects. The named object is found using a Dispatcher, and the method is invoked using an Invoker.
Instances of the Runtime host Clients and Servers, such instances may simultaneously host both Clients and Servers. The Runtime allows multiple names to be simultaneously supported via the Dispatcher interface.
The naming package provides a rendezvous mechanism for Clients and Servers. In particular, it allows Runtimes hosting Servers to share Endpoints with Clients that enables communication between them. Endpoints encode sufficient addressing information to enable communication.
Index ¶
- Constants
- func PublisherNames(e []PublisherEntry) []string
- func PublisherServers(e []PublisherEntry) []string
- func TypeCheckMethods(obj interface{}) map[string]error
- type AddressChooser
- type AddressChooserFunc
- type AllGlobber
- type ArgDesc
- type CallOpt
- type ChildrenGlobber
- type Client
- type ClientCall
- type ClientOpt
- type Describer
- type Dispatcher
- type EmbedDesc
- type GlobChildrenServerCall
- type GlobServerCall
- type GlobState
- type Globber
- type Granter
- type InterfaceDesc
- type Invoker
- type ListenAddrs
- type ListenSpec
- type MethodDesc
- type ProxyPolicy
- type PublisherEntry
- type PublisherState
- type Request
- type Response
- type Server
- type ServerCall
- type ServerOpt
- type ServerState
- type ServerStatus
- type Stream
- type StreamServerCall
Constants ¶
const GlobMethod = "__Glob"
TODO(toddw): Rename GlobMethod to ReservedGlob.
const ReservedMethodSignature = "__MethodSignature"
const ReservedSignature = "__Signature"
Variables ¶
This section is empty.
Functions ¶
func PublisherNames ¶
func PublisherNames(e []PublisherEntry) []string
PublisherNames returns the current set of names being published by the publisher. These names are not rooted at the mounttable.
func PublisherServers ¶
func PublisherServers(e []PublisherEntry) []string
PublisherServers returns the current set of server addresses being published by the publisher.
func TypeCheckMethods ¶
TypeCheckMethods type checks each method in obj, and returns a map from method name to the type check result. Nil errors indicate the method is invocable by the Invoker returned by ReflectInvoker(obj). Non-nil errors contain details of the type mismatch - any error with the "Aborted" id will cause a panic in a ReflectInvoker() call.
This is useful for debugging why a particular method isn't available via ReflectInvoker.
Types ¶
type AddressChooser ¶
type AddressChooser interface {
ChooseAddresses(protocol string, candidates []net.Addr) ([]net.Addr, error)
}
AddressChooser determines the preferred addresses to publish into the mount table when one is not otherwise specified.
type AddressChooserFunc ¶
AddressChooserFunc is a convenience for implementations that wish to supply a function literal implementation of AddressChooser.
func (AddressChooserFunc) ChooseAddresses ¶
type AllGlobber ¶
type AllGlobber interface { // Glob__ returns a GlobReply for the objects that match the given // glob pattern in the namespace below the receiver object. All the // names returned are relative to the receiver. Glob__(ctx *context.T, call GlobServerCall, g *glob.Glob) error }
AllGlobber is a powerful interface that allows the object to enumerate the the entire namespace below the receiver object. Every object that implements it must be able to handle glob requests that could match any object below itself. E.g. "a/b".Glob__("*/*"), "a/b".Glob__("c/..."), etc.
type ArgDesc ¶
ArgDesc describes an argument; it is similar to signature.Arg, without the information that can be obtained via reflection.
type CallOpt ¶
type CallOpt interface {
RPCCallOpt()
}
CallOpt is the interface for all Call options.
type ChildrenGlobber ¶
type ChildrenGlobber interface { // GlobChildren__ returns a GlobChildrenReply for the receiver's // immediate children that match the glob pattern element. // It should return an error if the receiver doesn't exist. GlobChildren__(ctx *context.T, call GlobChildrenServerCall, matcher *glob.Element) error }
ChildrenGlobber allows the object to enumerate the namespace immediately below the receiver object.
type Client ¶
type Client interface { // StartCall starts an asynchronous call of the method on the server instance // identified by name, with the given input args (of any arity). The returned // Call object manages streaming args and results, and finishes the call. // // StartCall accepts at least the following options: // v.io/v23/options.ChannelTimeout, v.io/v23/options.NoRetry. StartCall(ctx *context.T, name, method string, args []interface{}, opts ...CallOpt) (ClientCall, error) // Call makes a synchronous call that will retry application level // verrors that have verror.ActionCode RetryBackoff. Call(ctx *context.T, name, method string, inArgs, outArgs []interface{}, opts ...CallOpt) error // PinConnection returns a flow.PinnedConn to the remote end if it is successful // connecting to it within the context’s timeout, or if the connection is // already in the cache. // Connection related opts passed to PinConnection are valid until the // PinnedConn.Unpin() is called. PinConnection(ctx *context.T, name string, opts ...CallOpt) (flow.PinnedConn, error) // Close discards all state associated with this Client. In-flight calls may // be terminated with an error. // TODO(mattr): This method is deprecated with the new RPC system. Close() // Closed returns a channel that will be closed after the client is shut down. Closed() <-chan struct{} }
Client represents the interface for making RPC calls. There may be multiple outstanding Calls associated with a single Client, and a Client may be used by multiple goroutines concurrently.
type ClientCall ¶
type ClientCall interface { Stream // CloseSend indicates to the server that no more items will be sent; server // Recv calls will receive io.EOF after all items are sent. Subsequent calls to // Send on the client will fail. This is an optional call - it is used by // streaming clients that need the server to receive the io.EOF terminator. CloseSend() error // Finish blocks until the server has finished the call, and fills resultptrs // with the positional output results (of any arity). Finish(resultptrs ...interface{}) error // RemoteBlesesings returns the blessings that the server provided to authenticate // with the client. // // It returns both the string blessings and a handle to the object that contains // cryptographic proof of the validity of those blessings. // // TODO(ashankar): Make this RemoteBlessingNames and remove the second result // since that is the same as ClientCall.Security().RemoteBlessings() RemoteBlessings() ([]string, security.Blessings) // Security returns the security-related state associated with the call. Security() security.Call }
Call defines the interface for each in-flight call on the client. Finish must be called to finish the call; all other methods are optional.
type ClientOpt ¶
type ClientOpt interface {
RPCClientOpt()
}
ClientOpt is the interface for all Client options.
type Describer ¶
type Describer interface { // Describe the underlying object. The implementation must be idempotent // across different instances of the same underlying type; the ReflectInvoker // calls this once per type and caches the results. Describe__() []InterfaceDesc }
Describer may be implemented by an underlying object served by the ReflectInvoker, in order to describe the interfaces that the object implements. This describes all data in signature.Interface that the ReflectInvoker cannot obtain through reflection; basically everything except the method names and types.
Note that a single object may implement multiple interfaces; to describe such an object, simply return more than one elem in the returned list.
type Dispatcher ¶
type Dispatcher interface { // Lookup returns the service implementation for the object identified // by the given suffix. // // Reflection is used to match requests to the service object's method // set. As a special-case, if the object returned by Lookup implements // the Invoker interface, the Invoker is used to invoke methods // directly, without reflection. // // Returning a nil object indicates that this Dispatcher does not // support the requested suffix. // // An Authorizer is also returned to allow control over authorization // checks. Returning a nil Authorizer indicates the default // authorization checks should be used. // // Returning any non-nil error indicates the dispatch lookup has failed. // The error will be delivered back to the client. // // Lookup may be called concurrently by the underlying RPC system, and // hence must be thread-safe. Lookup(ctx *context.T, suffix string) (interface{}, security.Authorizer, error) }
Dispatcher defines the interface that a server must implement to handle method invocations on named objects.
type EmbedDesc ¶
EmbedDesc describes an embedded interface; it is similar to signature.Embed, without the information that can be obtained via reflection.
type GlobChildrenServerCall ¶
type GlobChildrenServerCall interface { SendStream() interface { Send(reply naming.GlobChildrenReply) error } ServerCall }
GlobChildrenServerCall defines the in-flight context for a GlobChildren__ call, including the method to stream the results.
type GlobServerCall ¶
type GlobServerCall interface { SendStream() interface { Send(reply naming.GlobReply) error } ServerCall }
GlobServerCall defines the in-flight context for a Glob__ call, including the method to stream the results.
type GlobState ¶
type GlobState struct { AllGlobber AllGlobber ChildrenGlobber ChildrenGlobber }
GlobState indicates which Glob interface the object implements.
func NewGlobState ¶
func NewGlobState(obj interface{}) *GlobState
NewGlobState returns the GlobState corresponding to obj. Returns nil if obj doesn't implement AllGlobber or ChildrenGlobber.
type Globber ¶
type Globber interface { // Globber returns a GlobState with references to the interface that the // object implements. Only one implementation is needed to participate // in the namespace. Globber() *GlobState }
Globber allows objects to take part in the namespace. Service objects may choose to implement either the AllGlobber interface, or the ChildrenGlobber interface.
The AllGlobber interface lets the object handle complex glob requests for the entire namespace below the receiver object, i.e. "a/b".Glob__("...") must return the name of all the objects under "a/b".
The ChildrenGlobber interface is simpler. Each object only has to return a list of the objects immediately below itself in the namespace graph.
type Granter ¶
type Granter interface { Grant(ctx *context.T, call security.Call) (security.Blessings, error) CallOpt }
Granter is a ClientCallOpt that is used to provide blessings to the server when making an RPC.
It gets passed a context.T with parameters of the RPC call set on it.
type InterfaceDesc ¶
type InterfaceDesc struct { Name string PkgPath string Doc string Embeds []EmbedDesc Methods []MethodDesc }
InterfaceDesc describes an interface; it is similar to signature.Interface, without the information that can be obtained via reflection.
type Invoker ¶
type Invoker interface { // Prepare is the first stage of method invocation, based on the given method // name. The given numArgs specifies the number of input arguments sent by // the client, which may be used to support method overloading or generic // processing. // // Returns argptrs which will be filled in by the caller; e.g. the server // framework calls Prepare, and decodes the input arguments sent by the client // into argptrs. // // If the Invoker has access to the underlying Go values, it should return // argptrs containing pointers to the Go values that will receive the // arguments. This is the typical case, e.g. the ReflectInvoker. // // If the Invoker doesn't have access to the underlying Go values, but knows // the expected types, it should return argptrs containing *vdl.Value objects // initialized to each expected type. For purely generic decoding each // *vdl.Value may be initialized to vdl.AnyType. // // The returned method tags provide additional information associated with the // method. E.g. the security system uses tags to configure AccessLists. The tags // are typically configured in the VDL specification of the method. Prepare(ctx *context.T, method string, numArgs int) (argptrs []interface{}, tags []*vdl.Value, _ error) // Invoke is the second stage of method invocation. It is passed the // in-flight context and call, the method name, and the argptrs returned by // Prepare, filled in with decoded arguments. It returns the results from the // invocation, and any errors in invoking the method. // // Note that argptrs is a slice of pointers to the argument objects; each // pointer must be dereferenced to obtain the actual argument value. Invoke(ctx *context.T, call StreamServerCall, method string, argptrs []interface{}) (results []interface{}, _ error) // Signature corresponds to the reserved __Signature method; it returns the // signatures of the interfaces the underlying object implements. Signature(ctx *context.T, call ServerCall) ([]signature.Interface, error) // MethodSignature corresponds to the reserved __MethodSignature method; it // returns the signature of the given method. MethodSignature(ctx *context.T, call ServerCall, method string) (signature.Method, error) // Globber allows objects to take part in the namespace. Globber }
Invoker defines the interface used by the server for invoking methods on named objects. Typically ReflectInvoker(object) is used, which makes all exported methods on the given object invocable.
Advanced users may implement this interface themselves for finer-grained control. E.g. an RPC gateway that enables bindings for other languages (like javascript) may use this interface to support serving methods without an explicit intermediate object.
func ChildrenGlobberInvoker ¶
ChildrenGlobberInvoker returns an Invoker for an object that implements the ChildrenGlobber interface, and nothing else.
func ReflectInvoker ¶
ReflectInvoker returns an Invoker implementation that uses reflection to make each compatible exported method in obj available. E.g.:
type impl struct{} func (impl) NonStreaming(ctx *context.T, call rpc.ServerCall, ...) (...) func (impl) Streaming(ctx *context.T, call *MyCall, ...) (...)
The first in-arg must be context.T. The second in-arg must be a call; for non-streaming methods it must be rpc.ServerCall, and for streaming methods it must be a pointer to a struct that implements rpc.StreamServerCall, and also adds typesafe streaming wrappers. Here's an example that streams int32 from client to server, and string from server to client:
type MyCall struct { rpc.StreamServerCall } // Init initializes MyCall via rpc.StreamServerCall. func (*MyCall) Init(rpc.StreamServerCall) {...} // RecvStream returns the receiver side of the server stream. func (*MyCall) RecvStream() interface { Advance() bool Value() int32 Err() error } {...} // SendStream returns the sender side of the server stream. func (*MyCall) SendStream() interface { Send(item string) error } {...}
We require the streaming call arg to have this structure so that we can capture the streaming in and out arg types via reflection. We require it to be a concrete type with an Init func so that we can create new instances, also via reflection.
As a temporary special-case, we also allow generic streaming methods:
func (impl) Generic(ctx *context.T, call rpc.StreamServerCall, ...) (...)
The problem with allowing this form is that via reflection we can no longer determine whether the server performs streaming, or what the streaming in and out types are. TODO(toddw): Remove this special-case.
The ReflectInvoker silently ignores unexported methods, and exported methods whose first argument doesn't implement rpc.ServerCall. All other methods must follow the above rules; bad method types cause an error to be returned.
If obj implements the Describer interface, we'll use it to describe portions of the object signature that cannot be retrieved via reflection; e.g. method tags, documentation, variable names, etc.
func ReflectInvokerOrDie ¶
func ReflectInvokerOrDie(obj interface{}) Invoker
ReflectInvokerOrDie is the same as ReflectInvoker, but panics on all errors.
type ListenAddrs ¶
type ListenAddrs []struct { Protocol, Address string }
ListenAddrs is the set of protocol, address pairs to listen on. An anonymous struct is used to more easily initialize a ListenSpec from a different package.
For TCP, the address must be in <ip>:<port> format. The <ip> may be omitted, but the <port> cannot. Use port 0 to have the system allocate one for you.
type ListenSpec ¶
type ListenSpec struct { // The addresses to listen on. Addrs ListenAddrs // The name of a proxy to be used to proxy connections to this listener. Proxy string // The policy to use when selecting from multiple proxies. ProxyPolicy ProxyPolicy // ProxyLimit sets a limit on the number of proxies to be used when the // ProxyPolicy is UseAllProxies. 0 implies no limit, ie. all available // proxies are used. ProxyLimit int // The address chooser to use for determining preferred publishing // addresses. AddressChooser }
ListenSpec specifies the information required to create a set of listening network endpoints for a server and, optionally, the name of a proxy to use in conjunction with that listener.
func (ListenSpec) Copy ¶
func (l ListenSpec) Copy() ListenSpec
Copy clones a ListenSpec. The cloned spec has its own copy of the array of addresses to listen on.
func (ListenSpec) String ¶
func (l ListenSpec) String() string
type MethodDesc ¶
type MethodDesc struct { Name string Doc string InArgs []ArgDesc // Input arguments OutArgs []ArgDesc // Output arguments InStream ArgDesc // Input stream (client to server) OutStream ArgDesc // Output stream (server to client) Tags []*vdl.Value // Method tags }
MethodDesc describes an interface method; it is similar to signature.Method, without the information that can be obtained via reflection.
type ProxyPolicy ¶ added in v0.1.10
type ProxyPolicy int
ProxyPolicy determines how a server will chose an rpc proxy when multiple are available, that is when multiple proxy instances are mounted under the same name.
const ( // UseFirstProxy will use the first proxy addresse found in the set returned // by the mounttable. UseFirstProxy ProxyPolicy = iota // UseRandomProxy will randomly select from proxy addresses returned by // the mounttable. UseRandomProxy // UseAllProxies will simultaneously use all of the proxies returned by the // mounttable or up the number specified by ProxyLimit. UseAllProxies )
func (ProxyPolicy) String ¶ added in v0.1.10
func (pp ProxyPolicy) String() string
String implements fmt.Stringer.
type PublisherEntry ¶
type PublisherEntry struct {
// The Name and Server 'address' of this mount table request.
Name, Server string
// LastMount records the time of the last attempted mount request.
LastMount time.Time
// LastMountErr records any error reported by the last attempted mount.
LastMountErr error
// TTL is the TTL supplied for the last mount request.
TTL time.Duration
// LastUnmount records the time of the last attempted unmount request.
LastUnmount time.Time
// LastUnmountErr records any error reported by the last attempted unmount.
LastUnmountErr error
// LastState is the last known publisher state of the entry.
LastState PublisherState
// DesiredState is the current desired state of the entry.
// This will be either PublisherMounted or PublisherUnmounted.
DesiredState PublisherState
}
PublisherEntry contains the status of a given mount operation.
func (PublisherEntry) String ¶
func (e PublisherEntry) String() string
type PublisherState ¶
type PublisherState int
PublisherState indicates the state of a PublisherEntry.
const ( // PublisherUnmounted indicates that the PublisherEntry is not mounted. PublisherUnmounted PublisherState = iota // PublisherMounting indicates that the PublisherEntry is in the process of mounting. PublisherMounting // PublisherMounted indicates that the PublisherEntry is mounted. PublisherMounted // PublisherUnmounting indicates that the PublisherEntry is in the process of unmounting. PublisherUnmounting )
func (PublisherState) String ¶
func (s PublisherState) String() string
String returns a string representation of the PublisherState.
type Request ¶
type Request struct { // Suffix of the name used to identify the object hosting the service. Suffix string // Method to invoke on the service. Method string // NumPosArgs is the number of positional arguments, which follow this message // (and any blessings) on the request stream. NumPosArgs uint64 // EndStreamArgs is true iff no more streaming arguments will be sent. No // more data will be sent on the request stream. // // NOTE(bprosnitz): We can support multiple stream values per request (+response) header // efficiently by adding a NumExtraStreamArgs (+NumExtraStreamResults to response) field // that is the uint64 (number of stream args to send) - 1. The request is then zero when // exactly one streaming arg is sent. Since the request and response headers are small, // this is only likely necessary for frequently streaming small values. // See implementation in CL: 3913 EndStreamArgs bool // Deadline after which the request should be cancelled. This is a hint to // the server, to avoid wasted work. Deadline vdltime.Deadline // GrantedBlessings are blessings bound to the principal running the server, // provided by the client. GrantedBlessings security.Blessings // TraceRequest maintains the vtrace context between clients and servers // and specifies additional parameters that control how tracing behaves. TraceRequest vtrace.Request // Language indicates the language of the instegator of the RPC. // By convention it should be an IETF language tag: // http://en.wikipedia.org/wiki/IETF_language_tag Language string }
Request describes the request header sent by the client to the server. A non-zero request header is sent at the beginning of the RPC call, followed by the positional args. Thereafter a zero request header is sent before each streaming arg, terminated by a non-zero request header with EndStreamArgs set to true.
func (Request) VDLReflect ¶
type Response ¶
type Response struct { // Error in processing the RPC at the server. Implies EndStreamResults. Error error // EndStreamResults is true iff no more streaming results will be sent; the // remainder of the stream consists of NumPosResults positional results. EndStreamResults bool // NumPosResults is the number of positional results, which immediately follow // on the response stream. After these results, no further data will be sent // on the response stream. NumPosResults uint64 // TraceResponse maintains the vtrace context between clients and servers. // In some cases trace data will be included in this response as well. TraceResponse vtrace.Response // AckBlessings is true if the server successfully recevied the client's // blessings and stored them in the server's blessings cache. AckBlessings bool }
Response describes the response header sent by the server to the client. A zero response header is sent before each streaming arg. Thereafter a non-zero response header is sent at the end of the RPC call, right before the positional results.
func (Response) VDLReflect ¶
type Server ¶
type Server interface { // AddName adds the specified name to the mount table for this server. // AddName may be called multiple times. AddName(name string) error // RemoveName removes the specified name from the mount table. RemoveName may // be called multiple times. RemoveName(name string) // Status returns the current status of the server, see ServerStatus for // details. Status() ServerStatus // Closed returns a channel that will be closed after the server is shut down. Closed() <-chan struct{} }
Server defines the interface for managing a server that receives RPC calls.
type ServerCall ¶
type ServerCall interface { // Security returns the security-related state associated with the call. Security() security.Call // Suffix returns the object name suffix for the request. Suffix() string // LocalEndpoint returns the Endpoint at the local end of // communication. LocalEndpoint() naming.Endpoint // RemoteEndpoint returns the Endpoint at the remote end of // communication. RemoteEndpoint() naming.Endpoint // RemoteAddr returns the net address of the peer. RemoteAddr() net.Addr // GrantedBlessings are blessings granted by the client to the server // (bound to the server). Typically provided by a client to delegate // to the server, allowing the server to use the client's authority to // pursue some task. // // Can be nil, indicating that the client did not delegate any // authority to the server for this request. // // This is distinct from the blessings used by the client and // server to authenticate with each other (RemoteBlessings // and LocalBlessings respectively). GrantedBlessings() security.Blessings // Server returns the Server that this context is associated with. Server() Server }
ServerCall defines the in-flight context for a server method call, not including methods to stream args and results.
type ServerOpt ¶
type ServerOpt interface {
RPCServerOpt()
}
ServerOpt is the interface for all Server options.
type ServerState ¶
type ServerState int
ServerState represents the 'state' of the Server.
const ( // ServerActive indicates that the server is 'active'. ServerActive ServerState = iota // ServerStopping indicates that the server has been asked to stop and is // in the process of doing so. It may take a while for the server to // complete this process since it will wait for outstanding operations // to complete gracefully. ServerStopping // ServerStopped indicates that the server has stopped. It can no longer be // used. ServerStopped )
func (ServerState) String ¶
func (i ServerState) String() string
type ServerStatus ¶
type ServerStatus struct { // The current state of the server. State ServerState // ServesMountTable is true if this server serves a mount table. ServesMountTable bool // PublisherStatus returns the status of the last mount or unmount // operation for every combination of name and server address being // published by this Server. PublisherStatus []PublisherEntry // Endpoints contains the set of endpoints currently registered with the // mount table for the names published using this server including all // proxied addresses. Endpoints []naming.Endpoint // ListenErrors contains the set of errors encountered when listening on // the network. Entries are keyed by the protocol, address specified in // the ListenSpec. ListenErrors map[struct{ Protocol, Address string }]error // ProxyErrors contains the set of errors encountered when listening on // proxies. Entries are keyed by the name of the proxy specified in the // ListenSpec. ProxyErrors map[string]error // Dirty will be closed if a status change occurs. Callers should // requery server.Status() to get the fresh server status. Dirty <-chan struct{} }
type Stream ¶
type Stream interface { // Send places the item onto the output stream, blocking if there is no buffer // space available. Send(item interface{}) error // Recv fills itemptr with the next item in the input stream, blocking until // an item is available. Returns io.EOF to indicate graceful end of input. Recv(itemptr interface{}) error }
Stream defines the interface for a bidirectional FIFO stream of typed values.
type StreamServerCall ¶
type StreamServerCall interface { Stream ServerCall }
StreamServerCall defines the in-flight context for a server method call, including methods to stream args and results.
Directories ¶
Path | Synopsis |
---|---|
Package reserved implements client-side support for reserved RPC methods implemented by all servers.
|
Package reserved implements client-side support for reserved RPC methods implemented by all servers. |
Package version defines a mechanism for versioning the RPC protocol.
|
Package version defines a mechanism for versioning the RPC protocol. |