This is an automated email from the ASF dual-hosted git repository.
spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/master by this push:
new e543eea38e Restructure Upgrade Docs to polish up ToC CTR
e543eea38e is described below
commit e543eea38ea5987cf27759a35c747da872ca37a9
Author: Stephen Mallette <[email protected]>
AuthorDate: Mon Jul 20 10:50:45 2026 -0400
Restructure Upgrade Docs to polish up ToC CTR
---
docs/src/upgrade/release-4.x.x.asciidoc | 437 ++++++++++++++++----------------
1 file changed, 221 insertions(+), 216 deletions(-)
diff --git a/docs/src/upgrade/release-4.x.x.asciidoc
b/docs/src/upgrade/release-4.x.x.asciidoc
index e8a9f53155..5e2656ae74 100644
--- a/docs/src/upgrade/release-4.x.x.asciidoc
+++ b/docs/src/upgrade/release-4.x.x.asciidoc
@@ -295,154 +295,99 @@ anonymized form. The original gremlator.com was a
prototype built by TinkerPop c
implementation required Java and a running Gremlin Server, whereas the new
version runs entirely in the browser with
no server infrastructure needed.
-==== Bindings are now Parameters
-
-The map of named values substituted into a Gremlin query was previously called
"bindings" in some places and
-"parameters" in others. TinkerPop now refers to these consistently as *query
parameters*, reserving "bindings" for
-the distinct concept of `ScriptEngine` variable bindings. As a result, the
driver methods for supplying query
-parameters have been renamed. Update any code that sets them:
-
-- Java: `RequestMessage.Builder.addBindings(...)` is now `addParameters(...)`.
-- Python: `client.submit(..., bindings=...)` is now `submit(...,
parameters=...)`, and the `request_options`
-key `bindings` is now `parameters`.
-- Go: `SetBindings`/`SetBindingsString`/`AddBinding` are now
-`SetParameters`/`SetParametersString`/`AddParameter`.
-- .NET: `AddBinding`/`AddBindings`/`AddBindingsString` are now
-`AddParameter`/`AddParameters`/`AddParametersString`.
-- JavaScript: `addBinding`/`addBindings`/`addBindingsString` are now
-`addParameter`/`addParameters`/`addParametersString`, and the
`RequestOptions.bindings` field is now `parameters`.
-
-For example, in the Java driver:
+==== Runtime Upgrades
-[source,java]
-----
-final Map<String, Object> params = new HashMap<>();
-params.put("x", 1);
+TinkerPop 4.0 introduces major upgrades to its various runtimes.
-// 3.x
-RequestMessage.build("g.V(x)").addBindings(params).create();
+===== Java Runtime Upgrade
-// 4.x
-RequestMessage.build("g.V(x)").addParameters(params).create();
-----
+TinkerPop 4.0 raises the minimum Java version from 11 to 17 for both building
and running, and adds support for running
+on Java 21 and Java 25. Supporting Java 25 required upgrading Groovy to
4.0.32, Hadoop to 3.4.3, Spark to 4.1.x, and
+Netty to 4.2.x. These upgrades collectively prohibit building on Java 11, but
enable support in Java 21 and 25.
-See: link:https://issues.apache.org/jira/browse/TINKERPOP-3262[TINKERPOP-3262]
+As with the earlier JDK 17 support, some libraries still rely on deep
reflection (most notably the Kryo serialization
+library used with OLAP), so it may be necessary to `--add-opens` or
`--add-exports` certain modules at runtime. The set
+of options used by TinkerPop's own tests is unchanged.
-==== Standardizing GLV Connections
+===== .NET Runtime Upgrade
-TinkerPop 4.x standardizes connection option names and defaults across all
five Gremlin Language Variants (Java, Python,
-.NET, Go, and JavaScript). Each driver using its language-idiomatic casing
(`camelCase`, `PascalCase`, or `snake_case`).
-These renames are breaking, the old option names have been removed.
+The minimum target framework is now `net8.0` (previously
`netstandard2.0;net6.0`).
-===== Standardized options (cross-GLV)
+==== New Gremlin-Lang Literals
-The table lists each standardized option by driver. Defaults are shown in
parentheses; "n/a" means the driver does not
-expose that option.
+The canonical Gremlin grammar now includes literal syntax for `Character`,
`Duration`, and `Binary` types. These
+literals can be used directly in traversals without falling back to parameter
serialization.
-[width="100%",cols="2,2,2,2,2,2",options="header"]
-|=========================================================
-|Concept |Java (`Cluster.Builder`) |Python (kwarg) |.NET
(`ConnectionSettings`) |Go (settings field) |JavaScript (option)
-|Max pooled connections |`maxConnections` (128) |`max_connections` (128)
|`MaxConnections` (128) |`MaxConnections` (128) |`maxConnections` (128)
-|Connect timeout |`connectTimeoutMillis` (5000) |`connect_timeout_millis`
(5000) |`ConnectTimeoutMillis` (5000) |`ConnectTimeoutMillis` (5000) |n/a
-|Idle-read timeout |`readTimeoutMillis` (0/off) |`read_timeout_millis` (off)
|`ReadTimeoutMillis` (0/off) |`ReadTimeoutMillis` (0/off) |`readTimeoutMillis`
(undici default)
-|Pool idle timeout |`idleTimeoutMillis` (180000) |`idle_timeout_millis`
(180000) |`IdleTimeout` (180s) |`IdleTimeoutMillis` (180000) |n/a
-|TCP keep-alive idle |`keepAliveTimeMillis` (30000) |`keep_alive_time_millis`
(30000) |`KeepAliveTime` (30s) |`KeepAliveTimeMillis` (30000)
|`keepAliveTimeMillis` (30000)
-|Compression |`compression` (`DEFLATE`) |`compression` (`'deflate'`)
|`Compression` (`Deflate`) |`Compression` (`CompressionDeflate`) |`compression`
(`'deflate'`)
-|Connection-level batch size |`batchSize` (64) |`batch_size` (64) |`BatchSize`
(64) |`BatchSize` (64) |`batchSize` (64)
-|Connection-level bulkResults |`bulkResults` (false) |`bulk_results` (false)
|`BulkResults` (false) |`BulkResults` (false) |`bulkResults` (false)
-|Max response header bytes |`maxResponseHeaderBytes` (8192) |n/a
|`MaxResponseHeaderBytes` (handler default) |`MaxResponseHeaderBytes` (net/http
default) |`maxResponseHeaderBytes` (undici default)
-|TLS configuration |`ssl(SslContext)` + keystore builders |`ssl`
(`SSLContext`) |`Ssl` (`SslClientAuthenticationOptions`) |`Ssl` (`*tls.Config`)
|runtime (`NODE_EXTRA_CA_CERTS`, etc.)
-|HTTP proxy |`proxy(ProxyOptions)` |`proxy` |`Proxy` (`IWebProxy`) |`Proxy`
(env default) |`proxy` (undici `ProxyAgent`)
-|Request interceptors |`interceptors` |`interceptors` |interceptor delegates
|`Interceptors` |`interceptors`
-|=========================================================
+===== Character
-===== Behavior changes (all drivers)
+A character literal is a single-character string with a `c` suffix:
-These change runtime behavior on upgrade even if you do not change your
configuration:
+[source,text]
+----
+g.V().has("initial","M"c)
+----
-- *Compression defaults to on.* Every driver now defaults compression to
`deflate` and sends `Accept-Encoding: deflate`.
- Disable it with the compression option's "none" value (`Compression.NONE`,
`'none'`, `Compression.None`,
- `CompressionNone`).
-- *Connect timeout lowered to 5s* (from 15s, where applicable) and is now
actually applied to transport establishment
- (TCP connect plus TLS handshake), not the whole request.
-- *`readTimeout` is an idle-read timeout*, armed when the request is sent and
reset on each inbound response chunk, so it
- is streaming-safe and bounds the wait for the first response as well as the
idle gap between chunks, but not total
- response duration. It is off by default.
-- *`idleTimeout` reaps only pooled connections* that are idle between
requests; it no longer bounds an in-flight
- response (that is `readTimeout`'s job).
+===== Duration
-===== Driver-specific notes
+A duration literal uses seconds and nanoseconds with an optional sign flag:
-- *Java* (`gremlin-driver`): Renamed:
`maxConnectionPoolSize`->`maxConnections`,
`connectionSetupTimeoutMillis`->`connectTimeoutMillis`,
- `idleConnectionTimeoutMillis`->`idleTimeoutMillis`,
`resultIterationBatchSize`->`batchSize`, `serializer`->`responseSerializer`,
- and `RequestOptions` `addG`->`traversalSource`. New: `readTimeoutMillis`,
`keepAliveTimeMillis`,
- `maxResponseHeaderBytes`, `proxy(ProxyOptions)`, `url(String)`,
`ssl(SslContext)`. Removed: `maxResponseContentLength`.
- `validationRequest` default reconciled to `g.inject(0)`.
-- *Python* (`gremlin-python`): Renamed: `pool_size`->`max_connections`
(default 8->128) and `ssl_options`->`ssl`.
- New: `connect_timeout_millis`, `read_timeout_millis`, `idle_timeout_millis`,
`keep_alive_time_millis`, `compression`,
- `batch_size`, `proxy`, `trust_env`. `auth.sigv4` gained an optional
credentials provider. Removed: `headers` (use interceptors)
- and `max_content_length`.
-- *.NET* (`gremlin-dotnet`): Renamed:
`MaxConnectionsPerServer`->`MaxConnections`,
`ConnectionTimeout`->`ConnectTimeout`,
- `IdleConnectionTimeout`->`IdleTimeout`,
`KeepAliveInterval`->`KeepAliveTime`, `EnableCompression`->`Compression`, and
- `Auth.BasicAuth`/`Auth.SigV4Auth`->`Auth.Basic`/`Auth.Sigv4`. New:
`ReadTimeout`, `MaxResponseHeaderBytes`,
- `Proxy`, `Ssl`, `BulkResults`.
-- *Go* (`gremlin-go`): Renamed:
`MaximumConcurrentConnections`->`MaxConnections`,
`IdleConnectionTimeout`->`IdleTimeout`,
- `KeepAliveInterval`->`KeepAliveTime`, `ConnectionTimeout`->`ConnectTimeout`,
`TlsConfig`->`Ssl`, `RequestInterceptors`->`Interceptors`,
- `EnableCompression`->`Compression`. Auth helpers moved from package
`gremlingo`
- (`BasicAuth`/`SigV4Auth`/`SigV4AuthWithCredentials`) into a new `auth`
sub-package (`auth.Basic`/`auth.SigV4`/`auth.SigV4WithCredentials`).
- New: `ReadTimeout(Millis)`, `MaxResponseHeaderBytes`, `Proxy` (defaults to
`http.ProxyFromEnvironment`), `BatchSize`, `BulkResults`.
-- *JavaScript* (`gremlin-javascript`): adopted `undici` as a pinned dependency
providing the default dispatcher built from the
- options above. Renamed: `reader`->`responseSerializer`. New:
`readTimeoutMillis`, `keepAliveTimeMillis`, `maxResponseHeaderBytes`,
- `proxy`, `compression`, `batchSize`, `bulkResults`, `logger`. Removed
`headers` (use interceptors) and the
- `ca`/`cert`/`pfx`/`rejectUnauthorized`/`agent` options (TLS is configured
through the Node/undici runtime). undici is swapped
- out in browser bundles, where these connection-pool options are managed by
the browser.
+[source,text]
+----
+Duration(seconds,nanos)
+Duration(seconds,nanos,false)
+----
-See:
link:https://lists.apache.org/thread/yqtr2wnb1kq2pqqq4002cz511q5o0bkg[[DISCUSS]
Standardizing GLV connection options in TinkerPop 4].
+The first argument is seconds (non-negative integer), the second is
nanoseconds (integer, 0 to 999999999). The
+optional third argument is an `isPositive` boolean that defaults to `true`
when omitted. Set it to `false` for
+negative durations.
-===== Renaming `evaluationTimeout` to `timeoutMillis`
+[source,text]
+----
+g.V().has("length",P.gt(Duration(3600,0)))
+----
-The per-request execution timeout is now referred to by a single name,
`timeoutMillis`, everywhere. `timeoutMillis` is
-the maximum time in milliseconds that a request is allowed to execute on the
server before it times out. It can be
-configured server-wide and overridden on a per-request basis. Previously the
same concept was called
-`evaluationTimeout` in the server configuration, the `with()` script token,
and several driver APIs. The `Millis`
-suffix aligns it with the driver connection options such as
`connectTimeoutMillis` and `readTimeoutMillis`.
+===== Binary
-This is a breaking change with no backward-compatible alias. The old
`evaluationTimeout` name (and the long-deprecated
-`scriptEvaluationTimeout`) are no longer recognized anywhere. Update each
surface as follows:
+A binary literal wraps a base64-encoded string:
-- *Server config*: the `gremlin-server.yaml` key `evaluationTimeout` becomes
`timeoutMillis` (default still 30000).
-- *Script token*: `g.with('evaluationTimeout', 500)` becomes
`g.with('timeoutMillis', 500)`.
-- *Java driver*: `RequestOptions.Builder.timeout(long)` becomes
`timeoutMillis(long)` and `getTimeout()` becomes `getTimeoutMillis()`.
-- *Go driver*: `RequestOptionsBuilder.SetEvaluationTimeout(int)` becomes
`SetTimeoutMillis(int)`.
-- *.NET driver*: `Tokens.ArgsEvalTimeout` becomes `Tokens.ArgsTimeoutMillis`
and `RequestMessage.Builder.AddEvaluationTimeout(...)`
- becomes `AddTimeoutMillis(...)`.
-- *JavaScript driver*: the request option `{ evaluationTimeout: N }` becomes
`{ timeoutMillis: N }`.
-- *Python driver*: use the token `timeoutMillis` (e.g.
`g.with_('timeoutMillis', 500)` or `request_options={'timeoutMillis': 500}`).
+[source,text]
+----
+Binary("AQID")
+Binary("")
+----
-Driver and server should be upgraded together. A driver sending the old
`evaluationTimeout` field to a 4.x server has
-that field silently ignored and falls back to the server's default timeout, as
with any unrecognized request argument.
+Each GLV maps this to its native byte array type:
-See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-server[Gremlin
Server]
+[source,text]
+----
+g.V().has("blob",P.eq(Binary("AQID")))
+----
-==== Runtime Upgrades
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-3153[TINKERPOP-3153]
-TinkerPop 4.0 introduces major upgrades to its various runtimes.
+==== Driver Enhancements
-===== Java Runtime Upgrade
+This version of TinkerPop introduced many enhancements and changes to the
various language drivers. Some changes
+extended to all languages equally, while others were more specific to a single
language. The following sections
+describe the relevant changes.
-TinkerPop 4.0 raises the minimum Java version from 11 to 17 for both building
and running, and adds support for running
-on Java 21 and Java 25. Supporting Java 25 required upgrading Groovy to
4.0.32, Hadoop to 3.4.3, Spark to 4.1.x, and
-Netty to 4.2.x. These upgrades collectively prohibit building on Java 11, but
enable support in Java 21 and 25.
+===== HTTP Streaming Responses
-As with the earlier JDK 17 support, some libraries still rely on deep
reflection (most notably the Kryo serialization
-library used with OLAP), so it may be necessary to `--add-opens` or
`--add-exports` certain modules at runtime. The set
-of options used by TinkerPop's own tests is unchanged.
+The move to HTTP for TinkerPop 4 initially came with a tradeoff: Gremlin
Server's HTTP responses were buffered in
+full before the driver could begin deserializing them, so a request was not
usable by the caller until the server had
+finished producing every result. The drivers now deserialize an HTTP response
incrementally as it arrives, so a
+caller can begin working with the first results while the rest of the response
is still in transit. This reduces
+time-to-first-result and memory use for large result sets, and lets a caller
stop consuming and release the
+connection partway through a result set instead of waiting for it to complete.
-===== .NET Runtime Upgrade
+Streaming is active by default in all GLVs. The Reference Documentation covers
additional details and
+nuances for certain drivers specific to their implementation.
-The minimum target framework is now `net8.0` (previously
`netstandard2.0;net6.0`).
+See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-java-streaming[Java],
+link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-javascript-streaming[JavaScript],
+link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-dotnet-streaming[.NET]
-==== Request Interceptors
+===== Request Interceptors
When TinkerPop supported WebSockets prior to 4.0.0, the Java driver offered a
`RequestInterceptor` interface (and
its predecessor, `HandshakeInterceptor`) that allowed modification of the raw
Netty `FullHttpRequest`. For WebSocket
@@ -477,7 +422,7 @@ See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-java
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-javascript-interceptors[JavaScript],
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-dotnet-interceptors[.NET],
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-go-interceptors[Go]
-==== Non-configurable Serialization
+===== Non-configurable Serialization
TinkerPop 3.x drivers used a single serializer configuration (for example,
`serializer` in the Java driver or
`message_serializer` in Python) that controlled both how a `RequestMessage`
was serialized on the way to the server
@@ -494,59 +439,151 @@ reference.
See: link:https://issues.apache.org/jira/browse/TINKERPOP-3250[TINKERPOP-3250]
-==== New Gremlin-Lang Literals
+===== Standardized options (cross-GLV)
-The canonical Gremlin grammar now includes literal syntax for `Character`,
`Duration`, and `Binary` types. These
-literals can be used directly in traversals without falling back to parameter
serialization.
+TinkerPop 4.x standardizes connection option names and defaults across all
five Gremlin Language Variants (Java, Python,
+.NET, Go, and JavaScript). Each driver using its language-idiomatic casing
(`camelCase`, `PascalCase`, or `snake_case`).
+These renames are breaking, the old option names have been removed.
-===== Character
+The table lists each standardized option by driver. Defaults are shown in
parentheses; "n/a" means the driver does not
+expose that option.
-A character literal is a single-character string with a `c` suffix:
+[width="100%",cols="2,2,2,2,2,2",options="header"]
+|=========================================================
+|Concept |Java (`Cluster.Builder`) |Python (kwarg) |.NET
(`ConnectionSettings`) |Go (settings field) |JavaScript (option)
+|Max pooled connections |`maxConnections` (128) |`max_connections` (128)
|`MaxConnections` (128) |`MaxConnections` (128) |`maxConnections` (128)
+|Connect timeout |`connectTimeoutMillis` (5000) |`connect_timeout_millis`
(5000) |`ConnectTimeoutMillis` (5000) |`ConnectTimeoutMillis` (5000) |n/a
+|Idle-read timeout |`readTimeoutMillis` (0/off) |`read_timeout_millis` (off)
|`ReadTimeoutMillis` (0/off) |`ReadTimeoutMillis` (0/off) |`readTimeoutMillis`
(undici default)
+|Pool idle timeout |`idleTimeoutMillis` (180000) |`idle_timeout_millis`
(180000) |`IdleTimeout` (180s) |`IdleTimeoutMillis` (180000) |n/a
+|TCP keep-alive idle |`keepAliveTimeMillis` (30000) |`keep_alive_time_millis`
(30000) |`KeepAliveTime` (30s) |`KeepAliveTimeMillis` (30000)
|`keepAliveTimeMillis` (30000)
+|Compression |`compression` (`DEFLATE`) |`compression` (`'deflate'`)
|`Compression` (`Deflate`) |`Compression` (`CompressionDeflate`) |`compression`
(`'deflate'`)
+|Connection-level batch size |`batchSize` (64) |`batch_size` (64) |`BatchSize`
(64) |`BatchSize` (64) |`batchSize` (64)
+|Connection-level bulkResults |`bulkResults` (false) |`bulk_results` (false)
|`BulkResults` (false) |`BulkResults` (false) |`bulkResults` (false)
+|Max response header bytes |`maxResponseHeaderBytes` (8192) |n/a
|`MaxResponseHeaderBytes` (handler default) |`MaxResponseHeaderBytes` (net/http
default) |`maxResponseHeaderBytes` (undici default)
+|TLS configuration |`ssl(SslContext)` + keystore builders |`ssl`
(`SSLContext`) |`Ssl` (`SslClientAuthenticationOptions`) |`Ssl` (`*tls.Config`)
|runtime (`NODE_EXTRA_CA_CERTS`, etc.)
+|HTTP proxy |`proxy(ProxyOptions)` |`proxy` |`Proxy` (`IWebProxy`) |`Proxy`
(env default) |`proxy` (undici `ProxyAgent`)
+|Request interceptors |`interceptors` |`interceptors` |interceptor delegates
|`Interceptors` |`interceptors`
+|=========================================================
-[source,text]
-----
-g.V().has("initial","M"c)
-----
+===== Behavior changes (all drivers)
-===== Duration
+These change runtime behavior on upgrade even if you do not change your
configuration:
-A duration literal uses seconds and nanoseconds with an optional sign flag:
+- *Compression defaults to on.* Every driver now defaults compression to
`deflate` and sends `Accept-Encoding: deflate`.
+Disable it with the compression option's "none" value (`Compression.NONE`,
`'none'`, `Compression.None`,
+`CompressionNone`).
+- *Connect timeout lowered to 5s* (from 15s, where applicable) and is now
actually applied to transport establishment
+(TCP connect plus TLS handshake), not the whole request.
+- *`readTimeout` is an idle-read timeout*, armed when the request is sent and
reset on each inbound response chunk, so it
+is streaming-safe and bounds the wait for the first response as well as the
idle gap between chunks, but not total
+response duration. It is off by default.
+- *`idleTimeout` reaps only pooled connections* that are idle between
requests; it no longer bounds an in-flight
+response (that is `readTimeout`'s job).
-[source,text]
-----
-Duration(seconds,nanos)
-Duration(seconds,nanos,false)
-----
+===== Driver-specific notes
-The first argument is seconds (non-negative integer), the second is
nanoseconds (integer, 0 to 999999999). The
-optional third argument is an `isPositive` boolean that defaults to `true`
when omitted. Set it to `false` for
-negative durations.
+- *Java* (`gremlin-driver`): Renamed:
`maxConnectionPoolSize`->`maxConnections`,
`connectionSetupTimeoutMillis`->`connectTimeoutMillis`,
+`idleConnectionTimeoutMillis`->`idleTimeoutMillis`,
`resultIterationBatchSize`->`batchSize`, `serializer`->`responseSerializer`,
+and `RequestOptions` `addG`->`traversalSource`. New: `readTimeoutMillis`,
`keepAliveTimeMillis`,
+`maxResponseHeaderBytes`, `proxy(ProxyOptions)`, `url(String)`,
`ssl(SslContext)`. Removed: `maxResponseContentLength`.
+`validationRequest` default reconciled to `g.inject(0)`.
+- *Python* (`gremlin-python`): Renamed: `pool_size`->`max_connections`
(default 8->128) and `ssl_options`->`ssl`.
+New: `connect_timeout_millis`, `read_timeout_millis`, `idle_timeout_millis`,
`keep_alive_time_millis`, `compression`,
+`batch_size`, `proxy`, `trust_env`. `auth.sigv4` gained an optional
credentials provider. Removed: `headers` (use interceptors)
+and `max_content_length`.
+- *.NET* (`gremlin-dotnet`): Renamed:
`MaxConnectionsPerServer`->`MaxConnections`,
`ConnectionTimeout`->`ConnectTimeout`,
+`IdleConnectionTimeout`->`IdleTimeout`, `KeepAliveInterval`->`KeepAliveTime`,
`EnableCompression`->`Compression`, and
+`Auth.BasicAuth`/`Auth.SigV4Auth`->`Auth.Basic`/`Auth.Sigv4`. New:
`ReadTimeout`, `MaxResponseHeaderBytes`,
+`Proxy`, `Ssl`, `BulkResults`.
+- *Go* (`gremlin-go`): Renamed:
`MaximumConcurrentConnections`->`MaxConnections`,
`IdleConnectionTimeout`->`IdleTimeout`,
+`KeepAliveInterval`->`KeepAliveTime`, `ConnectionTimeout`->`ConnectTimeout`,
`TlsConfig`->`Ssl`, `RequestInterceptors`->`Interceptors`,
+`EnableCompression`->`Compression`. Auth helpers moved from package `gremlingo`
+(`BasicAuth`/`SigV4Auth`/`SigV4AuthWithCredentials`) into a new `auth`
sub-package (`auth.Basic`/`auth.SigV4`/`auth.SigV4WithCredentials`).
+New: `ReadTimeout(Millis)`, `MaxResponseHeaderBytes`, `Proxy` (defaults to
`http.ProxyFromEnvironment`), `BatchSize`, `BulkResults`.
+- *JavaScript* (`gremlin-javascript`): adopted `undici` as a pinned dependency
providing the default dispatcher built from the
+options above. Renamed: `reader`->`responseSerializer`. New:
`readTimeoutMillis`, `keepAliveTimeMillis`, `maxResponseHeaderBytes`,
+`proxy`, `compression`, `batchSize`, `bulkResults`, `logger`. Removed
`headers` (use interceptors) and the
+`ca`/`cert`/`pfx`/`rejectUnauthorized`/`agent` options (TLS is configured
through the Node/undici runtime). undici is swapped
+out in browser bundles, where these connection-pool options are managed by the
browser.
-[source,text]
+See:
link:https://lists.apache.org/thread/yqtr2wnb1kq2pqqq4002cz511q5o0bkg[[DISCUSS]
Standardizing GLV connection options in TinkerPop 4].
+
+===== Renaming `evaluationTimeout` to `timeoutMillis`
+
+The per-request execution timeout is now referred to by a single name,
`timeoutMillis`, everywhere. `timeoutMillis` is
+the maximum time in milliseconds that a request is allowed to execute on the
server before it times out. It can be
+configured server-wide and overridden on a per-request basis. Previously the
same concept was called
+`evaluationTimeout` in the server configuration, the `with()` script token,
and several driver APIs. The `Millis`
+suffix aligns it with the driver connection options such as
`connectTimeoutMillis` and `readTimeoutMillis`.
+
+This is a breaking change with no backward-compatible alias. The old
`evaluationTimeout` name (and the long-deprecated
+`scriptEvaluationTimeout`) are no longer recognized anywhere. Update each
surface as follows:
+
+- *Server config*: the `gremlin-server.yaml` key `evaluationTimeout` becomes
`timeoutMillis` (default still 30000).
+- *Script token*: `g.with('evaluationTimeout', 500)` becomes
`g.with('timeoutMillis', 500)`.
+- *Java driver*: `RequestOptions.Builder.timeout(long)` becomes
`timeoutMillis(long)` and `getTimeout()` becomes `getTimeoutMillis()`.
+- *Go driver*: `RequestOptionsBuilder.SetEvaluationTimeout(int)` becomes
`SetTimeoutMillis(int)`.
+- *.NET driver*: `Tokens.ArgsEvalTimeout` becomes `Tokens.ArgsTimeoutMillis`
and `RequestMessage.Builder.AddEvaluationTimeout(...)`
+becomes `AddTimeoutMillis(...)`.
+- *JavaScript driver*: the request option `{ evaluationTimeout: N }` becomes
`{ timeoutMillis: N }`.
+- *Python driver*: use the token `timeoutMillis` (e.g.
`g.with_('timeoutMillis', 500)` or `request_options={'timeoutMillis': 500}`).
+
+Driver and server should be upgraded together. A driver sending the old
`evaluationTimeout` field to a 4.x server has
+that field silently ignored and falls back to the server's default timeout, as
with any unrecognized request argument.
+
+See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-server[Gremlin
Server]
+
+===== JavaScript Typed Numerics
+
+JavaScript has a single `Number` type (IEEE 754 double) which loses the
distinction between Gremlin numeric types like
+`int`, `float`, `long`, and `double`. The `gremlin-javascript` driver now
provides typed wrapper classes and factory
+functions that give explicit control over how numbers are serialized and
deserialized.
+
+On the *serialization* side, wrapping a value controls the GremlinLang type
suffix and GraphBinary type code sent to
+the server:
+
+[source,javascript]
----
-g.V().has("length",P.gt(Duration(3600,0)))
+const { toInt, toLong, toFloat, toDouble } = gremlin.structure;
+
+g.V().has('age', toInt(29)).next(); // age sent as Int
+g.V().has('score', toFloat(3.14)).next(); // score sent as Float
+g.V().has('id', toLong('9007199254740993')).next(); // id sent as Long
----
-===== Binary
+`toLong()` accepts `number`, `string`, or `bigint`. Number inputs must be
within the safe integer range (throws
+`RangeError` otherwise); string and bigint inputs support the full signed
64-bit range.
-A binary literal wraps a base64-encoded string:
+Without wrappers, the driver continues to infer types automatically from the
JavaScript value, so existing code is
+unaffected.
-[source,text]
+On the *deserialization* side, a new `preciseNumbers: true` connection option
wraps incoming numeric values in the
+same typed wrappers, preserving the server's original type information:
+
+[source,javascript]
----
-Binary("AQID")
-Binary("")
+const g = traversal().with_(new
DriverRemoteConnection('http://localhost:8182/gremlin', {
+ preciseNumbers: true
+}));
+
+const v = await g.V(1).elementMap().next();
+const age = v.value.get('age'); // Int { value: 29, type: 'int' }
+age + 1; // 30 — wrappers support arithmetic via
valueOf()
----
-Each GLV maps this to its native byte array type:
+The `unwrap()` helper extracts the raw value from any wrapper, passing
non-wrapper values through unchanged:
-[source,text]
+[source,javascript]
----
-g.V().has("blob",P.eq(Binary("AQID")))
+const { unwrap } = gremlin.structure;
+unwrap(toInt(29)); // 29
+unwrap('hello'); // 'hello'
----
-See: link:https://issues.apache.org/jira/browse/TINKERPOP-3153[TINKERPOP-3153]
+See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-javascript-numeric-types[Numeric
Types]
+
-==== Python Driver Improvements
+===== Python Driver Improvements
Gremlin for Python has been heavily refactored for this release, simplifying
driver usage and removing unnecessary
infrastructure. Key areas for change to consider when upgrading include
removal of the old mechanism used to configure
@@ -609,22 +646,6 @@ replacement planned for this functionality.
See: link:https://issues.apache.org/jira/browse/TINKERPOP-3249[TINKERPOP-3249]
-==== HTTP Streaming Responses
-
-The move to HTTP for TinkerPop 4 initially came with a tradeoff: Gremlin
Server's HTTP responses were buffered in
-full before the driver could begin deserializing them, so a request was not
usable by the caller until the server had
-finished producing every result. The drivers now deserialize an HTTP response
incrementally as it arrives, so a
-caller can begin working with the first results while the rest of the response
is still in transit. This reduces
-time-to-first-result and memory use for large result sets, and lets a caller
stop consuming and release the
-connection partway through a result set instead of waiting for it to complete.
-
-Streaming is active by default in all GLVs. The Reference Documentation covers
additional details and
-nuances for certain drivers specific to their implementation.
-
-See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-java-streaming[Java],
-link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-javascript-streaming[JavaScript],
-link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-dotnet-streaming[.NET]
-
==== More Secure Gremlin Server
Previous versions of Gremlin Server relied on a Gremlin-flavored Groovy
`ScriptEngine` for basic server initialization,
@@ -698,6 +719,39 @@
link:https://issues.apache.org/jira/browse/TINKERPOP-3107[TINKERPOP-3107]
The following sections describe changes related to paramters passed to the
server and the related concept of `GValue`.
+===== Bindings are now Parameters
+
+The map of named values substituted into a Gremlin query was previously called
"bindings" in some places and
+"parameters" in others. TinkerPop now refers to these consistently as *query
parameters*, reserving "bindings" for
+the distinct concept of `ScriptEngine` variable bindings. As a result, the
driver methods for supplying query
+parameters have been renamed. Update any code that sets them:
+
+- Java: `RequestMessage.Builder.addBindings(...)` is now `addParameters(...)`.
+- Python: `client.submit(..., bindings=...)` is now `submit(...,
parameters=...)`, and the `request_options`
+key `bindings` is now `parameters`.
+- Go: `SetBindings`/`SetBindingsString`/`AddBinding` are now
+`SetParameters`/`SetParametersString`/`AddParameter`.
+- .NET: `AddBinding`/`AddBindings`/`AddBindingsString` are now
+`AddParameter`/`AddParameters`/`AddParametersString`.
+- JavaScript: `addBinding`/`addBindings`/`addBindingsString` are now
+`addParameter`/`addParameters`/`addParametersString`, and the
`RequestOptions.bindings` field is now `parameters`.
+
+For example, in the Java driver:
+
+[source,java]
+----
+final Map<String, Object> params = new HashMap<>();
+params.put("x", 1);
+
+// 3.x
+RequestMessage.build("g.V(x)").addBindings(params).create();
+
+// 4.x
+RequestMessage.build("g.V(x)").addParameters(params).create();
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-3262[TINKERPOP-3262]
+
===== `gremlin-lang` based Parameters
Parameters that are sent as part of the request are now `gremlin-lang` string
maps rather than an actual Map
@@ -769,55 +823,6 @@ See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-java
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-javascript-gvalue[JavaScript],
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-dotnet-gvalue[.NET],
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-go-gvalue[Go]
-==== JavaScript Typed Numerics
-
-JavaScript has a single `Number` type (IEEE 754 double) which loses the
distinction between Gremlin numeric types like
-`int`, `float`, `long`, and `double`. The `gremlin-javascript` driver now
provides typed wrapper classes and factory
-functions that give explicit control over how numbers are serialized and
deserialized.
-
-On the *serialization* side, wrapping a value controls the GremlinLang type
suffix and GraphBinary type code sent to
-the server:
-
-[source,javascript]
-----
-const { toInt, toLong, toFloat, toDouble } = gremlin.structure;
-
-g.V().has('age', toInt(29)).next(); // age sent as Int
-g.V().has('score', toFloat(3.14)).next(); // score sent as Float
-g.V().has('id', toLong('9007199254740993')).next(); // id sent as Long
-----
-
-`toLong()` accepts `number`, `string`, or `bigint`. Number inputs must be
within the safe integer range (throws
-`RangeError` otherwise); string and bigint inputs support the full signed
64-bit range.
-
-Without wrappers, the driver continues to infer types automatically from the
JavaScript value, so existing code is
-unaffected.
-
-On the *deserialization* side, a new `preciseNumbers: true` connection option
wraps incoming numeric values in the
-same typed wrappers, preserving the server's original type information:
-
-[source,javascript]
-----
-const g = traversal().with_(new
DriverRemoteConnection('http://localhost:8182/gremlin', {
- preciseNumbers: true
-}));
-
-const v = await g.V(1).elementMap().next();
-const age = v.value.get('age'); // Int { value: 29, type: 'int' }
-age + 1; // 30 — wrappers support arithmetic via
valueOf()
-----
-
-The `unwrap()` helper extracts the raw value from any wrapper, passing
non-wrapper values through unchanged:
-
-[source,javascript]
-----
-const { unwrap } = gremlin.structure;
-unwrap(toInt(29)); // 29
-unwrap('hello'); // 'hello'
-----
-
-See:
link:https://tinkerpop.apache.org/docs/4.0.0-beta.3/reference/#gremlin-javascript-numeric-types[Numeric
Types]
-
==== Improving Tree
The `Tree` object in Java, returned from the `tree()` step was originally
built as an extension to `HashMap`. There is