-
Notifications
You must be signed in to change notification settings - Fork 38
Description
SDK/Area
- sdk/golang
- WebSocket bootstrap / token provider
- File: sdk/golang/internal/infra/default_ws_token_provider.go
Summary
The Go SDK hard-codes a 5-second context deadline when fetching the WebSocket bullet token. On slower/variable networks (VPN, IPv6 fallback/Happy-Eyeballs, MTU quirks, congested edges), the POST to /api/v1/bullet-public sometimes exceeds 5s, leading to repeated context deadline exceeded failures—even though the endpoint is healthy and reachable and even when the app/transport is configured with a higher timeout.
This timeout also does not honor the SDK’s configured HTTP transport timeout or any WebSocket client option, so users cannot adjust it without vendoring/patching.
// sdk/golang/internal/infra/default_ws_token_provider.go
func (p *DefaultWsTokenProvider) GetToken() (error, []*interfaces.WsToken) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) // ← hard-coded 5s
defer cancel()
path := PathPublic
if p.private {
path = PathPrivate
}
resp := &tokenResponse{}
err := p.transport.Call(ctx, p.domain, false, "Post", path, nil, resp, false)
if err != nil {
return err, nil
}
for _, sr := range resp.Servers {
sr.Token = resp.Token
}
return nil, resp.Servers
}
Actual behavior
With certain networks, the WS bootstrap fails:
Post "https://api.kucoin.com/api/v1/bullet-public": context deadline exceeded
The failure repeats per attempt, regardless of increasing retry count/delay via SDK options, because each attempt still uses a 5s context deadline internally.
Expected behavior
The token request should respect a configurable timeout (e.g., from transport or WS client options), or at least use a more generous default (e.g., 20–30s) suitable for real-world networks.
Ideally, the timeout should inherit from the configured HTTP client/transport rather than being hard-coded locally.
Why this is a problem (real-world repro)
From the same host over VPN, a direct curl to https://api.kucoin.com/api/v1/bullet-public succeeds (HTTP/2 200) while the SDK call times out after ~5s. This indicates a deadline issue in the SDK rather than endpoint health.
Environments with IPv6 first / fallback to IPv4 often incur extra connection setup time; a 5s cap is too tight for initial TLS + HTTP/2 handshakes via some VPN providers or Cloudflare edges.
Proposed fixes (compatible options)
A. Honor configured timeouts (preferred):
Plumb a timeout from WebSocketClientOption (e.g., TokenRequestTimeout time.Duration).
If unset, default to the HTTP transport’s timeout (if available) or to a more forgiving default (e.g., 30s).
B. Remove the hard-coded deadline here and rely on the HTTP client timeout:
Use ctx := context.Background() (or a caller-provided ctx) and let p.transport enforce timeouts.
C. At minimum, increase the default:
Change time.Second5 → time.Second30. (Still sub-optimal because it’s not user-configurable.)
Backward compatibility
Introducing TokenRequestTimeout is backward-compatible; existing users keep the new default if they don’t set it.
Relying on transport timeout aligns with user expectations (many already tune HTTP timeouts globally).
Thank you