Skip to content

NewSpiceClient() pairs a local Flight address with the Spice Cloud HTTP address #81

Description

@claudespice

What happens

NewSpiceClient() builds a client whose Flight address is the local default and whose HTTP address is the Cloud default:

// client.go
func NewSpiceClient() *SpiceClient {
	return NewSpiceClientWithAddress(defaultLocalConfig.FlightUrl)   // grpc://127.0.0.1:50051
}

func NewSpiceClientWithAddress(flightAddress string) *SpiceClient {
	spiceClient := &SpiceClient{
		flightAddress: flightAddress,
		baseHttpUrl:   defaultCloudConfig.HttpUrl,                    // https://data.spiceai.io
		...

So a client left on its defaults submits SQL over Flight to the local runtime while every HTTP-backed call addresses Spice Cloud. The two halves of one client describe two different runtimes.

Which calls this affects

Every method built on baseHttpUrl:

method route
IsRuntimeHealthy /health
IsRuntimeReady /v1/ready
GetRuntimeStatus /v1/status
RefreshDataset /v1/datasets/{name}/acceleration/refresh
Search /v1/search
ListActiveQueries / CancelActiveQuery /v1/sql/active, /v1/sql/{id}/cancel

The listing and cancellation pair makes it most visible, because those two are useless against the wrong runtime: a query submitted over local Flight is never listed, and its id cannot be cancelled. But the health and readiness probes have the same shape — a default client reports on Cloud's health, not on the runtime it is querying.

Why this is not a small fix

Making the defaults a pair changes where already-shipped calls go. Anyone relying on NewSpiceClient() + WithApiKey() reaching Cloud over HTTP (without WithSpiceCloudAddress()) would silently start addressing 127.0.0.1:8090. It needs a deliberate decision about the default and, most likely, a release note — which is why it is filed rather than folded into an SDK feature PR.

Options

  1. NewSpiceClient() takes both local defaults, and WithSpiceCloudAddress() sets both Cloud defaults. Consistent, but changes existing HTTP behavior.
  2. Derive the HTTP default from the Flight address whenever the caller supplied one, keeping the current default only for the no-argument Cloud path.
  3. Keep the current defaults and require WithHttpAddress for local HTTP, documenting the split at each method.

Option 3 is what the docs say today (see #80, which documents the split on the two active-query methods); 1 or 2 would remove the trap instead of describing it.

Found by Copilot's review on #80.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions