Documentation
¶
Overview ¶
Package capnp is a Cap'n Proto library for Go. https://capnproto.org/
Read the Getting Started guide for a tutorial on how to use this package. https://github.com/capnproto/go-capnproto2/wiki/Getting-Started
Generating code ¶
capnpc-go provides the compiler backend for capnp.
# First, install capnpc-go to $PATH. go install capnproto.org/go/capnp/v3/capnpc-go # Then, generate Go files. capnp compile -I$GOPATH/src/capnproto.org/go/capnp/v3/std -ogo *.capnp
capnpc-go requires two annotations for all files: package and import. package is needed to know what package to place at the head of the generated file and what identifier to use when referring to the type from another package. import should be the fully qualified import path and is used to generate import statement from other packages and to detect when two types are in the same package. For example:
using Go = import "/go.capnp"; $Go.package("main"); $Go.import("capnproto.org/go/capnp/v3/example");
For adding documentation comments to the generated code, there's the doc annotation. This annotation adds the comment to a struct, enum or field so that godoc will pick it up. For example:
struct Zdate $Go.doc("Zdate represents a calendar date") { year @0 :Int16; month @1 :UInt8; day @2 :UInt8 ; }
Messages and Segments ¶
In Cap'n Proto, the unit of communication is a message. A message consists of one or more segments -- contiguous blocks of memory. This allows large messages to be split up and loaded independently or lazily. Typically you will use one segment per message. Logically, a message is organized in a tree of objects, with the root always being a struct (as opposed to a list or primitive). Messages can be read from and written to a stream.
The Message and Segment types are the main types that application code will use from this package. The Message type has methods for marshaling and unmarshaling its segments to the wire format. If the application needs to read or write from a stream, it should use the Encoder and Decoder types.
Pointers ¶
The type for a generic reference to a Cap'n Proto object is Ptr. A Ptr can refer to a struct, a list, or an interface. Ptr, Struct, List, and Interface (the pointer types) have value semantics and refer to data in a single segment. All of the pointer types have a notion of "valid". An invalid pointer will return the default value from any accessor and panic when any setter is called.
In previous versions of this package, the Pointer interface was used instead of the Ptr struct. This interface and functions that use it are now deprecated. See https://github.com/capnproto/go-capnproto2/wiki/New-Ptr-Type for details about this API change.
Data accessors and setters (i.e. struct primitive fields and list elements) do not return errors, but pointer accessors and setters do. There are a few reasons that a read or write of a pointer can fail, but the most common are bad pointers or allocation failures. For accessors, an invalid object will be returned in case of an error.
Since Go doesn't have generics, wrapper types provide type safety on lists. This package provides lists of basic types, and capnpc-go generates list wrappers for named types. However, if you need to use deeper nesting of lists (e.g. List(List(UInt8))), you will need to use a PointerList and wrap the elements.
Structs ¶
For the following schema:
struct Foo @0x8423424e9b01c0af { num @0 :UInt32; bar @1 :Foo; }
capnpc-go will generate:
// Foo is a pointer to a Foo struct in a segment. // Member functions are provided to get/set members in the // struct. type Foo struct{ capnp.Struct } // Foo_TypeID is the unique identifier for the type Foo. // It remains the same across languages and schema changes. const Foo_TypeID = 0x8423424e9b01c0af // NewFoo creates a new orphaned Foo struct, preferring placement in // s. If there isn't enough space, then another segment in the // message will be used or allocated. You can set a field of type Foo // to this new message, but usually you will want to use the // NewBar()-style method shown below. func NewFoo(s *capnp.Segment) (Foo, error) // NewRootFoo creates a new Foo struct and sets the message's root to // it. func NewRootFoo(s *capnp.Segment) (Foo, error) // ReadRootFoo reads the message's root pointer and converts it to a // Foo struct. func ReadRootFoo(msg *capnp.Message) (Foo, error) // Num returns the value of the num field. func (s Foo) Num() uint32 // SetNum sets the value of the num field to v. func (s Foo) SetNum(v uint32) // Bar returns the value of the bar field. This can return an error // if the pointer goes beyond the segment's range, the segment fails // to load, or the pointer recursion limit has been reached. func (s Foo) Bar() (Foo, error) // HasBar reports whether the bar field was initialized (non-null). func (s Foo) HasBar() bool // SetBar sets the value of the bar field to v. func (s Foo) SetBar(v Foo) error // NewBar sets the bar field to a newly allocated Foo struct, // preferring placement in s's segment. func (s Foo) NewBar() (Foo, error) // Foo_List is a value with pointer semantics. It is created for all // structs, and is used for List(Foo) in the capnp file. type Foo_List struct{ capnp.List } // NewFoo_List creates a new orphaned List(Foo), preferring placement // in s. This can then be added to a message by using a Set function // which takes a Foo_List. sz specifies the number of elements in the // list. The list's size cannot be changed after creation. func NewFoo_List(s *capnp.Segment, sz int32) Foo_List // Len returns the number of elements in the list. func (s Foo_List) Len() int // At returns a pointer to the i'th element. If i is an invalid index, // this will return an invalid Foo (all getters will return default // values, setters will fail). func (s Foo_List) At(i int) Foo // Foo_Promise is a promise for a Foo. Methods are provided to get // promises of struct and interface fields. type Foo_Promise struct{ *capnp.Pipeline } // Get waits until the promise is resolved and returns the result. func (p Foo_Promise) Get() (Foo, error) // Bar returns a promise for that bar field. func (p Foo_Promise) Bar() Foo_Promise
Groups ¶
For each group a typedef is created with a different method set for just the groups fields:
struct Foo { group :Group { field @0 :Bool; } }
generates the following:
type Foo struct{ capnp.Struct } type Foo_group Foo func (s Foo) Group() Foo_group func (s Foo_group) Field() bool
That way the following may be used to access a field in a group:
var f Foo value := f.Group().Field()
Note that group accessors just convert the type and so have no overhead.
Unions ¶
Named unions are treated as a group with an inner unnamed union. Unnamed unions generate an enum Type_Which and a corresponding Which() function:
struct Foo { union { a @0 :Bool; b @1 :Bool; } }
generates the following:
type Foo_Which uint16 const ( Foo_Which_a Foo_Which = 0 Foo_Which_b Foo_Which = 1 ) func (s Foo) A() bool func (s Foo) B() bool func (s Foo) SetA(v bool) func (s Foo) SetB(v bool) func (s Foo) Which() Foo_Which
Which() should be checked before using the getters, and the default case must always be handled.
Setters for single values will set the union discriminator as well as set the value.
For voids in unions, there is a void setter that just sets the discriminator. For example:
struct Foo { union { a @0 :Void; b @1 :Void; } }
generates the following:
func (s Foo) SetA() // Set that we are using A func (s Foo) SetB() // Set that we are using B
Similarly, for groups in unions, there is a group setter that just sets the discriminator. This must be called before the group getter can be used to set values. For example:
struct Foo { union { a :group { v :Bool } b :group { v :Bool } } }
and in usage:
f.SetA() // Set that we are using group A f.A().SetV(true) // then we can use the group A getter to set the inner values
Enums ¶
capnpc-go generates enum values as constants. For example in the capnp file:
enum ElementSize { empty @0; bit @1; byte @2; twoBytes @3; fourBytes @4; eightBytes @5; pointer @6; inlineComposite @7; }
In the generated capnp.go file:
type ElementSize uint16 const ( ElementSize_empty ElementSize = 0 ElementSize_bit ElementSize = 1 ElementSize_byte ElementSize = 2 ElementSize_twoBytes ElementSize = 3 ElementSize_fourBytes ElementSize = 4 ElementSize_eightBytes ElementSize = 5 ElementSize_pointer ElementSize = 6 ElementSize_inlineComposite ElementSize = 7 )
In addition an enum.String() function is generated that will convert the constants to a string for debugging or logging purposes. By default, the enum name is used as the tag value, but the tags can be customized with a $Go.tag or $Go.notag annotation.
For example:
enum ElementSize { empty @0 $Go.tag("void"); bit @1 $Go.tag("1 bit"); byte @2 $Go.tag("8 bits"); inlineComposite @7 $Go.notag; }
In the generated go file:
func (c ElementSize) String() string { switch c { case ElementSize_empty: return "void" case ElementSize_bit: return "1 bit" case ElementSize_byte: return "8 bits" default: return "" } }
Interfaces ¶
capnpc-go generates type-safe Client wrappers for interfaces. For parameter lists and result lists, structs are generated as described above with the names Interface_method_Params and Interface_method_Results, unless a single struct type is used. For example, for this interface:
interface Calculator { evaluate @0 (expression :Expression) -> (value :Value); }
capnpc-go generates the following Go code (along with the structs Calculator_evaluate_Params and Calculator_evaluate_Results):
// Calculator is a client to a Calculator interface. type Calculator struct{ Client capnp.Client } // Evaluate calls `evaluate` on the client. params is called on a newly // allocated Calculator_evaluate_Params struct to fill in the parameters. func (c Calculator) Evaluate( ctx context.Context, params func(Calculator_evaluate_Params) error, opts ...capnp.CallOption) *Calculator_evaluate_Results_Promise
capnpc-go also generates code to implement the interface:
// A Calculator_Server implements the Calculator interface. type Calculator_Server interface { Evaluate(context.Context, Calculator_evaluate_Call) error } // Calculator_evaluate_Call holds the arguments for a Calculator.evaluate server call. type Calculator_evaluate_Call struct { Params Calculator_evaluate_Params Results Calculator_evaluate_Results Options capnp.CallOptions } // Calculator_ServerToClient is equivalent to calling: // NewCalculator(capnp.NewServer(Calculator_Methods(nil, s), s)) // If s does not implement the Close method, then nil is used. func Calculator_ServerToClient(s Calculator_Server) Calculator // Calculator_Methods appends methods from Calculator that call to server and // returns the methods. If methods is nil or the capacity of the underlying // slice is too small, a new slice is returned. func Calculator_Methods(methods []server.Method, s Calculator_Server) []server.Method
Since a single capability may want to implement many interfaces, you can use multiple *_Methods functions to build a single slice to send to NewServer.
An example of combining the client/server code to communicate with a locally implemented Calculator:
var srv Calculator_Server calc := Calculator_ServerToClient(srv) result := calc.Evaluate(ctx, func(params Calculator_evaluate_Params) { params.SetExpression(expr) }) val := result.Value().Get()
A note about message ordering: when implementing a server method, you are responsible for acknowledging delivery of a method call. Failure to do so can cause deadlocks. See the server.Ack function for more details.
Example ¶
// Make a brand new empty message. msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil)) // If you want runtime-type identification, this is easily obtained. Just // wrap everything in a struct that contains a single anoymous union (e.g. struct Z). // Then always set a Z as the root object in you message/first segment. // The cost of the extra word of storage is usually worth it, as // then human readable output is easily obtained via a shell command such as // // $ cat binary.cpz | capnp decode aircraft.capnp Z // // If you need to conserve space, and know your content in advance, it // isn't necessary to use an anonymous union. Just supply the type name // in place of 'Z' in the decode command above. // There can only be one root. Subsequent NewRoot* calls will set the root // pointer and orphan the previous root. z, err := air.NewRootZ(seg) if err != nil { panic(err) } // then non-root objects: aircraft, err := z.NewAircraft() if err != nil { panic(err) } b737, err := aircraft.NewB737() if err != nil { panic(err) } planebase, err := b737.NewBase() if err != nil { panic(err) } // Set primitive fields planebase.SetCanFly(true) planebase.SetName("Henrietta") planebase.SetRating(100) planebase.SetMaxSpeed(876) // km/hr // if we don't set capacity, it will get the default value, in this case 0. //planebase.SetCapacity(26020) // Liters fuel // Creating a list homes, err := planebase.NewHomes(2) if err != nil { panic(err) } homes.Set(0, air.Airport_jfk) homes.Set(1, air.Airport_lax) // Ready to write! // You can write to memory... buf, err := msg.Marshal() if err != nil { panic(err) } _ = buf // ... or write to an io.Writer. file, err := ioutil.TempFile("", "go-capnproto") if err != nil { panic(err) } defer file.Close() defer os.Remove(file.Name()) err = capnp.NewEncoder(file).Encode(msg) if err != nil { panic(err) }
Output:
Index ¶
- func Canonicalize(s Struct) ([]byte, error)
- func Disconnected(s string) error
- func Equal(p1, p2 Ptr) (bool, error)
- func IsDisconnected(e error) bool
- func IsUnimplemented(e error) bool
- func NewMessage(arena Arena) (msg *Message, first *Segment, err error)
- func NewPromisedClient(hook ClientHook) (*Client, *ClientPromise)
- func SamePtr(p, q Ptr) bool
- func SetClientLeakFunc(f func(msg string))
- func Unimplemented(s string) error
- type Answer
- func (ans *Answer) Client() *Client
- func (ans *Answer) Done() <-chan struct{}
- func (ans *Answer) Field(off uint16, def []byte) *Future
- func (ans *Answer) Future() *Future
- func (ans *Answer) PipelineRecv(ctx context.Context, transform []PipelineOp, r Recv) PipelineCaller
- func (ans *Answer) PipelineSend(ctx context.Context, transform []PipelineOp, s Send) (*Answer, ReleaseFunc)
- func (ans *Answer) Struct() (Struct, error)
- type Arena
- type BitList
- type BitOffset
- type Brand
- type CapabilityID
- type Client
- func (c *Client) AddRef() *Client
- func (c *Client) IsSame(c2 *Client) bool
- func (c *Client) IsValid() bool
- func (c *Client) RecvCall(ctx context.Context, r Recv) PipelineCaller
- func (c *Client) Release()
- func (c *Client) Resolve(ctx context.Context) error
- func (c *Client) SendCall(ctx context.Context, s Send) (*Answer, ReleaseFunc)
- func (c *Client) State() ClientState
- func (c *Client) String() string
- func (c *Client) WeakRef() *WeakClient
- type ClientHook
- type ClientPromise
- type ClientState
- type DataList
- type DataOffset
- type Decoder
- type Encoder
- type Float32List
- type Float64List
- type Future
- type Int16List
- type Int32List
- type Int64List
- type Int8List
- type Interface
- type List
- type Message
- func (m *Message) AddCap(c *Client) CapabilityID
- func (m *Message) Marshal() ([]byte, error)
- func (m *Message) MarshalPacked() ([]byte, error)
- func (m *Message) NumSegments() int64
- func (m *Message) Reset(arena Arena)
- func (m *Message) ResetReadLimit(limit uint64)
- func (m *Message) Root() (Ptr, error)
- func (m *Message) Segment(id SegmentID) (*Segment, error)
- func (m *Message) SetRoot(p Ptr) error
- func (m *Message) Unread(sz Size)
- type Method
- type ObjectSize
- type PipelineCaller
- type PipelineOp
- type PointerList
- type Promise
- type Ptr
- func (p Ptr) Data() []byte
- func (p Ptr) DataDefault(def []byte) []byte
- func (p Ptr) Default(def []byte) (Ptr, error)
- func (p Ptr) Interface() Interface
- func (p Ptr) IsValid() bool
- func (p Ptr) List() List
- func (p Ptr) ListDefault(def []byte) (List, error)
- func (p Ptr) Message() *Message
- func (p Ptr) Segment() *Segment
- func (p Ptr) Struct() Struct
- func (p Ptr) StructDefault(def []byte) (Struct, error)
- func (p Ptr) Text() string
- func (p Ptr) TextBytes() []byte
- func (p Ptr) TextBytesDefault(def string) []byte
- func (p Ptr) TextDefault(def string) string
- type Recv
- type ReleaseFunc
- type Returner
- type Segment
- type SegmentID
- type Send
- type Size
- type Struct
- func (p Struct) Bit(n BitOffset) bool
- func (p Struct) CopyFrom(other Struct) error
- func (p Struct) HasPtr(i uint16) bool
- func (p Struct) IsValid() bool
- func (p Struct) Message() *Message
- func (p Struct) Ptr(i uint16) (Ptr, error)
- func (p Struct) Segment() *Segment
- func (p Struct) SetBit(n BitOffset, v bool)
- func (p Struct) SetData(i uint16, v []byte) error
- func (p Struct) SetNewText(i uint16, v string) error
- func (p Struct) SetPtr(i uint16, src Ptr) error
- func (p Struct) SetText(i uint16, v string) error
- func (p Struct) SetTextFromBytes(i uint16, v []byte) error
- func (p Struct) SetUint16(off DataOffset, v uint16)
- func (p Struct) SetUint32(off DataOffset, v uint32)
- func (p Struct) SetUint64(off DataOffset, v uint64)
- func (p Struct) SetUint8(off DataOffset, v uint8)
- func (p Struct) Size() ObjectSize
- func (p Struct) ToPtr() Ptr
- func (p Struct) Uint16(off DataOffset) uint16
- func (p Struct) Uint32(off DataOffset) uint32
- func (p Struct) Uint64(off DataOffset) uint64
- func (p Struct) Uint8(off DataOffset) uint8
- type TextList
- type UInt16List
- type UInt32List
- type UInt64List
- type UInt8List
- type VoidList
- type WeakClient
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Canonicalize ¶
Canonicalize encodes a struct into its canonical form: a single- segment blob without a segment table. The result will be identical for equivalent structs, even as the schema evolves. The blob is suitable for hashing or signing.
func Disconnected ¶
Disconnected returns an error that formats as the given text and will report true when passed to IsDisconnected.
func Equal ¶
Equal returns true iff p1 and p2 are equal.
Equality is defined to be:
- Two structs are equal iff all of their fields are equal. If one struct has more fields than the other, the extra fields must all be zero.
- Two lists are equal iff they have the same length and their corresponding elements are equal. If one list is a list of primitives and the other is a list of structs, then the list of primitives is treated as if it was a list of structs with the element value as the sole field.
- Two interfaces are equal iff they point to a capability created by the same call to NewClient or they are referring to the same capability table index in the same message. The latter is significant when the message's capability table has not been populated.
- Two null pointers are equal.
- All other combinations of things are not equal.
func IsDisconnected ¶
IsDisconnected reports whether e indicates a failure due to loss of a necessary capability.
func IsUnimplemented ¶
IsUnimplemented reports whether e indicates that functionality is unimplemented.
func NewMessage ¶
NewMessage creates a message with a new root and returns the first segment. It is an error to call NewMessage on an arena with data in it.
func NewPromisedClient ¶
func NewPromisedClient(hook ClientHook) (*Client, *ClientPromise)
NewPromisedClient creates the first reference to a capability that can resolve to a different capability. The hook will be shut down when the promise is resolved or the client has no more references, whichever comes first.
Typically the RPC system will create a client for the application. Most applications will not need to use this directly.
func SetClientLeakFunc ¶
func SetClientLeakFunc(f func(msg string))
SetClientLeakFunc sets a callback for reporting Clients that went out of scope without being released. The callback is not guaranteed to be called and must be safe to call concurrently from multiple goroutines. The exact format of the message is unspecified.
SetClientLeakFunc must not be called after any calls to NewClient or NewPromisedClient.
func Unimplemented ¶
Unimplemented returns an error that formats as the given text and will report true when passed to IsUnimplemented.
Types ¶
type Answer ¶
type Answer struct {
// contains filtered or unexported fields
}
An Answer is a deferred result of a client call. Conceptually, this is a future. It is safe to use from multiple goroutines.
func ErrorAnswer ¶
ErrorAnswer returns a Answer that always returns error e.
func ImmediateAnswer ¶
ImmediateAnswer returns an Answer that accesses s.
func (*Answer) Client ¶
Client returns the answer as a client. If the answer's originating call has not completed, then calls will be queued until the original call's completion. The client reference is borrowed: the caller should not call Close.
func (*Answer) Done ¶
func (ans *Answer) Done() <-chan struct{}
Done returns a channel that is closed when the answer's call is finished.
func (*Answer) Field ¶
Field returns a derived future which yields the pointer field given, defaulting to the value given.
func (*Answer) PipelineRecv ¶
func (ans *Answer) PipelineRecv(ctx context.Context, transform []PipelineOp, r Recv) PipelineCaller
PipelineRecv starts a pipelined call.
func (*Answer) PipelineSend ¶
func (ans *Answer) PipelineSend(ctx context.Context, transform []PipelineOp, s Send) (*Answer, ReleaseFunc)
PipelineSend starts a pipelined call.
type Arena ¶
type Arena interface { // NumSegments returns the number of segments in the arena. // This must not be larger than 1<<32. NumSegments() int64 // Data loads the data for the segment with the given ID. IDs are in // the range [0, NumSegments()). // must be tightly packed in the range [0, NumSegments()). Data(id SegmentID) ([]byte, error) // Allocate selects a segment to place a new object in, creating a // segment or growing the capacity of a previously loaded segment if // necessary. If Allocate does not return an error, then the // difference of the capacity and the length of the returned slice // must be at least minsz. segs is a map of segments keyed by ID // using arrays returned by the Data method (although the length of // these slices may have changed by previous allocations). Allocate // must not modify segs. // // If Allocate creates a new segment, the ID must be one larger than // the last segment's ID or zero if it is the first segment. // // If Allocate returns an previously loaded segment's ID, then the // arena is responsible for preserving the existing data in the // returned byte slice. Allocate(minsz Size, segs map[SegmentID]*Segment) (SegmentID, []byte, error) }
An Arena loads and allocates segments for a Message.
func MultiSegment ¶
MultiSegment returns a new arena that allocates new segments when they are full. b can be used to populate the buffer for reading or to reserve memory of a specific size.
func SingleSegment ¶
SingleSegment returns a new arena with an expanding single-segment buffer. b can be used to populate the segment for reading or to reserve memory of a specific size. A SingleSegment arena does not return errors unless you attempt to access another segment.
type BitList ¶
type BitList struct{ List }
A BitList is a reference to a list of booleans.
func NewBitList ¶
NewBitList creates a new bit list, preferring placement in s.
type BitOffset ¶
type BitOffset uint32
BitOffset is an offset in bits from the beginning of a struct's data section. It is bounded to [0, 1<<22).
type Brand ¶
type Brand struct {
Value interface{}
}
A Brand is an opaque value used to identify a capability.
type CapabilityID ¶
type CapabilityID uint32
A CapabilityID is an index into a message's capability table.
func (CapabilityID) GoString ¶
func (id CapabilityID) GoString() string
GoString returns the ID as a Go expression.
func (CapabilityID) String ¶
func (id CapabilityID) String() string
String returns the ID in the format "capability X".
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
A Client is a reference to a Cap'n Proto capability. The zero value is a null capability reference. It is safe to use from multiple goroutines.
func ErrorClient ¶
ErrorClient returns a Client that always returns error e. An ErrorClient does not need to be released: it is a sentinel like a nil Client.
func NewClient ¶
func NewClient(hook ClientHook) *Client
NewClient creates the first reference to a capability. If hook is nil, then NewClient returns nil.
Typically the RPC system will create a client for the application. Most applications will not need to use this directly.
func (*Client) AddRef ¶
AddRef creates a new Client that refers to the same capability as c. If c is nil or has resolved to null, then AddRef returns nil.
func (*Client) IsSame ¶
IsSame reports whether c and c2 refer to a capability created by the same call to NewClient. This can return false negatives if c or c2 are not fully resolved: use Resolve if this is an issue. If either c or c2 are released, then IsSame panics.
func (*Client) IsValid ¶
IsValid reports whether c is a valid reference to a capability. A reference is invalid if it is nil, has resolved to null, or has been released.
func (*Client) RecvCall ¶
func (c *Client) RecvCall(ctx context.Context, r Recv) PipelineCaller
RecvCall starts executing a method with the referenced arguments and returns an answer that will hold the result. The hook will call a.Release when it no longer needs to reference the parameters. The caller must call the returned release function when it no longer needs the answer's data.
func (*Client) Release ¶
func (c *Client) Release()
Release releases a capability reference. If this is the last reference to the capability, then the underlying resources associated with the capability will be released.
Release will panic if c has already been released, but not if c is nil or resolved to null.
func (*Client) Resolve ¶
Resolve blocks until the capability is fully resolved or the Context is Done.
func (*Client) SendCall ¶
SendCall allocates space for parameters, calls args.Place to fill out the parameters, then starts executing a method, returning an answer that will hold the result. The caller must call the returned release function when it no longer needs the answer's data.
func (*Client) State ¶
func (c *Client) State() ClientState
State reads the current state of the client. It returns the zero ClientState if c is nil, has resolved to null, or has been released.
func (*Client) String ¶
String returns a string that identifies this capability for debugging purposes. Its format should not be depended on: in particular, it should not be used to compare clients. Use IsSame to compare clients for equality.
func (*Client) WeakRef ¶
func (c *Client) WeakRef() *WeakClient
WeakRef creates a new WeakClient that refers to the same capability as c. If c is nil or has resolved to null, then WeakRef returns nil.
type ClientHook ¶
type ClientHook interface { // Send allocates space for parameters, calls s.PlaceArgs to fill out // the arguments, then starts executing a method, returning an answer // that will hold the result. The hook must call s.PlaceArgs at most // once, and if it does call s.PlaceArgs, it must return before Send // returns. The caller must call the returned release function when // it no longer needs the answer's data. // // Send is typically used when application code is making a call. Send(ctx context.Context, s Send) (*Answer, ReleaseFunc) // Recv starts executing a method with the referenced arguments // and places the result in a message controlled by the caller. // The hook will call r.ReleaseArgs when it no longer needs to // reference the parameters and use r.Returner to complete the method // call. If Recv does not call r.Returner.Return before it returns, // then it must return a non-nil PipelineCaller. // // Recv is typically used when the RPC system has received a call. Recv(ctx context.Context, r Recv) PipelineCaller // Brand returns an implementation-specific value. This can be used // to introspect and identify kinds of clients. Brand() Brand // Shutdown releases any resources associated with this capability. // The behavior of calling any methods on the receiver after calling // Shutdown is undefined. It is expected for the ClientHook to reject // any outstanding call futures. Shutdown() }
A ClientHook represents a Cap'n Proto capability. Application code should not pass around ClientHooks; applications should pass around Clients. A ClientHook must be safe to use from multiple goroutines.
Calls must be delivered to the capability in the order they are made. This guarantee is based on the concept of a capability acknowledging delivery of a call: this is specific to an implementation of ClientHook. A type that implements ClientHook must guarantee that if foo() then bar() is called on a client, then the capability acknowledging foo() happens before the capability observing bar().
type ClientPromise ¶
type ClientPromise struct {
// contains filtered or unexported fields
}
A ClientPromise resolves the identity of a client created by NewPromisedClient.
func (*ClientPromise) Fulfill ¶
func (cp *ClientPromise) Fulfill(c *Client)
Fulfill resolves the client promise to c. After Fulfill returns, then all future calls to the client created by NewPromisedClient will be sent to c. It is guaranteed that the hook passed to NewPromisedClient will be shut down after Fulfill returns, but the hook may have been shut down earlier if the client ran out of references.
type ClientState ¶
type ClientState struct { // Brand is the value returned from the hook's Brand method. Brand Brand // IsPromise is true if the client has not resolved yet. IsPromise bool }
ClientState is a snapshot of a client's identity.
type DataList ¶
type DataList struct{ List }
DataList is an array of pointers to data.
func NewDataList ¶
NewDataList allocates a new list of data pointers, preferring placement in s.
type DataOffset ¶
type DataOffset uint32
DataOffset is an offset in bytes from the beginning of a struct's data section. It is bounded to [0, 1<<19).
func (DataOffset) GoString ¶
func (off DataOffset) GoString() string
GoString returns the offset as a Go expression.
func (DataOffset) String ¶
func (off DataOffset) String() string
String returns the offset in the format "+X bytes".
type Decoder ¶
type Decoder struct { // Maximum number of bytes that can be read per call to Decode. // If not set, a reasonable default is used. MaxMessageSize uint64 // contains filtered or unexported fields }
A Decoder represents a framer that deserializes a particular Cap'n Proto input stream.
func NewDecoder ¶
NewDecoder creates a new Cap'n Proto framer that reads from r. The returned decoder will only read as much data as necessary to decode the message.
func NewPackedDecoder ¶
NewPackedDecoder creates a new Cap'n Proto framer that reads from a packed stream r. The returned decoder may read more data than necessary from r.
func (*Decoder) Decode ¶
Decode reads a message from the decoder stream. The error is io.EOF only if no bytes were read.
func (*Decoder) ReuseBuffer ¶
func (d *Decoder) ReuseBuffer()
ReuseBuffer causes the decoder to reuse its buffer on subsequent decodes. The decoder may return messages that cannot handle allocations.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
An Encoder represents a framer for serializing a particular Cap'n Proto stream.
func NewEncoder ¶
NewEncoder creates a new Cap'n Proto framer that writes to w.
func NewPackedEncoder ¶
NewPackedEncoder creates a new Cap'n Proto framer that writes to a packed stream w.
type Float32List ¶
type Float32List struct{ List }
Float32List is an array of Float32 values.
func NewFloat32List ¶
func NewFloat32List(s *Segment, n int32) (Float32List, error)
NewFloat32List creates a new list of Float32, preferring placement in s.
func (Float32List) String ¶
func (l Float32List) String() string
String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]").
type Float64List ¶
type Float64List struct{ List }
Float64List is an array of Float64 values.
func NewFloat64List ¶
func NewFloat64List(s *Segment, n int32) (Float64List, error)
NewFloat64List creates a new list of Float64, preferring placement in s.
func (Float64List) String ¶
func (l Float64List) String() string
String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]").
type Future ¶
type Future struct {
// contains filtered or unexported fields
}
A Future accesses a portion of an Answer. It is safe to use from multiple goroutines.
func (*Future) Client ¶
Client returns the future as a client. If the answer's originating call has not completed, then calls will be queued until the original call's completion. The client reference is borrowed: the caller should not call Close.
func (*Future) Done ¶
func (f *Future) Done() <-chan struct{}
Done returns a channel that is closed when the answer's call is finished.
type Int16List ¶
type Int16List struct{ List }
Int16List is an array of Int16 values.
func NewInt16List ¶
NewInt16List creates a new list of Int16, preferring placement in s.
type Int32List ¶
type Int32List struct{ List }
Int32List is an array of Int32 values.
func NewInt32List ¶
NewInt32List creates a new list of Int32, preferring placement in s.
type Int64List ¶
type Int64List struct{ List }
Int64List is an array of Int64 values.
func NewInt64List ¶
NewInt64List creates a new list of Int64, preferring placement in s.
type Int8List ¶
type Int8List struct{ List }
Int8List is an array of Int8 values.
func NewInt8List ¶
NewInt8List creates a new list of Int8, preferring placement in s.
type Interface ¶
type Interface struct {
// contains filtered or unexported fields
}
An Interface is a reference to a client in a message's capability table.
func NewInterface ¶
func NewInterface(s *Segment, cap CapabilityID) Interface
NewInterface creates a new interface pointer.
No allocation is performed in the given segment: it is used purely to associate the interface pointer with a message.
func (Interface) Capability ¶
func (i Interface) Capability() CapabilityID
Capability returns the capability ID of the interface.
func (Interface) Client ¶
Client returns the client stored in the message's capability table or nil if the pointer is invalid.
type List ¶
type List struct {
// contains filtered or unexported fields
}
A List is a reference to an array of values.
func NewCompositeList ¶
func NewCompositeList(s *Segment, sz ObjectSize, n int32) (List, error)
NewCompositeList creates a new composite list, preferring placement in s.
func (List) Message ¶
Message returns the message the referenced list is stored in or nil if the pointer is invalid.
func (List) Segment ¶
Segment returns the segment the referenced list is stored in or nil if the pointer is invalid.
type Message ¶
type Message struct { Arena Arena // CapTable is the indexed list of the clients referenced in the // message. Capability pointers inside the message will use this table // to map pointers to Clients. The table is usually populated by the // RPC system. // // See https://capnproto.org/encoding.html#capabilities-interfaces for // more details on the capability table. CapTable []*Client // TraverseLimit limits how many total bytes of data are allowed to be // traversed while reading. Traversal is counted when a Struct or // List is obtained. This means that calling a getter for the same // sub-struct multiple times will cause it to be double-counted. Once // the traversal limit is reached, pointer accessors will report // errors. See https://capnproto.org/encoding.html#amplification-attack // for more details on this security measure. // // If not set, this defaults to 64 MiB. TraverseLimit uint64 // DepthLimit limits how deeply-nested a message structure can be. // If not set, this defaults to 64. DepthLimit uint // contains filtered or unexported fields }
A Message is a tree of Cap'n Proto objects, split into one or more segments of contiguous memory. The only required field is Arena. A Message is safe to read from multiple goroutines.
func Unmarshal ¶
Unmarshal reads an unpacked serialized stream into a message. No copying is performed, so the objects in the returned message read directly from data.
Example ¶
msg, s, err := capnp.NewMessage(capnp.SingleSegment(nil)) if err != nil { fmt.Printf("allocation error %v\n", err) return } d, err := air.NewRootZdate(s) if err != nil { fmt.Printf("root error %v\n", err) return } d.SetYear(2004) d.SetMonth(12) d.SetDay(7) data, err := msg.Marshal() if err != nil { fmt.Printf("marshal error %v\n", err) return } // Read msg, err = capnp.Unmarshal(data) if err != nil { fmt.Printf("unmarshal error %v\n", err) return } d, err = air.ReadRootZdate(msg) if err != nil { fmt.Printf("read root error %v\n", err) return } fmt.Printf("year %d, month %d, day %d\n", d.Year(), d.Month(), d.Day())
Output: year 2004, month 12, day 7
func UnmarshalPacked ¶
UnmarshalPacked reads a packed serialized stream into a message.
func (*Message) AddCap ¶
func (m *Message) AddCap(c *Client) CapabilityID
AddCap appends a capability to the message's capability table and returns its ID. It "steals" c's reference: the Message will release the client when calling Reset.
func (*Message) Marshal ¶
Marshal concatenates the segments in the message into a single byte slice including framing.
func (*Message) MarshalPacked ¶
MarshalPacked marshals the message in packed form.
func (*Message) NumSegments ¶
NumSegments returns the number of segments in the message.
func (*Message) Reset ¶
Reset resets a message to use a different arena, allowing a single Message to be reused for reading multiple messages. This invalidates any existing pointers in the Message, so use with caution. All clients in the message's capability table will be released.
func (*Message) ResetReadLimit ¶
ResetReadLimit sets the number of bytes allowed to be read from this message.
type Method ¶
type Method struct { InterfaceID uint64 MethodID uint16 // Canonical name of the interface. May be empty. InterfaceName string // Method name as it appears in the schema. May be empty. MethodName string }
A Method identifies a method along with an optional human-readable description of the method.
type ObjectSize ¶
ObjectSize records section sizes for a struct or list.
func (ObjectSize) GoString ¶
func (sz ObjectSize) GoString() string
GoString formats the ObjectSize as a keyed struct literal.
func (ObjectSize) String ¶
func (sz ObjectSize) String() string
String returns a short, human readable representation of the object size.
type PipelineCaller ¶
type PipelineCaller interface { PipelineSend(ctx context.Context, transform []PipelineOp, s Send) (*Answer, ReleaseFunc) PipelineRecv(ctx context.Context, transform []PipelineOp, r Recv) PipelineCaller }
A PipelineCaller implements promise pipelining.
See the counterpart methods in ClientHook for a description.
type PipelineOp ¶
A PipelineOp describes a step in transforming a pipeline. It maps closely with the PromisedAnswer.Op struct in rpc.capnp.
func (PipelineOp) String ¶
func (op PipelineOp) String() string
String returns a human-readable description of op.
type PointerList ¶
type PointerList struct{ List }
A PointerList is a reference to an array of pointers.
func NewPointerList ¶
func NewPointerList(s *Segment, n int32) (PointerList, error)
NewPointerList allocates a new list of pointers, preferring placement in s.
type Promise ¶
type Promise struct {
// contains filtered or unexported fields
}
A Promise holds the result of an RPC call. Only one of Fulfill, Reject, or Join can be called on a Promise. Before the result is written, calls can be queued up using the Answer methods — this is promise pipelining.
Promise is most useful for implementing ClientHook. Most applications will use Answer, since that what is returned by a Client.
func NewPromise ¶
func NewPromise(m Method, pc PipelineCaller) *Promise
NewPromise creates a new unresolved promise. The PipelineCaller will be used to make pipelined calls before the promise resolves.
func (*Promise) Answer ¶
Answer returns a read-only view of the promise. Answer may be called concurrently by multiple goroutines.
func (*Promise) Fulfill ¶
Fulfill resolves the promise with a successful result.
Fulfill will wait for any outstanding calls to the underlying PipelineCaller to yield Answers and any pipelined clients to be fulfilled.
func (*Promise) Join ¶
Join ties the outcome of a promise to an answer's outcome. The owner of the Promise is still responsible for ensuring that ReleaseClients is called on the joined promise.
Join will wait for any Fulfill, Reject, or Join calls on the answer's underlying promise to complete as well as any outstanding calls to the underlying PipelineCaller to yield an Answer.
func (*Promise) Reject ¶
Reject resolves the promise with a failure.
Reject will wait for any outstanding calls to the underlying PipelineCaller to yield Answers and any pipelined clients to be fulfilled.
func (*Promise) ReleaseClients ¶
func (p *Promise) ReleaseClients()
ReleaseClients waits until p is resolved and then closes any proxy clients created by the promise's answer. Failure to call this method will result in capability leaks. After the first call, subsequent calls to ReleaseClients do nothing. It is safe to call ReleaseClients concurrently from multiple goroutines.
This method is typically used in a ReleaseFunc.
type Ptr ¶
type Ptr struct {
// contains filtered or unexported fields
}
A Ptr is a reference to a Cap'n Proto struct, list, or interface. The zero value is a null pointer.
func MustUnmarshalRoot ¶
MustUnmarshalRoot reads an unpacked serialized stream and returns its root pointer. If there is any error, it panics.
func Transform ¶
func Transform(p Ptr, transform []PipelineOp) (Ptr, error)
Transform applies a sequence of pipeline operations to a pointer and returns the result.
func (Ptr) Data ¶
Data attempts to convert p into Data, returning nil if p is not a valid 1-byte list pointer.
func (Ptr) DataDefault ¶
DataDefault attempts to convert p into Data, returning def if p is not a valid 1-byte list pointer.
func (Ptr) Interface ¶
Interface converts p to an Interface. If p does not hold a List pointer, the zero value is returned.
func (Ptr) List ¶
List converts p to a List. If p does not hold a List pointer, the zero value is returned.
func (Ptr) ListDefault ¶
ListDefault attempts to convert p into a list, reading the default value from def if p is not a list.
func (Ptr) Message ¶
Message returns the message the referenced data is stored in or nil if the pointer is invalid.
func (Ptr) Segment ¶
Segment returns the segment that the referenced data is stored in or nil if the pointer is invalid.
func (Ptr) Struct ¶
Struct converts p to a Struct. If p does not hold a Struct pointer, the zero value is returned.
func (Ptr) StructDefault ¶
StructDefault attempts to convert p into a struct, reading the default value from def if p is not a struct.
func (Ptr) Text ¶
Text attempts to convert p into Text, returning an empty string if p is not a valid 1-byte list pointer.
func (Ptr) TextBytes ¶
TextBytes attempts to convert p into Text, returning nil if p is not a valid 1-byte list pointer. It returns a slice directly into the segment.
func (Ptr) TextBytesDefault ¶
TextBytesDefault attempts to convert p into Text, returning def if p is not a valid 1-byte list pointer. It returns a slice directly into the segment.
func (Ptr) TextDefault ¶
TextDefault attempts to convert p into Text, returning def if p is not a valid 1-byte list pointer.
type Recv ¶
type Recv struct { // Method must have InterfaceID and MethodID filled in. Method Method // Args is the set of arguments for the RPC. Args Struct // ReleaseArgs is called after Args is no longer referenced. // Must not be nil. ReleaseArgs ReleaseFunc // Returner manages the results. Returner Returner }
Recv is the input to ClientHook.Recv.
func (Recv) AllocResults ¶
func (r Recv) AllocResults(sz ObjectSize) (Struct, error)
AllocResults allocates a result struct. It is the same as calling r.Returner.AllocResults(sz).
type ReleaseFunc ¶
type ReleaseFunc func()
A ReleaseFunc tells the RPC system that a parameter or result struct is no longer in use and may be reclaimed. After the first call, subsequent calls to a ReleaseFunc do nothing. A ReleaseFunc should not be called concurrently.
type Returner ¶
type Returner interface { // AllocResults allocates the results struct that will be sent using // Return. It can be called at most once, and only before calling // Return. The struct returned by AllocResults cannot be used after // Return is called. AllocResults(sz ObjectSize) (Struct, error) // Return resolves the method call successfully if e is nil, or failure // otherwise. Return must be called once. // // Return must wait for all ongoing pipelined calls to be delivered, // and after it returns, no new calls can be sent to the PipelineCaller // returned from Recv. Return(e error) }
A Returner allocates and sends the results from a received capability method call.
type Segment ¶
type Segment struct {
// contains filtered or unexported fields
}
A Segment is an allocation arena for Cap'n Proto objects. It is part of a Message, which can contain other segments that reference each other.
type Send ¶
type Send struct { // Method must have InterfaceID and MethodID filled in. Method Method // PlaceArgs is a function that will be called at most once before Send // returns to populate the arguments for the RPC. PlaceArgs may be nil. PlaceArgs func(Struct) error // ArgsSize specifies the size of the struct to pass to PlaceArgs. ArgsSize ObjectSize }
Send is the input to ClientHook.Send.
type Size ¶
type Size uint32
A Size is a size (in bytes).
type Struct ¶
type Struct struct {
// contains filtered or unexported fields
}
Struct is a pointer to a struct.
func NewRootStruct ¶
func NewRootStruct(s *Segment, sz ObjectSize) (Struct, error)
NewRootStruct creates a new struct, preferring placement in s, then sets the message's root to the new struct.
func NewStruct ¶
func NewStruct(s *Segment, sz ObjectSize) (Struct, error)
NewStruct creates a new struct, preferring placement in s.
func (Struct) CopyFrom ¶
CopyFrom copies content from another struct. If the other struct's sections are larger than this struct's, the extra data is not copied, meaning there is a risk of data loss when copying from messages built with future versions of the protocol.
func (Struct) HasPtr ¶
HasPtr reports whether the i'th pointer in the struct is non-null. It does not affect the read limit.
func (Struct) Message ¶
Message returns the message the referenced struct is stored in or nil if the pointer is invalid.
func (Struct) Segment ¶
Segment returns the segment the referenced struct is stored in or nil if the pointer is invalid.
func (Struct) SetData ¶
SetData sets the i'th pointer to a newly allocated data or null if v is nil.
func (Struct) SetNewText ¶
SetNewText sets the i'th pointer to a newly allocated text.
func (Struct) SetText ¶
SetText sets the i'th pointer to a newly allocated text or null if v is empty.
func (Struct) SetTextFromBytes ¶
SetTextFromBytes sets the i'th pointer to a newly allocated text or null if v is nil.
func (Struct) SetUint16 ¶
func (p Struct) SetUint16(off DataOffset, v uint16)
SetUint16 sets the 16-bit integer that is off bytes from the start of the struct to v.
func (Struct) SetUint32 ¶
func (p Struct) SetUint32(off DataOffset, v uint32)
SetUint32 sets the 32-bit integer that is off bytes from the start of the struct to v.
func (Struct) SetUint64 ¶
func (p Struct) SetUint64(off DataOffset, v uint64)
SetUint64 sets the 64-bit integer that is off bytes from the start of the struct to v.
func (Struct) SetUint8 ¶
func (p Struct) SetUint8(off DataOffset, v uint8)
SetUint8 sets the 8-bit integer that is off bytes from the start of the struct to v.
func (Struct) Uint16 ¶
func (p Struct) Uint16(off DataOffset) uint16
Uint16 returns a 16-bit integer from the struct's data section.
func (Struct) Uint32 ¶
func (p Struct) Uint32(off DataOffset) uint32
Uint32 returns a 32-bit integer from the struct's data section.
func (Struct) Uint64 ¶
func (p Struct) Uint64(off DataOffset) uint64
Uint64 returns a 64-bit integer from the struct's data section.
func (Struct) Uint8 ¶
func (p Struct) Uint8(off DataOffset) uint8
Uint8 returns an 8-bit integer from the struct's data section.
type TextList ¶
type TextList struct{ List }
TextList is an array of pointers to strings.
func NewTextList ¶
NewTextList allocates a new list of text pointers, preferring placement in s.
func (TextList) BytesAt ¶
BytesAt returns the i'th element in the list as a byte slice. The underlying array of the slice is the segment data.
type UInt16List ¶
type UInt16List struct{ List }
A UInt16List is an array of UInt16 values.
func NewUInt16List ¶
func NewUInt16List(s *Segment, n int32) (UInt16List, error)
NewUInt16List creates a new list of UInt16, preferring placement in s.
func (UInt16List) String ¶
func (l UInt16List) String() string
String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]").
type UInt32List ¶
type UInt32List struct{ List }
UInt32List is an array of UInt32 values.
func NewUInt32List ¶
func NewUInt32List(s *Segment, n int32) (UInt32List, error)
NewUInt32List creates a new list of UInt32, preferring placement in s.
func (UInt32List) String ¶
func (l UInt32List) String() string
String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]").
type UInt64List ¶
type UInt64List struct{ List }
UInt64List is an array of UInt64 values.
func NewUInt64List ¶
func NewUInt64List(s *Segment, n int32) (UInt64List, error)
NewUInt64List creates a new list of UInt64, preferring placement in s.
func (UInt64List) String ¶
func (l UInt64List) String() string
String returns the list in Cap'n Proto schema format (e.g. "[1, 2, 3]").
type UInt8List ¶
type UInt8List struct{ List }
A UInt8List is an array of UInt8 values.
func NewTextFromBytes ¶
NewTextFromBytes creates a NUL-terminated list of UInt8 from a byte slice.
func NewUInt8List ¶
NewUInt8List creates a new list of UInt8, preferring placement in s.
type VoidList ¶
type VoidList struct{ List }
A VoidList is a list of zero-sized elements.
func NewVoidList ¶
NewVoidList creates a list of voids. No allocation is performed; s is only used for Segment()'s return value.
type WeakClient ¶
type WeakClient struct {
// contains filtered or unexported fields
}
A WeakClient is a weak reference to a capability: it refers to a capability without preventing it from being shut down. The zero value is a null reference.
func (*WeakClient) AddRef ¶
func (wc *WeakClient) AddRef() (c *Client, ok bool)
AddRef creates a new Client that refers to the same capability as c as long as the capability hasn't already been shut down.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
capnpc-go is the Cap'n proto code generator for Go.
|
capnpc-go is the Cap'n proto code generator for Go. |
encoding
|
|
text
Package text supports marshaling Cap'n Proto messages as text based on a schema.
|
Package text supports marshaling Cap'n Proto messages as text based on a schema. |
internal
|
|
capnptool
Package capnptool provides an API for calling the capnp tool in tests.
|
Package capnptool provides an API for calling the capnp tool in tests. |
demo
Package demo contains example tests.
|
Package demo contains example tests. |
errors
Package errors provides errors with codes and prefixes.
|
Package errors provides errors with codes and prefixes. |
nodemap
Package nodemap provides a schema registry index type.
|
Package nodemap provides a schema registry index type. |
packed
Package packed provides functions to read and write the "packed" compression scheme described at https://capnproto.org/encoding.html#packing.
|
Package packed provides functions to read and write the "packed" compression scheme described at https://capnproto.org/encoding.html#packing. |
strquote
Package strquote provides a function for formatting a string as a Cap'n Proto string literal.
|
Package strquote provides a function for formatting a string as a Cap'n Proto string literal. |
Package pogs provides functions to convert Cap'n Proto messages to and from Go structs.
|
Package pogs provides functions to convert Cap'n Proto messages to and from Go structs. |
Package rpc implements the Cap'n Proto RPC protocol.
|
Package rpc implements the Cap'n Proto RPC protocol. |
Package schemas provides a container for Cap'n Proto reflection data.
|
Package schemas provides a container for Cap'n Proto reflection data. |
Package server provides runtime support for implementing Cap'n Proto interfaces locally.
|
Package server provides runtime support for implementing Cap'n Proto interfaces locally. |
std
|
|