This is an automated email from the ASF dual-hosted git repository. Cole-Greer pushed a commit to branch GLVBehaviouralAlignment in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit 994b1bf3ce96ee4f08968380a7a4ca56cdb0ca8f Author: Cole Greer <[email protected]> AuthorDate: Thu Jul 16 14:51:33 2026 -0700 Drop requestTimeout in favor of standardized readTimeout The requestTimeout option added to gremlin-go and gremlin-javascript in this branch (a time-to-first-byte / whole-request deadline) duplicates and conflicts with the readTimeout / readTimeoutMillis option that master's cross-GLV connection-options standardization already established as the canonical timeout knob. readTimeout is streaming-safe (armed per read/chunk) and already covers the server-never-responds scenario, since the very first read of the response never succeeds. - gremlin-go: remove connectionSettings.requestTimeout and ClientSettings.RequestTimeout; drop the http.Transport.ResponseHeaderTimeout wiring. TestShouldTimeoutWhenServerNeverResponds now sets ReadTimeout. - gremlin-javascript: remove ConnectionOptions.requestTimeout and the AbortController-based timeout wrapping in #makeHttpRequest, keeping the transport-error-wrapping behavior. The behavioral test now configures readTimeoutMillis and asserts on the generic connection-closed message. --- gremlin-go/driver/client.go | 7 ------ gremlin-go/driver/client_behavior_test.go | 2 +- gremlin-go/driver/connection.go | 5 ----- gremlin-go/driver/connection_test.go | 2 -- .../gremlin-javascript/lib/driver/connection.ts | 25 +--------------------- .../test/integration/client-behavior-tests.js | 4 ++-- 6 files changed, 4 insertions(+), 41 deletions(-) diff --git a/gremlin-go/driver/client.go b/gremlin-go/driver/client.go index 83e5d21054..d5345393ad 100644 --- a/gremlin-go/driver/client.go +++ b/gremlin-go/driver/client.go @@ -115,12 +115,6 @@ type ClientSettings struct { // uses http.ProxyFromEnvironment (HTTP_PROXY/HTTPS_PROXY/NO_PROXY). Proxy func(*http.Request) (*url.URL, error) - // RequestTimeout is the maximum time to wait for a response after sending a request. - // This bounds the time between finishing writing the request and receiving the response - // headers from the server. It is independent of ConnectionTimeout which only governs - // connection establishment. Set to 0 to disable (no timeout). Default: 0 (disabled). - RequestTimeout time.Duration - EnableUserAgentOnConnect bool // PDTRegistry enables automatic hydration of CompositePDT values during deserialization. @@ -189,7 +183,6 @@ func NewClient(url string, configurations ...func(settings *ClientSettings)) (*C ssl: settings.Ssl, connectTimeout: connectTimeout, readTimeout: readTimeout, - requestTimeout: settings.RequestTimeout, maxConnsPerHost: settings.MaxConnections, maxIdleConnsPerHost: settings.MaxIdleConnections, idleTimeout: idleTimeout, diff --git a/gremlin-go/driver/client_behavior_test.go b/gremlin-go/driver/client_behavior_test.go index 6e35a43f76..d0e69811c2 100644 --- a/gremlin-go/driver/client_behavior_test.go +++ b/gremlin-go/driver/client_behavior_test.go @@ -184,7 +184,7 @@ func TestShouldHandleSlowResponse(t *testing.T) { func TestShouldTimeoutWhenServerNeverResponds(t *testing.T) { url := socketServerURL() client, err := NewClient(url, func(settings *ClientSettings) { - settings.RequestTimeout = 2 * time.Second + settings.ReadTimeout = 2 * time.Second }) if err != nil { t.Skip("Socket server not available") diff --git a/gremlin-go/driver/connection.go b/gremlin-go/driver/connection.go index 6da5429c4e..976e9410f6 100644 --- a/gremlin-go/driver/connection.go +++ b/gremlin-go/driver/connection.go @@ -50,7 +50,6 @@ type connectionSettings struct { ssl *tls.Config connectTimeout time.Duration readTimeout time.Duration - requestTimeout time.Duration maxConnsPerHost int maxIdleConnsPerHost int idleTimeout time.Duration @@ -166,10 +165,6 @@ func newConnection(handler *logHandler, url string, connSettings *connectionSett // generic HTTP compression, so the manual decode path in getReader handles // decompression. Disable net/http's transparent (gzip-only) handling. DisableCompression: true, - // Bounds the time between finishing writing the request and receiving response - // headers. Independent of connectTimeout, which only governs connection - // establishment. Zero disables the timeout. - ResponseHeaderTimeout: connSettings.requestTimeout, } return &connection{ diff --git a/gremlin-go/driver/connection_test.go b/gremlin-go/driver/connection_test.go index 6182a5bcaf..f3ca4094ca 100644 --- a/gremlin-go/driver/connection_test.go +++ b/gremlin-go/driver/connection_test.go @@ -1229,7 +1229,6 @@ func TestConnectionPoolSettings(t *testing.T) { idleTimeout: 300 * time.Second, keepAliveTime: 60 * time.Second, connectTimeout: 30 * time.Second, - requestTimeout: 5 * time.Second, } conn := newConnection(newTestLogHandler(), "http://localhost:8182/gremlin", customSettings) @@ -1240,7 +1239,6 @@ func TestConnectionPoolSettings(t *testing.T) { assert.Equal(t, 256, transport.MaxConnsPerHost, "MaxConnsPerHost should be custom value") assert.Equal(t, 16, transport.MaxIdleConnsPerHost, "MaxIdleConnsPerHost should be custom value") assert.Equal(t, 300*time.Second, transport.IdleConnTimeout, "IdleConnTimeout should be custom value") - assert.Equal(t, 5*time.Second, transport.ResponseHeaderTimeout, "ResponseHeaderTimeout should be custom value") }) t.Run("partial custom settings use defaults for unset values", func(t *testing.T) { diff --git a/gremlin-js/gremlin-javascript/lib/driver/connection.ts b/gremlin-js/gremlin-javascript/lib/driver/connection.ts index 27e6af37f5..47407cbcc5 100644 --- a/gremlin-js/gremlin-javascript/lib/driver/connection.ts +++ b/gremlin-js/gremlin-javascript/lib/driver/connection.ts @@ -80,8 +80,6 @@ export type ConnectionOptions = { /** An optional auth interceptor. As a convenience, this is always appended to the end of the * interceptor list so it runs last, after any user interceptors have modified the request. */ auth?: RequestInterceptor; - /** Maximum time in milliseconds to wait for a server response before aborting the request. Undefined means no timeout. */ - requestTimeout?: number; }; /** The default per-request batch size used when neither the request nor the connection sets one. */ @@ -324,44 +322,23 @@ export default class Connection extends EventEmitter { this._log('debug', `Sending ${httpRequest.method} request to ${httpRequest.url}`); - let effectiveSignal = signal; - const timeoutMs = this.options.requestTimeout; - let timeoutId: ReturnType<typeof setTimeout> | undefined; - let timeoutController: AbortController | undefined; - - if (timeoutMs !== undefined) { - timeoutController = new AbortController(); - timeoutId = setTimeout(() => timeoutController!.abort(new DOMException('TimeoutError', 'TimeoutError')), timeoutMs); - effectiveSignal = signal ? AbortSignal.any([signal, timeoutController.signal]) : timeoutController.signal; - } - try { return await httpFetch.fetch(httpRequest.url, { method: httpRequest.method, headers: httpRequest.headers, body: httpRequest.body, - signal: effectiveSignal, + signal, // Node only: the undici dispatcher carries the connection-pool options. In the browser // it is undefined and the field is omitted, letting the user agent manage the transport. ...(this._dispatcher ? { dispatcher: this._dispatcher } : {}), } as RequestInit); } catch (err: any) { - if (timeoutController?.signal.aborted) { - const e = new ResponseError( - `Request timed out after ${timeoutMs}ms - the server did not respond in time`, - { code: 598, message: `Request timeout: ${timeoutMs}ms exceeded` }, - ); - e.cause = err; - throw e; - } const e = new ResponseError( 'Connection to server closed unexpectedly. Ensure that the server is still reachable and the connection has not been closed by the server or a network device.', { code: 599, message: err.message || 'Connection failed' }, ); e.cause = err; throw e; - } finally { - if (timeoutId !== undefined) clearTimeout(timeoutId); } } diff --git a/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js b/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js index 53be66adbc..a8f9f3de50 100644 --- a/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js +++ b/gremlin-js/gremlin-javascript/test/integration/client-behavior-tests.js @@ -127,12 +127,12 @@ describe('Client Behavior', function () { it('should timeout when server never responds', async function () { this.timeout(5000); - const shortTimeoutClient = createClient({ requestTimeout: 1000 }); + const shortTimeoutClient = createClient({ readTimeoutMillis: 1000 }); try { await assert.rejects( shortTimeoutClient.submit(GREMLIN_NO_RESPONSE), (err) => { - assert.match(err.message, /timed out/i); + assert.match(err.message, /closed unexpectedly/i); assert.strictEqual(err.name, 'ResponseError'); return true; },
