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 a4ae684e0b Reorganize 4.x upgrade notes
a4ae684e0b is described below

commit a4ae684e0bdcdcd893b0b191a961e0ddbcc9ab2a
Author: Stephen Mallette <[email protected]>
AuthorDate: Fri Jul 17 13:45:43 2026 -0400

    Reorganize 4.x upgrade notes
    
    Moves the dynamic-arguments section up near the multi-label content and
    groups the Java and .NET runtime upgrades under a single Runtime Upgrades
    heading. Nests the evaluationTimeout rename under connection options, fixes
    the Inconfigurable/Non-configurable heading, and trims redundant notes.
---
 docs/src/upgrade/release-4.x.x.asciidoc | 151 +++++++++++++++-----------------
 1 file changed, 69 insertions(+), 82 deletions(-)

diff --git a/docs/src/upgrade/release-4.x.x.asciidoc 
b/docs/src/upgrade/release-4.x.x.asciidoc
index 4e869d9039..39f72fa69f 100644
--- a/docs/src/upgrade/release-4.x.x.asciidoc
+++ b/docs/src/upgrade/release-4.x.x.asciidoc
@@ -163,6 +163,63 @@ See: 
link:https://issues.apache.org/jira/browse/TINKERPOP-3261[TINKERPOP-3261],
 
link:https://tinkerpop.apache.org/docs/4.0.0/reference/#tinkergraph-multi-label[Multi-Label],
 link:https://tinkerpop.apache.org/docs/4.0.0/reference/#labels-step[labels()],
 link:https://tinkerpop.apache.org/docs/4.0.0/reference/#the-zoo-toy-graph[The 
Zoo]
 
+==== More Dynamic Arguments in Gremlin
+
+Prior to 4.0, comparing a traverser's value against a dynamically computed 
reference required several coordinated
+step labels and `where()` comparison. For example, finding all people older 
than "marko" previously required:
+
+[source,groovy]
+----
+// Old way: label marko's age, compare via where()
+gremlin> g.V(1).values("age").as("markosAge").
+......1>   V().hasLabel("person").as("p").
+......2>   values("age").as("otherAge").
+......3>   where("otherAge", gt("markosAge")).
+......4>   select("p").values("name")
+==>josh
+==>peter
+----
+
+This pattern required several coordinated step labels and could not easily 
compose with other predicates. With
+traversal-accepting arguments, the same query becomes a single, readable step:
+
+[source,groovy]
+----
+// New way: traversal inside the predicate
+gremlin> g.V().has("age", P.gt(__.V(1).values("age"))).values("name")
+==>josh
+==>peter
+----
+
+Steps and predicates that previously only accepted literal values now accept 
child traversals resolved per-traverser
+at runtime. Affected steps: `has()`, `hasId()`, `hasKey()`, `hasLabel()`, 
`hasValue()`, `V()`, `E()`, `property()`,
+`is()`, `where(P)`, and all `P` and `TextP` predicates.
+
+[source,groovy]
+----
+// Multi-source filtering with within() - combine sources in one traversal 
with union().fold()
+gremlin> g.V().has("name", 
P.within(__.union(__.V(1).out("knows").values("name"), 
__.constant("peter")).fold()))
+==>v[2]
+==>v[4]
+==>v[6]
+
+// Set multiple properties from a computed Map
+gremlin> 
g.V(4).property(__.V(1).project("friendCount").by(__.out("knows").count()))
+==>v[4]
+----
+
+Users should look to simplify existing traversals that use 
`as()`/`where()`/`select()` patterns solely to compare
+a traverser against a dynamically computed value. In particular, patterns of 
the form
+`__.as("x")...where("x", P.gt("y"))` can often be replaced with a single 
`has()` or `is()` step containing
+a traversal predicate.
+
+See: <<has-step,has()>>, <<v-step,V()>>, <<property-step,property()>>, 
<<is-step,is()>>,
+<<where-step,where()>>,
+link:https://issues.apache.org/jira/browse/TINKERPOP-2586[TINKERPOP-2586],
+link:https://issues.apache.org/jira/browse/TINKERPOP-2777[TINKERPOP-2777],
+link:https://issues.apache.org/jira/browse/TINKERPOP-3005[TINKERPOP-3005],
+link:https://issues.apache.org/jira/browse/TINKERPOP-1463[TINKERPOP-1463]
+
 ==== Transactions
 
 TinkerPop 4.0 brings a set of related transaction changes across the drivers 
and embedded graphs: explicit remote
@@ -180,13 +237,6 @@ Each GLV provides two entry points:
 * **Traversal API**: `g.tx().begin()` returns a transaction-bound 
`GraphTraversalSource`
 * **Driver API**: `client.transact()` (or `client.Transact()` in .NET) returns 
a `Transaction` with `submit()` methods
 
-Key behaviors consistent across all GLVs:
-
-* Transactions are not thread-safe. All operations must be sequential.
-* The default close behavior is rollback (partial work discarded if commit is 
not called explicitly).
-* Transactions are single-use. After commit or rollback, a new transaction 
must be created.
-* `gtx.tx()` returns the same transaction object (enabling `gtx.tx().commit()` 
pattern from the Traversal API).
-
 See the <<gremlin-drivers-variants,Gremlin Drivers and Variants>> reference 
documentation for language-specific
 syntax and examples.
 
@@ -245,7 +295,7 @@ configuring close behavior and always rollback.
 All GLVs now support the `subgraph()` step. Previously, calling `subgraph()` 
from a GLV produced an unknown-type error
 because the variant could not interpret the `Graph` payload that the server 
returned. Applications can now extract a
 portion of a remote graph as part of a normal traversal and inspect its 
vertices and edges directly from the client,
-without having to re-issue queries to reconstruct the result. See: 
<<subgraph-step>>.
+without having to re-issue queries to reconstruct the result.
 
 In the GLVs, the result is a detached snapshot of the captured vertices and 
edges, not a traversable `Graph` instance.
 It cannot be passed to `traversal().with(...)`, and mutating its collections 
has no effect on the source graph. To
@@ -257,9 +307,9 @@ re-query elements against the original graph, extract their 
ids and call `g.V(id
 link:https://gremlator.com[Gremlator] has been rebuilt entirely in JavaScript 
as a browser-based single-page
 application and is now an official part of the Apache TinkerPop project. It 
translates Gremlin queries into
 equivalent representations in all supported language variants: Groovy, Java, 
Python, JavaScript, Go, .NET, and an
-anonymized form. The original gremlator.com was a prototype built by TinkerPop 
committer Dave Bechberger; the
-previous implementation required Java and a running Gremlin Server, whereas 
the new version runs entirely in the
-browser with no server infrastructure needed.
+anonymized form. The original gremlator.com was a prototype built by TinkerPop 
committer Dave Bechberger. This previous
+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
 
@@ -327,11 +377,6 @@ TinkerPop 4.x standardizes connection option names and 
defaults across all five
 .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.
 
-NOTE: Timeouts use a millisecond-suffixed canonical name 
(`connectTimeoutMillis`, `readTimeoutMillis`,
-`idleTimeoutMillis`, `keepAliveTimeMillis`, and the `_millis` form in Python). 
Java, Go, .NET, and Python also accept an
-idiomatic duration companion for the same setting (Java `Duration`, Go 
`time.Duration`, .NET `TimeSpan`, Python seconds);
-set only one form per option. JavaScript exposes only the millisecond form.
-
 ===== Standardized options (cross-GLV)
 
 The table lists each standardized option by driver. Defaults are shown in 
parentheses; "n/a" means the driver does not
@@ -396,7 +441,7 @@ These change runtime behavior on upgrade even if you do not 
change your configur
 
 See: 
link:https://lists.apache.org/thread/yqtr2wnb1kq2pqqq4002cz511q5o0bkg[[DISCUSS] 
Standardizing GLV connection options in TinkerPop 4].
 
-==== Renaming `evaluationTimeout` to `timeoutMillis`
+===== 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
@@ -421,7 +466,11 @@ that field silently ignored and falls back to the server's 
default timeout, as w
 
 See: 
link:https://tinkerpop.apache.org/docs/4.0.0/reference/#gremlin-server[Gremlin 
Server]
 
-==== Java Runtime Upgrade
+==== Runtime Upgrades
+
+TinkerPop 4.0 introduces major upgrades to its various runtimes.
+
+===== Java Runtime Upgrade
 
 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
@@ -431,7 +480,7 @@ As with the earlier JDK 17 support, some libraries still 
rely on deep reflection
 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.
 
-==== .NET Runtime Upgrade
+===== .NET Runtime Upgrade
 
 The minimum target framework is now `net8.0` (previously 
`netstandard2.0;net6.0`).
 
@@ -470,7 +519,7 @@ See: 
link:https://tinkerpop.apache.org/docs/4.0.0/reference/#gremlin-java-interc
 
link:https://tinkerpop.apache.org/docs/4.0.0/reference/#gremlin-javascript-interceptors[JavaScript],
 
link:https://tinkerpop.apache.org/docs/4.0.0/reference/#gremlin-dotnet-interceptors[.NET],
 
link:https://tinkerpop.apache.org/docs/4.0.0/reference/#gremlin-go-interceptors[Go]
 
-==== Inconfigurable Request Serialization
+==== Non-configurable Request 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
@@ -487,63 +536,6 @@ reference.
 
 See: link:https://issues.apache.org/jira/browse/TINKERPOP-3250[TINKERPOP-3250]
 
-==== Expanding Dynamic Arguments to Additional Steps
-
-Prior to 4.0, comparing a traverser's value against a dynamically computed 
reference required several coordinated
-step labels and `where()` comparison. For example, finding all people older 
than "marko" previously required:
-
-[source,groovy]
-----
-// Old way: label marko's age, compare via where()
-gremlin> g.V(1).values("age").as("markosAge").
-......1>   V().hasLabel("person").as("p").
-......2>   values("age").as("otherAge").
-......3>   where("otherAge", gt("markosAge")).
-......4>   select("p").values("name")
-==>josh
-==>peter
-----
-
-This pattern required several coordinated step labels and could not easily 
compose with other predicates. With
-traversal-accepting arguments, the same query becomes a single, readable step:
-
-[source,groovy]
-----
-// New way: traversal inside the predicate
-gremlin> g.V().has("age", P.gt(__.V(1).values("age"))).values("name")
-==>josh
-==>peter
-----
-
-Steps and predicates that previously only accepted literal values now accept 
child traversals resolved per-traverser
-at runtime. Affected steps: `has()`, `hasId()`, `hasKey()`, `hasLabel()`, 
`hasValue()`, `V()`, `E()`, `property()`,
-`is()`, `where(P)`, and all `P` and `TextP` predicates.
-
-[source,groovy]
-----
-// Multi-source filtering with within() - combine sources in one traversal 
with union().fold()
-gremlin> g.V().has("name", 
P.within(__.union(__.V(1).out("knows").values("name"), 
__.constant("peter")).fold()))
-==>v[2]
-==>v[4]
-==>v[6]
-
-// Set multiple properties from a computed Map
-gremlin> 
g.V(4).property(__.V(1).project("friendCount").by(__.out("knows").count()))
-==>v[4]
-----
-
-Users should look to simplify existing traversals that use 
`as()`/`where()`/`select()` patterns solely to compare
-a traverser against a dynamically computed value. In particular, patterns of 
the form
-`__.as("x")...where("x", P.gt("y"))` can often be replaced with a single 
`has()` or `is()` step containing
-a traversal predicate.
-
-See: <<has-step,has()>>, <<v-step,V()>>, <<property-step,property()>>, 
<<is-step,is()>>,
-<<where-step,where()>>,
-link:https://issues.apache.org/jira/browse/TINKERPOP-2586[TINKERPOP-2586],
-link:https://issues.apache.org/jira/browse/TINKERPOP-2777[TINKERPOP-2777],
-link:https://issues.apache.org/jira/browse/TINKERPOP-3005[TINKERPOP-3005],
-link:https://issues.apache.org/jira/browse/TINKERPOP-1463[TINKERPOP-1463]
-
 ==== New Gremlin-Lang Literals
 
 The canonical Gremlin grammar now includes literal syntax for `Character`, 
`Duration`, and `Binary` types. These
@@ -579,11 +571,6 @@ negative durations.
 g.V().has("length",P.gt(Duration(3600,0)))
 ----
 
-NOTE: Python's `timedelta` has microsecond resolution, so sub-microsecond 
nanosecond values are truncated.
-.NET's `TimeSpan` has 100-nanosecond tick resolution, so sub-100ns values are 
truncated.
-
-NOTE: Duration is not supported in gremlin-javascript.
-
 ===== Binary
 
 A binary literal wraps a base64-encoded string:

Reply via email to