Help us shape the future of Go! Take the 2026 Go Developer Survey

client

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: MIT Imports: 19 Imported by: 0

README

Experimental client

This package implements the pinned Pi client request, connection, and subscription lifecycle over the native protocol codec. A client requires an explicit transport factory. The package does not select a gateway or enable a stable CLI command.

NewClient(ClientOptions) creates a disconnected client. Connect(ctx, ClientOptions) creates and connects a client. Instance Connect and Reconnect await a validated server hello. Request waits for a correlated service result. Cancellation sends a target-fenced cancel and keeps the response correlation until the server responds or the connection ends. A response without a matching request fails the connection.

ByteTransportFactory and ByteTransport.Send expose the synchronous admission prefix and asynchronous completion separately. Both return promptly. Their completion callback runs exactly once. This preserves transport write ordering and pending-byte admission before an unawaited send returns. Connection callbacks run on the transport dispatcher. Promise-style continuations are published after the complete incoming chunk, including coalesced and reentrant messages.

Connection and attachment callbacks use identity-bearing listener objects because Go functions are not comparable. Reusing one listener object preserves JavaScript Set registration/removal behavior. Callback additions and removals during a notification affect the live iteration. Listener failures reach OnListenerError; a failure in that diagnostic callback does not change protocol state.

Connect awaits failed-startup disposal and joins the attempt and native transport before returning its error. Instance Dispose remains callback-safe; external owners use WaitClosed to join it without making a reader callback wait on itself.

BeginInvoke returns an owned chord.ServiceInvocation only after actual validation, correlation registration and send admission. Wait(waitContext) cancels only the observer; the original operation context remains unchanged. Presentation shutdown can stop awaiting a Background-context operation without inventing cancellation of that operation. The runtime service-source adapter invokes extension.CallInitiated after this admission boundary and before awaiting the response. RemoteService.BeginCall retains normal access/member checks and requires an explicit initiating transport; it does not infer entry by starting a blocking call in a goroutine.

SubscribeService returns a snapshot and buffers updates until ServiceSubscription.Start. State dictionaries belong to the subscription decoder. Listener delivery is ordered and owned by the subscription. Dispose removes the listener before sending an unsubscribe. It joins admitted delivery after a successful unsubscribe. Callers dispose bindings/subscriptions before disposing their client. Client disposal rejects requests and removes connection/attachment/subscription registrations without inventing application cancellation.

CreateClientServiceTransport accepts the narrow ServiceTransportClient contract so a decorator can interpose a service operation without replacing connection state or the transport. This is the adapter used by Chord bindings.

CreateUnixTransportFactory creates a fresh Unix socket transport for each attempt. It copies admitted sends and applies the upstream four-frame pending-byte budget before returning. One owned writer preserves invocation order. Local close suppresses remote terminal callbacks and releases queued writes. WaitClosed(ctx) joins Go-owned attempts, native I/O, and admitted subscription delivery after disposal; it stays separate from callback-safe Dispose so a callback never waits for itself.

DiscoverUnixServers checks canonical server-addressed socket entries, runs at most sixteen joined probes, applies the caller's per-probe timeout, and returns routes in server-ID order. It leaves stale/unresponsive sockets on disk. Unexpected filesystem or transport failures propagate. Unix transport remains unsupported on Windows, as upstream.

OpenClientRuntime, RunClient and the client TUI in internal/experimental compose this client; the experimental suite runs it against real servers.

Documentation

Overview

Package client implements the experimental Pi client over ordered byte transports.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateClientServiceTransport

func CreateClientServiceTransport(client ServiceTransportClient, getTarget func() protocol.RpcTarget) chord.RemoteServiceTransport

CreateClientServiceTransport resolves the current target for each operation. Update listeners receive the background context, matching upstream's transport adapter.

Types

type AttachmentChangeListener

type AttachmentChangeListener struct {
	// contains filtered or unexported fields
}

AttachmentChangeListener retains callback identity across removal and re-registration.

func NewAttachmentChangeListener

func NewAttachmentChangeListener(call func(*protocol.SessionTarget)) *AttachmentChangeListener

type ByteTransport

type ByteTransport interface {
	Send(chunk []byte, complete func(error))
	Close()
}

ByteTransport admits sends synchronously, in invocation order, and completes each send exactly once. Send returns promptly; its completion callback represents the upstream Promise settlement. Close is idempotent and does not report a local close as a remote callback.

type ByteTransportFactory

type ByteTransportFactory func(context.Context, ByteTransportHandlers, func(ByteTransport, error))

ByteTransportFactory starts one connection attempt and returns promptly. Completion supplies one fresh connected transport or an error. The context owns the attempt, not the established transport. This callback boundary preserves the synchronous prefix of upstream's possibly Promise-returning factory.

func CreateUnixTransportFactory

func CreateUnixTransportFactory(options UnixTransportOptions) (ByteTransportFactory, error)

CreateUnixTransportFactory validates options without connecting. Every invocation owns one cancellable dial and returns a fresh transport.

type ByteTransportHandlers

type ByteTransportHandlers struct {
	OnData  func([]byte)
	OnClose func()
	OnError func(error)
}

ByteTransportHandlers receive ordered data and exactly one remote terminal notification.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client correlates framed requests, maintains attachment state, and hydrates ordered Chord subscriptions. It does not interpret application service methods.

func Connect

func Connect(ctx context.Context, options ClientOptions) (*Client, error)

Connect constructs a client and waits for its handshake. Failed startup disposes the client and joins Go-owned attempts and transport I/O before returning the original error.

func NewClient

func NewClient(options ClientOptions) (*Client, error)

NewClient validates identity and creates a disconnected client without opening a transport.

func (*Client) Attachment

func (client *Client) Attachment() *protocol.SessionTarget

func (*Client) BeginInvoke

func (client *Client) BeginInvoke(ctx context.Context, target protocol.RpcTarget, call chord.ServiceCall) (*chord.ServiceInvocation, error)

BeginInvoke performs request validation, correlation registration and ordered send admission before returning. The operation keeps ctx unchanged. Cancelling its Wait only abandons that observer; ctx still controls the actual request.

func (*Client) Connect

func (client *Client) Connect(ctx context.Context) (protocol.ServerHello, error)

func (*Client) Connected

func (client *Client) Connected() bool

func (*Client) ConnectionState

func (client *Client) ConnectionState() ConnectionState

func (*Client) Disconnect

func (client *Client) Disconnect(reason error)

func (*Client) Dispose

func (client *Client) Dispose() error

Dispose rejects pending requests, disconnects, and removes listeners. Repeated calls are harmless. Subscription owners dispose their subscriptions to join pending listener deliveries.

func (*Client) Disposed

func (client *Client) Disposed() bool

func (*Client) Hello

func (client *Client) Hello() *protocol.ServerHello

func (*Client) OnAttachmentChange

func (client *Client) OnAttachmentChange(identity *AttachmentChangeListener) (func(), error)

func (*Client) OnConnectionStateChange

func (client *Client) OnConnectionStateChange(identity *ConnectionStateChangeListener) (func(), error)

func (*Client) Reconnect

func (client *Client) Reconnect(ctx context.Context) (protocol.ServerHello, error)

func (*Client) Request

func (client *Client) Request(ctx context.Context, target protocol.RpcTarget, call chord.ServiceCall) (json.RawMessage, error)

Request waits for one service result. Cancellation rejects this caller and sends a fenced cancel envelope without dropping the response correlation.

func (*Client) ServerId

func (client *Client) ServerId() string

func (*Client) ServiceCatalogue

func (client *Client) ServiceCatalogue(ctx context.Context, target protocol.RpcTarget) ([]chord.ServiceCatalogueEntry, error)

ServiceCatalogue validates the returned catalogue; malformed server data terminates the connection.

func (*Client) ServiceCatalogueCallback

func (client *Client) ServiceCatalogueCallback(ctx context.Context, target protocol.RpcTarget, complete func([]chord.ServiceCatalogueEntry, error))

ServiceCatalogueCallback preserves the synchronous request-admission prefix needed by the connection service source. Its completion remains client-owned and WaitClosed drains it even if the source is disposed first.

func (*Client) SubscribeService

func (client *Client) SubscribeService(ctx context.Context, target protocol.RpcTarget, serviceId string, mode chord.ServiceMode, listener func(chord.ServiceProviderUpdate) error) (*ServiceSubscription, error)

func (*Client) WaitClosed

func (client *Client) WaitClosed(ctx context.Context) error

WaitClosed joins Go-owned transport attempts, native I/O, and admitted subscription deliveries after Dispose. It is separate from callback-safe Dispose so a callback never waits for its own transport reader.

type ClientDisposedError

type ClientDisposedError struct{}

ClientDisposedError rejects operations after client disposal.

func (*ClientDisposedError) Error

func (*ClientDisposedError) Error() string

type ClientOptions

type ClientOptions struct {
	TransportFactory ByteTransportFactory
	ServerId         string
	MaxFrameLength   *float64
	OnListenerError  func(error)
}

ClientOptions selects one logical server and a fresh transport factory.

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

Connection validates handshakes and routes all subsequent messages. Each attempt has its own decoder and identity; stale transport callbacks cannot replace a newer connection.

func NewConnection

func NewConnection(options ConnectionOptions) (*Connection, error)

NewConnection validates the frame limit without opening a transport.

func (*Connection) Connect

func (connection *Connection) Connect(ctx context.Context) (protocol.ServerHello, error)

Connect starts the transport factory's synchronous prefix before waiting for a validated hello. Cancelling ctx cancels only this attempt; a completed connection stays live until Disconnect or a terminal transport event.

func (*Connection) Disconnect

func (connection *Connection) Disconnect(reason error)

Disconnect ends the current attempt or connection. A nil reason selects the upstream default diagnostic.

func (*Connection) Fail

func (connection *Connection) Fail(err error)

func (*Connection) MaxFrameLength

func (connection *Connection) MaxFrameLength() float64

func (*Connection) Send

func (connection *Connection) Send(frame []byte) error

Send admits an ordered write without awaiting it. A later transport rejection fails the connection that owns that write, not a replacement connection.

func (*Connection) State

func (connection *Connection) State() ConnectionState

type ConnectionOptions

type ConnectionOptions struct {
	TransportFactory ByteTransportFactory
	ServerId         string
	MaxFrameLength   *float64
	OnHandshake      func(protocol.ServerHello) error
	OnMessage        func(protocol.ServerMessage)
	OnStateChange    func(ConnectionStateChange)
}

ConnectionOptions supplies the transport and client-owned callbacks. Callbacks run on the transport's ordered dispatcher and may synchronously disconnect or start a new connection.

type ConnectionState

type ConnectionState string

ConnectionState is the transport/handshake lifecycle state.

const (
	Disconnected ConnectionState = "disconnected"
	Connecting   ConnectionState = "connecting"
	Connected    ConnectionState = "connected"
)

type ConnectionStateChange

type ConnectionStateChange struct {
	State ConnectionState
	Error error
}

ConnectionStateChange is delivered after committing the connection's state.

type ConnectionStateChangeListener

type ConnectionStateChangeListener struct {
	// contains filtered or unexported fields
}

ConnectionStateChangeListener gives Go callbacks the stable identity that JavaScript functions have in a Set.

func NewConnectionStateChangeListener

func NewConnectionStateChangeListener(call func(ConnectionStateChange)) *ConnectionStateChangeListener

type DisconnectedError

type DisconnectedError struct {
	Message string
	Cause   error
}

DisconnectedError retains an underlying transport failure when there is one.

func (*DisconnectedError) Error

func (err *DisconnectedError) Error() string

func (*DisconnectedError) Unwrap

func (err *DisconnectedError) Unwrap() error

type DiscoverUnixServersOptions

type DiscoverUnixServersOptions struct {
	Directory string
	TimeoutMs *float64
}

DiscoverUnixServersOptions bounds each connection and handshake attempt.

type InitiatingServiceTransportClient

type InitiatingServiceTransportClient interface {
	ServiceTransportClient
	BeginInvoke(context.Context, protocol.RpcTarget, chord.ServiceCall) (*chord.ServiceInvocation, error)
}

InitiatingServiceTransportClient explicitly supplies a true request-admission boundary. A decorator forwards this capability only when it preserves that boundary.

type ServerError

type ServerError struct{ Code, Message string }

ServerError retains the server's opaque error code and message.

func NewServerError

func NewServerError(failure protocol.ProtocolError) *ServerError

func (*ServerError) Error

func (err *ServerError) Error() string

type ServiceSubscription

type ServiceSubscription struct {
	Id       string
	Target   protocol.RpcTarget
	Snapshot chord.ServiceSubscriptionSnapshot
	// contains filtered or unexported fields
}

ServiceSubscription holds the initial snapshot and buffers subsequent updates until Start. Dispose removes its listener before unsubscribing and drains admitted delivery after a successful unsubscribe.

func (*ServiceSubscription) Dispose

func (subscription *ServiceSubscription) Dispose() error

func (*ServiceSubscription) Start

func (subscription *ServiceSubscription) Start()

type ServiceTransportClient

ServiceTransportClient is the request/subscription capability consumed by a routed Chord transport. Decorators retain the production Client's lifecycle while interposing one service operation.

type UnixServerRoute

type UnixServerRoute struct {
	ServerId string
	Path     string
}

UnixServerRoute identifies a canonical server-addressed local socket.

func DiscoverUnixServers

func DiscoverUnixServers(ctx context.Context, options DiscoverUnixServersOptions) ([]UnixServerRoute, error)

DiscoverUnixServers probes only canonical server-addressed sockets, with at most sixteen joined workers. Stale/unresponsive endpoints remain on disk and are omitted; unexpected filesystem/transport errors propagate.

type UnixTransportOptions

type UnixTransportOptions struct {
	Path            string
	MaxPendingBytes *float64
}

UnixTransportOptions selects a socket and the maximum admitted, not-yet-completed send bytes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL