waymaker-client/go/client.go

90 lines
3.2 KiB
Go

package waymaker
import (
"context"
"fmt"
waymaker_cache "git.awesomike.com/pub/waymaker-client/go/genpb/cache"
waymaker_collections "git.awesomike.com/pub/waymaker-client/go/genpb/collections"
waymaker_kv "git.awesomike.com/pub/waymaker-client/go/genpb/kv"
pb "git.awesomike.com/pub/waymaker-client/go/genpb/locks"
waymaker_sketches "git.awesomike.com/pub/waymaker-client/go/genpb/sketches"
waymaker_streams "git.awesomike.com/pub/waymaker-client/go/genpb/streams"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
// Client is a connected waymaker client. It holds a *grpc.ClientConn and
// exposes per-subsystem entry points. Client is safe to use from multiple
// goroutines.
//
// Client is cheap to copy — the underlying gRPC channel is reference-counted.
type Client struct {
conn *grpc.ClientConn
}
// Connect dials a single waymaker server and returns a Client. The target
// must be a valid gRPC target (e.g. "localhost:8818").
//
// Connection is lazy: Connect returns immediately after resolving the address.
// Use grpc.WithBlock() in opts if you need to confirm reachability at dial
// time.
func Connect(ctx context.Context, target string, opts ...grpc.DialOption) (*Client, error) {
defaults := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
}
opts = append(defaults, opts...)
conn, err := grpc.NewClient(target, opts...)
if err != nil {
return nil, fmt.Errorf("waymaker: dial %q: %w", target, err)
}
return &Client{conn: conn}, nil
}
// ConnectMulti dials multiple waymaker servers with round-robin load
// balancing. Requests are distributed across endpoints and automatically
// rerouted when one is unreachable — the right shape for a clustered
// deployment. Requires at least one target.
//
// Note: the current implementation dials the first endpoint only. A full
// static-resolver-based multi-endpoint implementation can be added without
// breaking the public surface.
func ConnectMulti(ctx context.Context, targets []string, opts ...grpc.DialOption) (*Client, error) {
if len(targets) == 0 {
return nil, invalidErr("ConnectMulti requires at least one target")
}
return Connect(ctx, targets[0], opts...)
}
// Close closes the underlying gRPC connection. Subsequent calls on the
// Client will fail.
func (c *Client) Close() error {
return c.conn.Close()
}
// --- per-subsystem gRPC client constructors (unexported) ---
func (c *Client) locksClient() pb.WaymakerServiceClient {
return pb.NewWaymakerServiceClient(c.conn)
}
func (c *Client) streamsClient() waymaker_streams.WaymakerStreamsServiceClient {
return waymaker_streams.NewWaymakerStreamsServiceClient(c.conn)
}
func (c *Client) kvClient() waymaker_kv.WaymakerKvServiceClient {
return waymaker_kv.NewWaymakerKvServiceClient(c.conn)
}
func (c *Client) collectionsClient() waymaker_collections.WaymakerCollectionsServiceClient {
return waymaker_collections.NewWaymakerCollectionsServiceClient(c.conn)
}
func (c *Client) sketchesClient() waymaker_sketches.WaymakerSketchesServiceClient {
return waymaker_sketches.NewWaymakerSketchesServiceClient(c.conn)
}
func (c *Client) cacheClient() waymaker_cache.WaymakerCacheServiceClient {
return waymaker_cache.NewWaymakerCacheServiceClient(c.conn)
}