type Binder … type BinderFunc … func (f BinderFunc) Bind(ctx context.Context, c *Connection) ConnectionOptions { … } var _ … type ConnectionOptions … type Connection … type inFlightState … // updateInFlight locks the state of the connection's in-flight requests, allows // f to mutate that state, and closes the connection if it is idle and either // is closing or has a read or write error. func (c *Connection) updateInFlight(f func(*inFlightState)) { … } // idle reports whether the connection is in a state with no pending calls or // notifications. // // If idle returns true, the readIncoming goroutine may still be running, // but no other goroutines are doing work on behalf of the connection. func (s *inFlightState) idle() bool { … } // shuttingDown reports whether the connection is in a state that should // disallow new (incoming and outgoing) calls. It returns either nil or // an error that is or wraps the provided errClosing. func (s *inFlightState) shuttingDown(errClosing error) error { … } type incomingRequest … // Bind returns the options unmodified. func (o ConnectionOptions) Bind(context.Context, *Connection) ConnectionOptions { … } // newConnection creates a new connection and runs it. // // This is used by the Dial and Serve functions to build the actual connection. // // The connection is closed automatically (and its resources cleaned up) when // the last request has completed after the underlying ReadWriteCloser breaks, // but it may be stopped earlier by calling Close (for a clean shutdown). func newConnection(bindCtx context.Context, rwc io.ReadWriteCloser, binder Binder, onDone func()) *Connection { … } // Notify invokes the target method but does not wait for a response. // The params will be marshaled to JSON before sending over the wire, and will // be handed to the method invoked. func (c *Connection) Notify(ctx context.Context, method string, params interface{ … } // Call invokes the target method and returns an object that can be used to await the response. // The params will be marshaled to JSON before sending over the wire, and will // be handed to the method invoked. // You do not have to wait for the response, it can just be ignored if not needed. // If sending the call failed, the response will be ready and have the error in it. func (c *Connection) Call(ctx context.Context, method string, params interface{ … } type AsyncCall … // ID used for this call. // This can be used to cancel the call if needed. func (ac *AsyncCall) ID() ID { … } // IsReady can be used to check if the result is already prepared. // This is guaranteed to return true on a result for which Await has already // returned, or a call that failed to send in the first place. func (ac *AsyncCall) IsReady() bool { … } // retire processes the response to the call. func (ac *AsyncCall) retire(response *Response) { … } // Await waits for (and decodes) the results of a Call. // The response will be unmarshaled from JSON into the result. func (ac *AsyncCall) Await(ctx context.Context, result interface{ … } // Respond delivers a response to an incoming Call. // // Respond must be called exactly once for any message for which a handler // returns ErrAsyncResponse. It must not be called for any other message. func (c *Connection) Respond(id ID, result interface{ … } // Cancel cancels the Context passed to the Handle call for the inbound message // with the given ID. // // Cancel will not complain if the ID is not a currently active message, and it // will not cause any messages that have not arrived yet with that ID to be // cancelled. func (c *Connection) Cancel(id ID) { … } // Wait blocks until the connection is fully closed, but does not close it. func (c *Connection) Wait() error { … } // Close stops accepting new requests, waits for in-flight requests and enqueued // Handle calls to complete, and then closes the underlying stream. // // After the start of a Close, notification requests (that lack IDs and do not // receive responses) will continue to be passed to the Preempter, but calls // with IDs will receive immediate responses with ErrServerClosing, and no new // requests (not even notifications!) will be enqueued to the Handler. func (c *Connection) Close() error { … } // readIncoming collects inbound messages from the reader and delivers them, either responding // to outgoing calls or feeding requests to the queue. func (c *Connection) readIncoming(ctx context.Context, reader Reader, preempter Preempter) { … } // acceptRequest either handles msg synchronously or enqueues it to be handled // asynchronously. func (c *Connection) acceptRequest(ctx context.Context, msg *Request, msgBytes int64, preempter Preempter) { … } // handleAsync invokes the handler on the requests in the handler queue // sequentially until the queue is empty. func (c *Connection) handleAsync() { … } // processResult processes the result of a request and, if appropriate, sends a response. func (c *Connection) processResult(from interface{ … } // write is used by all things that write outgoing messages, including replies. // it makes sure that writes are atomic func (c *Connection) write(ctx context.Context, msg Message) error { … } // internalErrorf reports an internal error. By default it panics, but if // c.onInternalError is non-nil it instead calls that and returns an error // wrapping ErrInternal. func (c *Connection) internalErrorf(format string, args ...interface{ … } // labelStatus labels the status of the event in ctx based on whether err is nil. func labelStatus(ctx context.Context, err error) { … } type notDone … func (ic notDone) Value(key interface{ … } func (notDone) Done() <-chan struct{ … } func (notDone) Err() error { … } func (notDone) Deadline() (time.Time, bool) { … }