diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 9632d16aee7..d1505373ad6 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -39,7 +39,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima * Removed `Transaction.open()` in favor of `begin()`, which is now the single transaction-start primitive across embedded and remote contexts. * Changed `begin()` and `close()` to be idempotent and calling it when a transaction is already in that state no longer throws. * Added `maxTransactionLifetime` setting to Gremlin Server, an absolute cap on the total age of an HTTP transaction that interrupts a running operation and rolls the transaction back when it fires (default 600000ms, set to `0` to disable). -* Changed the Gremlin Server HTTP transaction idle timer to suspend while an operation is running (so a long-running operation is bounded by `evaluationTimeout` rather than the idle timeout) and to honor `0` as "disable idle reclamation"; the `idleTransactionTimeout` default is now 60000ms. +* Changed the Gremlin Server HTTP transaction idle timer to suspend while an operation is running (so a long-running operation is bounded by `timeoutMs` rather than the idle timeout) and to honor `0` as "disable idle reclamation"; the `idleTransactionTimeout` default is now 60000ms. * Added configurable CORS `allowedOrigins` setting to Gremlin Server; warns when wildcard origin is used alongside authentication. * Fixed `ByteBuf` leak in `GraphBinaryMessageSerializerV4` when serialization throws an `IOException`. * Changed `Tree` to no longer extend `HashMap`; it is now a final class with a tree-shaped API (`childAt`, `hasChild`, `contains`, `findSubtree`, `getOrCreateChild`, `getNodesAtDepth`, `getLeafNodes`, `nodeCount`) and is no longer a `Map`. @@ -82,6 +82,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima * Deprecated Groovy-based `LifeCycleHook` and `TraversalSource` creation via init scripts in favor of YAML configuration. * Updated all default Gremlin Server configs to remove Groovy dependency from initialization. * Added script engine allowlist to Gremlin Server - the `scriptEngines` YAML configuration now restricts which engines can serve requests; `gremlin-lang` is always available. +* Modified the request timeout to a single name `timeoutMs` across the server and GLVs. * Modified request parameters from `Map` to gremlin-lang compatible `String`. * Modified HTTP API to expect gremlin-lang strings for parameters and update all GLVs to send requests in new format. * Added string parameter parsing to `GremlinServer` to prevent traversal injection and excessive nesting depths. diff --git a/docker/gremlin-server/gremlin-server-integration-krb5.yaml b/docker/gremlin-server/gremlin-server-integration-krb5.yaml index 6ba803b59d5..977a6804b91 100644 --- a/docker/gremlin-server/gremlin-server-integration-krb5.yaml +++ b/docker/gremlin-server/gremlin-server-integration-krb5.yaml @@ -17,7 +17,7 @@ host: 0.0.0.0 port: 45942 -evaluationTimeout: 30000 +timeoutMs: 30000 graphs: { graph: { configuration: conf/tinkergraph-empty.properties, diff --git a/docker/gremlin-server/gremlin-server-integration-secure.yaml b/docker/gremlin-server/gremlin-server-integration-secure.yaml index 5aae1611ef3..7a77de0527b 100644 --- a/docker/gremlin-server/gremlin-server-integration-secure.yaml +++ b/docker/gremlin-server/gremlin-server-integration-secure.yaml @@ -17,7 +17,7 @@ host: 0.0.0.0 port: 45941 -evaluationTimeout: 30000 +timeoutMs: 30000 graphs: { graph: { configuration: conf/tinkergraph-empty.properties, diff --git a/docker/gremlin-server/gremlin-server-integration.yaml b/docker/gremlin-server/gremlin-server-integration.yaml index 1880b34810e..da577cda914 100644 --- a/docker/gremlin-server/gremlin-server-integration.yaml +++ b/docker/gremlin-server/gremlin-server-integration.yaml @@ -17,7 +17,7 @@ host: 0.0.0.0 port: 45940 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: { diff --git a/docs/src/dev/provider/index.asciidoc b/docs/src/dev/provider/index.asciidoc index ec642cbfa14..36c2c7b98fb 100644 --- a/docs/src/dev/provider/index.asciidoc +++ b/docs/src/dev/provider/index.asciidoc @@ -1430,8 +1430,8 @@ rejects it with HTTP 400. This prevents cross-graph operations within a single t ==== Transaction Timeout and Idle Reclamation -A transaction can be bounded at three independent scopes, each disabled with `0`. The `evaluationTimeout` bounds a -single operation. The `idleTransactionTimeout` (default 60000ms) bounds the idle gaps between operations: how long a +A transaction can be bounded at three independent scopes, each disabled with `0`. The `timeoutMs` bounds a single +operation. The `idleTransactionTimeout` (default 60000ms) bounds the idle gaps between operations: how long a transaction may remain idle, with no operation running or queued, before it is rolled back and removed; once it is removed, a subsequent request with that transaction ID receives a 404. The `maxTransactionLifetime` (default 600000ms) bounds the total age of the transaction regardless of activity, and so may end a transaction while an operation is still diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc index eaa9950b697..bb7890c4351 100644 --- a/docs/src/reference/gremlin-applications.asciidoc +++ b/docs/src/reference/gremlin-applications.asciidoc @@ -930,7 +930,7 @@ The following table describes the various YAML configuration options that Gremli |gremlinPool |The number of "Gremlin" threads available to execute actual scripts in a `ScriptEngine`. This pool represents the workers available to handle blocking operations in Gremlin Server. When set to `0`, Gremlin Server will use the value provided by `Runtime.availableProcessors()`. |0 |host |The name of the host to bind the server to. |localhost |idleConnectionTimeout |Time in milliseconds that the server will allow a channel to not receive requests from a client before it automatically closes. If enabled, the value provided should typically exceed the amount of time given to `keepAliveInterval`. Note that while this value is to be provided as milliseconds it will resolve to second precision. Set this value to `0` to disable this feature. |0 -|idleTransactionTimeout |Time in milliseconds that a transaction can remain idle (no operation running or queued) before the server forcibly rolls it back and removes it. The idle timer is suspended while an operation is running, so a long-running operation does not trip it (its duration is instead bounded by `evaluationTimeout`); the timer is armed only once the transaction returns to idle. Set to `0` to disable idle reclamation. |60000 +|idleTransactionTimeout |Time in milliseconds that a transaction can remain idle (no operation running or queued) before the server forcibly rolls it back and removes it. The idle timer is suspended while an operation is running, so a long-running operation does not trip it (its duration is instead bounded by `timeoutMs`); the timer is armed only once the transaction returns to idle. Set to `0` to disable idle reclamation. |60000 |keepAliveInterval |Time in milliseconds that the server will allow a channel to not send responses to a client before it sends a "ping" to see if it is still present. If it is present, the client should respond with a "pong" which will thus reset the `idleConnectionTimeout` and keep the channel open. If enabled, this number should be smaller than the value provided to the `idleConnectionTimeout`. Note that while this value is to be provided as milliseconds it will resolve to second precision. Set this value to `0` to disable this feature. |0 |maxAccumulationBufferComponents |Maximum number of request components that can be aggregated for a message. |1024 |maxChunkSize |The maximum length of the content or each chunk. If the content length exceeds this value, the transfer encoding of the decoded request will be converted to 'chunked' and the content will be split into multiple `HttpContent` objects. If the transfer encoding of the HTTP request is 'chunked' already, each chunk will be split into smaller chunks if the length of the chunk exceeds this value. |8192 @@ -969,7 +969,6 @@ The following table describes the various YAML configuration options that Gremli |lifecycleHooks |A `List` of Java-based `LifeCycleHook` implementations to instantiate and execute during server startup and shutdown. See <>. |_none_ |lifecycleHooks[X].className |The fully qualified class name of the `LifeCycleHook` implementation. |_none_ |lifecycleHooks[X].config |A `Map` of configuration passed to the hook's `init(Map)` method. |_none_ -|evaluationTimeout |The amount of time in milliseconds before a request evaluation and iteration of result times out. This feature can be turned off by setting the value to `0`. |30000 |serializers |A `List` of `Map` settings, where each `Map` represents a `MessageSerializer` implementation to use along with its configuration. If this value is not set, then Gremlin Server will configure with GraphSON and GraphBinary but will not register any `ioRegistries` for configured graphs. |_empty_ |serializers[X].className |The full class name of the `MessageSerializer` implementation. |_none_ |serializers[X].config |A `Map` containing `MessageSerializer` specific configurations. |_none_ @@ -985,6 +984,7 @@ The following table describes the various YAML configuration options that Gremli |strictTransactionManagement |Set to `true` to require `aliases` to be submitted on every requests, where the `aliases` become the scope of transaction management. |false |threadPoolBoss |The number of threads available to Gremlin Server for accepting connections. Should always be set to `1`. |1 |threadPoolWorker |The number of threads available to Gremlin Server for processing non-blocking reads and writes. |1 +|timeoutMs |The maximum amount of time in milliseconds that a request is allowed to execute on the server before it times out. This is the server-wide default and may be overridden on a per-request basis with the `timeoutMs` request argument. This feature can be turned off by setting the value to `0`. |30000 |useEpollEventLoop |Try to use epoll event loops (works only on Linux os) instead of netty NIO. |false |writeBufferHighWaterMark | If the number of bytes in the network send buffer exceeds this value then the channel is no longer writeable, accepting no additional writes until buffer is drained and the `writeBufferLowWaterMark` is met. |65536 |writeBufferLowWaterMark | Once the number of bytes queued in the network send buffer exceeds the `writeBufferHighWaterMark`, the channel will not become writeable again until the buffer is drained and it drops below this value. |32768 @@ -1769,7 +1769,7 @@ continuously: client = Cluster.build("localhost").port(8182).create().connect() ==>org.apache.tinkerpop.gremlin.driver.Client$ClusteredClient@42ff9a77 client.submit("while(true) { }") -org.apache.tinkerpop.gremlin.driver.exception.ResponseException: A timeout occurred during traversal evaluation of [RequestMessage{, fields={bindings={}, language=gremlin-groovy, batchSize=64}, gremlin=while(true) { }}] - consider increasing the limit given to evaluationTimeout +org.apache.tinkerpop.gremlin.driver.exception.ResponseException: A timeout occurred during traversal evaluation of [RequestMessage{, fields={bindings={}, language=gremlin-groovy, batchSize=64}, gremlin=while(true) { }}] - consider increasing the limit given to timeoutMs (the maximum time in milliseconds a request may execute on the server) The `GroovyCompilerGremlinPlugin` has a number of configuration options: @@ -1923,11 +1923,11 @@ generally means being measured in the low hundreds of milliseconds and "slow" me * Requests that are "slow" can really hurt Gremlin Server if they are not properly accounted for. Since these requests block a thread until the job is complete or successfully interrupted, lots of long-run requests will eventually consume the `gremlinPool` preventing other requests from getting processed from the queue. -** To limit the impact of this problem, consider properly setting the `evaluationTimeout` to something "sane". +** To limit the impact of this problem, consider properly setting the `timeoutMs` to something "sane". In other words, test the traversals being sent to Gremlin Server and determine the maximum time they take to evaluate and iterate over results, then set the timeout value accordingly. Also, consider setting a shorter global timeout for requests and then use longer per-request timeouts for those specific ones that might execute at a longer rate. -** Note that `evaluationTimeout` can only attempt to interrupt the evaluation on timeout. It allows Gremlin +** Note that `timeoutMs` can only attempt to interrupt the evaluation on timeout. It allows Gremlin Server to "ignore" the result of that evaluation, which means the thread in the `gremlinPool` that did the evaluation may still be consumed after the timeout if interruption does not succeed on the thread. * When using transactions, the server dedicates resources to maintain transaction state for each open transaction. For @@ -2266,13 +2266,13 @@ server forcibly rolls it back. The idle timer is suspended while an operation is does not trip it; it is armed only once the transaction returns to idle. Set it to `0` to disable idle reclamation. The `maxTransactionLifetime` (default 600000ms) is an absolute cap on the total age of a transaction regardless of activity. Unlike `idleTransactionTimeout`, it fires even while an operation is running, interrupting it and rolling the -transaction back. It bounds transaction lifetime and concurrency-slot occupancy absolutely; like `evaluationTimeout`, -its ability to free the underlying worker thread depends on the operation reaching an interruptible point. Set it to +transaction back. It bounds transaction lifetime and concurrency-slot occupancy absolutely; like `timeoutMs`, its +ability to free the underlying worker thread depends on the operation reaching an interruptible point. Set it to `0` to disable the cap. Finally, `maxConcurrentTransactions` (default 1000) caps the number of open transactions allowed; when the limit is reached, new begin requests are rejected with HTTP 503. -These compose with the per-operation `evaluationTimeout` (and its per-request `timeoutMs` override) to bound a -transaction at three independent scopes: a single operation (`evaluationTimeout`), the gaps between operations +These compose with the per-operation `timeoutMs` (configurable server-wide and overridable per request) to bound a +transaction at three independent scopes: a single operation (`timeoutMs`), the gaps between operations (`idleTransactionTimeout`), and the transaction as a whole (`maxTransactionLifetime`). The defaults keep a transaction bounded out of the box; disabling all of them is a deliberate operator choice, and a per-request `timeoutMs` is always honored as sent. diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc index 4e90afdcf61..745839137ef 100644 --- a/docs/src/reference/gremlin-variants.asciidoc +++ b/docs/src/reference/gremlin-variants.asciidoc @@ -217,11 +217,11 @@ Some connection options can also be set on individual requests made through the [source,go] ---- -results, err := g.With("evaluationTimeout", 500).V().Out("knows").ToList() +results, err := g.With("timeoutMs", 500).V().Out("knows").ToList() ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `userAgent` and -`evaluationTimeout`. +`timeoutMs`. NOTE: When submitting traversals through `DriverRemoteConnection`, `bulkResults` defaults to `true` per-request to optimize result transfer. For direct `Client.Submit()` calls, set the connection-level `BulkResults` option to @@ -489,12 +489,12 @@ Both the `Client` and `DriverRemoteConnection` types have a `SubmitWithOptions(t of the standard `Submit()` method. These methods allow a `RequestOptions` struct to be passed in which will augment the execution on the server. `RequestOptions` can be constructed using `RequestOptionsBuilder`. A good use-case for this feature is to set a per-request override to the -`evaluationTimeout` so that it only applies to the current request. +`timeoutMs` so that it only applies to the current request. [source,go] ---- options := new(RequestOptionsBuilder). - SetEvaluationTimeout(5000). + SetTimeoutMs(5000). SetBatchSize(32). SetMaterializeProperties("tokens"). AddBinding("x", 100). @@ -503,15 +503,15 @@ resultSet, err := client.SubmitWithOptions("g.V(x).count()", options) ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `userAgent`, -`evaluationTimeout` and `materializeProperties`. +`timeoutMs` and `materializeProperties`. `RequestOptions` may also contain a map of variable `bindings` to be applied to the supplied traversal string. [source,go] ---- -resultSet, err := client.SubmitWithOptions("g.with('evaluationTimeout', 500).addV().iterate();"+ +resultSet, err := client.SubmitWithOptions("g.with('timeoutMs', 500).addV().iterate();"+ "g.addV().iterate();"+ - "g.with('evaluationTimeout', 500).addV();", new(RequestOptionsBuilder).SetEvaluationTimeout(500).Create()) + "g.with('timeoutMs', 500).addV();", new(RequestOptionsBuilder).SetTimeoutMs(500).Create()) results, err := resultSet.All() ---- @@ -1013,11 +1013,11 @@ on the `TraversalSource`. For instance to set request timeout to 500 millisecond [source,java] ---- GraphTraversalSource g = traversal().with(conf); -List vertices = g.with(Tokens.ARGS_EVAL_TIMEOUT, 500L).V().out("knows").toList() +List vertices = g.with(Tokens.TIMEOUT_MS, 500L).V().out("knows").toList() ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `userAgent`, -`materializeProperties` and `evaluationTimeout`. Use of `Tokens` to reference these options is preferred. +`materializeProperties` and `timeoutMs`. Use of `Tokens` to reference these options is preferred. NOTE: When submitting traversals through `DriverRemoteConnection`, `bulkResults` defaults to `true` per-request to optimize result transfer. This does not apply to direct `Client.submit()` calls, where `bulkResults` must be @@ -1355,8 +1355,7 @@ which will boost performance and reduce resources required on the server. There are a number of overloads to `Client.submit()` that accept a `RequestOptions` object. The `RequestOptions` provide a way to include options that are specific to the request made with the call to `submit()`. A good use-case for -this feature is to set a per-request override to the `evaluationTimeout` so that it only applies to the current -request. +this feature is to set a per-request override to the `timeoutMs` so that it only applies to the current request. [source,java] ---- @@ -1913,11 +1912,11 @@ Some connection options can also be set on individual requests made through the [source,javascript] ---- -const vertices = await g.with_('evaluationTimeout', 500).V().out('knows').toList() +const vertices = await g.with_('timeoutMs', 500).V().out('knows').toList() ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `requestId`, `userAgent`, -`bulkResults`, `materializeProperties` and `evaluationTimeout`. +`bulkResults`, `materializeProperties` and `timeoutMs`. NOTE: When submitting traversals through `DriverRemoteConnection`, `bulkResults` defaults to `true` per-request to optimize result transfer. This does not apply to direct `Client.submit()` calls, where `bulkResults` must be @@ -2254,16 +2253,15 @@ for (const vertex of result2) { The `client.submit()` functions accept a `requestOptions` which expects a dictionary. The `requestOptions` provide a way to include options that are specific to the request made with the call to `submit()`. A good use-case for -this feature is to set a per-request override to the `evaluationTimeout` so that it only applies to the current -request. +this feature is to set a per-request override to the `timeoutMs` so that it only applies to the current request. [source,javascript] ---- -const result = await client.submit("g.V().repeat(both()).times(100)", null, { evaluationTimeout: 5000 }) +const result = await client.submit("g.V().repeat(both()).times(100)", null, { timeoutMs: 5000 }) ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `requestId`, `userAgent`, -`bulkResults`, `materializeProperties` and `evaluationTimeout`. +`bulkResults`, `materializeProperties` and `timeoutMs`. IMPORTANT: The preferred method for setting a per-request timeout for scripts is demonstrated above, but those familiar with bytecode may try `g.with(EVALUATION_TIMEOUT, 500)` within a script. Scripts with multiple traversals and multiple @@ -2300,7 +2298,7 @@ per-request settings. [source,javascript] ---- try { - for await (const item of client.stream('g.V().has("age", gt(age))', { age: 30 }, { evaluationTimeout: 5000 })) { + for await (const item of client.stream('g.V().has("age", gt(age))', { age: 30 }, { timeoutMs: 5000 })) { console.log(item); } } catch (err) { @@ -2652,12 +2650,12 @@ For instance to set request timeout to 500 milliseconds: [source,csharp] ---- -var l = g.With(Tokens.ArgsEvalTimeout, 500).V().Out("knows").Count().ToList(); +var l = g.With(Tokens.ArgsTimeoutMs, 500).V().Out("knows").Count().ToList(); ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `userAgent`, -`materializeProperties`, and `evaluationTimeout`. These options are available as constants on the -`Gremlin.Net.Driver.Tokens` class. +`materializeProperties`, and `timeoutMs`. These options are available as constants on the `Gremlin.Net.Driver.Tokens` +class. NOTE: When submitting traversals through `DriverRemoteConnection`, `bulkResults` defaults to `true` per-request to optimize result transfer. This does not apply to direct `GremlinClient.SubmitAsync()` calls, where `bulkResults` @@ -2920,7 +2918,7 @@ include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference ==== Per Request Settings A `RequestMessage` can be built with additional fields using the builder pattern. A good use-case for this -feature is to set a per-request override to the `evaluationTimeout` so that it only applies to the current request. +feature is to set a per-request override to the `timeoutMs` so that it only applies to the current request. [source,csharp] ---- @@ -2928,7 +2926,7 @@ include::../../../gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `userAgent`, `materializeProperties` -and `evaluationTimeout`. These options are available as constants on the `Gremlin.Net.Driver.Tokens` class. +and `timeoutMs`. These options are available as constants on the `Gremlin.Net.Driver.Tokens` class. ==== Request Interceptors @@ -3313,11 +3311,11 @@ Some connection options can also be set on individual requests made through the [source,python] ---- -vertices = g.with_('evaluationTimeout', 500).V().out('knows').to_list() +vertices = g.with_('timeoutMs', 500).V().out('knows').to_list() ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `language`, -`materializeProperties`, `userAgent`, and `evaluationTimeout`. +`materializeProperties`, `userAgent`, and `timeoutMs`. NOTE: When submitting traversals through `DriverRemoteConnection`, `bulkResults` defaults to `True` per-request to optimize result transfer. This does not apply to direct `Client.submit()` calls, where `bulkResults` must be @@ -3666,16 +3664,15 @@ returns a `concurrent.futures.Future` that resolves to a list when it is complet The `client.submit()` functions accept a `request_options` which expects a dictionary. The `request_options` provide a way to include options that are specific to the request made with the call to `submit()`. A good use-case for -this feature is to set a per-request override to the `evaluationTimeout` so that it only applies to the current -request. +this feature is to set a per-request override to the `timeoutMs` so that it only applies to the current request. [source,python] ---- -result_set = client.submit('g.V().repeat(both()).times(100)', request_options={'evaluationTimeout': 5000}) +result_set = client.submit('g.V().repeat(both()).times(100)', request_options={'timeoutMs': 5000}) ---- The following options are allowed on a per-request basis in this fashion: `batchSize`, `bulkResults`, `requestId`, `userAgent`, -`materializeProperties` and `evaluationTimeout` (formerly `scriptEvaluationTimeout` which is also supported but now deprecated). +`materializeProperties` and `timeoutMs`. IMPORTANT: The preferred method for setting a per-request timeout for scripts is demonstrated above, but those familiar with bytecode may try `g.with(EVALUATION_TIMEOUT, 500)` within a script. Scripts with multiple traversals and multiple diff --git a/docs/src/upgrade/release-4.x.x.asciidoc b/docs/src/upgrade/release-4.x.x.asciidoc index 1118cf3fc9e..891ba2ee391 100644 --- a/docs/src/upgrade/release-4.x.x.asciidoc +++ b/docs/src/upgrade/release-4.x.x.asciidoc @@ -106,6 +106,29 @@ 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 `timeoutMs` + +The per-request execution timeout is now referred to by a single name, `timeoutMs`, everywhere. `timeoutMs` 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, while the wire +protocol already used `timeoutMs` — collapsing to one name removes that inconsistency. + +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 `timeoutMs` (default still 30000). +- *Script token*: `g.with('evaluationTimeout', 500)` becomes `g.with('timeoutMs', 500)`. +- *Java driver*: `RequestOptions.Builder.timeout(long)` becomes `timeoutMs(long)` and `getTimeout()` becomes `getTimeoutMs()`. +- *Go driver*: `RequestOptionsBuilder.SetEvaluationTimeout(int)` becomes `SetTimeoutMs(int)`. +- *.NET driver*: `Tokens.ArgsEvalTimeout` becomes `Tokens.ArgsTimeoutMs` and `RequestMessage.Builder.AddEvaluationTimeout(...)` + becomes `AddTimeoutMs(...)`. +- *JavaScript driver*: the request option `{ evaluationTimeout: N }` becomes `{ timeoutMs: N }`. +- *Python driver*: use the token `timeoutMs` (e.g. `g.with_('timeoutMs', 500)` or `request_options={'timeoutMs': 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. + ==== Declarative Pattern Matching Gremlin has always offered both imperative and declarative styles to writing graph queries. While the imperative style diff --git a/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml index cb16c1fa8fa..352e6efe60f 100644 --- a/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml +++ b/gremlin-console/src/test/resources/org/apache/tinkerpop/gremlin/console/jsr223/gremlin-server-integration.yaml @@ -17,7 +17,7 @@ host: localhost port: 45940 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java index 74ee59ea325..04f88df10c4 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptChecker.java @@ -42,9 +42,8 @@ public class GremlinScriptChecker { * At least one of these tokens should be present somewhere in the Gremlin string for {@link #parse(String)} to * take any action at all. */ - private static final Set tokens = new HashSet<>(Arrays.asList("evaluationTimeout", "scriptEvaluationTimeout", - "ARGS_EVAL_TIMEOUT", "ARGS_SCRIPT_EVAL_TIMEOUT", "requestId", "REQUEST_ID", "materializeProperties", - "ARGS_MATERIALIZE_PROPERTIES")); + private static final Set tokens = new HashSet<>(Arrays.asList("timeoutMs", "TIMEOUT_MS", + "requestId", "REQUEST_ID", "materializeProperties", "ARGS_MATERIALIZE_PROPERTIES")); /** * Matches single line comments, multi-line comments and space characters. @@ -76,16 +75,14 @@ public class GremlinScriptChecker { private static final Pattern patternClean = Pattern.compile("//.*$|/\\*(.|[\\r\\n])*?\\*/|\\s", Pattern.MULTILINE); /** - * Regex fragment for the timeout tokens to look for. There are basically four: + * Regex fragment for the timeout tokens to look for. There are basically two: *
    - *
  • {@code evaluationTimeout} which is a string value and thus single or double quoted
  • - *
  • {@code scriptEvaluationTimeout} which is a string value and thus single or double quoted
  • - *
  • {@code ARGS_EVAL_TIMEOUT} which is a enum type of value which can be referenced with or without a {@code Tokens} qualifier
  • - *
  • {@code ARGS_SCRIPT_EVAL_TIMEOUT} which is a enum type of value which can be referenced with or without a {@code Tokens} qualifier
  • + *
  • {@code timeoutMs} which is a string value and thus single or double quoted
  • + *
  • {@code TIMEOUT_MS} which is a enum type of value which can be referenced with or without a {@code Tokens} qualifier
  • *
* See {@link #patternWithOptions} for explain as this regex is embedded in there. */ - private static final String timeoutTokens = "[\"']evaluationTimeout[\"']|[\"']scriptEvaluationTimeout[\"']|(?:Tokens\\.)?ARGS_EVAL_TIMEOUT|(?:Tokens\\.)?ARGS_SCRIPT_EVAL_TIMEOUT"; + private static final String timeoutTokens = "[\"']timeoutMs[\"']|(?:Tokens\\.)?TIMEOUT_MS"; /** * Regex fragment for the timeout tokens to look for. There are basically four: diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java index 3d8fbd6b854..19a7932fd09 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/GremlinScriptCheckerTest.java @@ -50,17 +50,17 @@ public void shouldReturnEmpty() { @Test public void shouldNotFindTimeoutCozWeCommentedItOut() { assertEquals(Optional.empty(), GremlinScriptChecker.parse("g.\n" + - " // with('evaluationTimeout', 1000L).\n" + + " // with('timeoutMs', 1000L).\n" + " with(true).V().out('knows')").getTimeout()); } @Test public void shouldIdentifyTimeoutWithOddSpacing() { - assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout' , 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs' , 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout' , 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs' , 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout',1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs',1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @@ -84,25 +84,25 @@ public void shouldIdentifyRequestIdWithEmbeddedQuote() { @Test public void shouldIdentifyTimeoutWithLowerL() { - assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000l).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000l).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @Test public void shouldIdentifyTimeoutWithNoL() { - assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout', 1000).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000).with(true).V().out('knows')"). getTimeout().get().longValue()); } @Test public void shouldIdentifyTimeoutAsStringKeySingleQuoted() { - assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @@ -116,9 +116,7 @@ public void shouldIdentifyRequestIdAsStringKeySingleQuoted() { @Test public void shouldIdentifyTimeoutAsStringKeyDoubleQuoted() { - assertEquals(1000, GremlinScriptChecker.parse("g.with(\"evaluationTimeout\", 1000L).with(true).V().out('knows')"). - getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with(\"scriptEvaluationTimeout\", 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with(\"timeoutMs\", 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @@ -132,9 +130,9 @@ public void shouldIdentifyRequestIdAsStringKeyDoubleQuoted() { @Test public void shouldIdentifyTimeoutAsTokenKey() { - assertEquals(1000, GremlinScriptChecker.parse("g.with(Tokens.ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with(Tokens.TIMEOUT_MS, 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with(Tokens.TIMEOUT_MS, 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @@ -148,9 +146,9 @@ public void shouldIdentifyRequestIdAsTokenKey() { @Test public void shouldIdentifyTimeoutAsTokenKeyWithoutClassName() { - assertEquals(1000, GremlinScriptChecker.parse("g.with(ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with(TIMEOUT_MS, 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); - assertEquals(1000, GremlinScriptChecker.parse("g.with(ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinScriptChecker.parse("g.with(TIMEOUT_MS, 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @@ -164,17 +162,17 @@ public void shouldIdentifyRequestIdAsTokenKeyWithoutClassName() { @Test public void shouldIdentifyMultipleTimeouts() { - assertEquals(6000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows');" + - "g.with('evaluationTimeout', 1000L).with(true).V().out('knows');\n" + - " //g.with('evaluationTimeout', 1000L).with(true).V().out('knows');\n" + - " /* g.with('evaluationTimeout', 1000L).with(true).V().out('knows');*/\n" + + assertEquals(6000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows');" + + "g.with('timeoutMs', 1000L).with(true).V().out('knows');\n" + + " //g.with('timeoutMs', 1000L).with(true).V().out('knows');\n" + + " /* g.with('timeoutMs', 1000L).with(true).V().out('knows');*/\n" + " /* \n" + - "g.with('evaluationTimeout', 1000L).with(true).V().out('knows'); \n" + + "g.with('timeoutMs', 1000L).with(true).V().out('knows'); \n" + "*/ \n" + - " g.with('evaluationTimeout', 1000L).with(true).V().out('knows');\n" + - " g.with(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows');\n" + - " g.with(ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows');\n" + - " g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows');"). + " g.with('timeoutMs', 1000L).with(true).V().out('knows');\n" + + " g.with(Tokens.TIMEOUT_MS, 1000L).with(true).V().out('knows');\n" + + " g.with(TIMEOUT_MS, 1000L).with(true).V().out('knows');\n" + + " g.with('timeoutMs', 1000L).with(true).V().out('knows');"). getTimeout().get().longValue()); } @@ -241,7 +239,7 @@ public void shouldIdentifyMultipleMaterializeProperties() { @Test public void shouldFindAllResults() { final GremlinScriptChecker.Result r = GremlinScriptChecker.parse( - "g.with('evaluationTimeout', 1000).with(true).with(REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").with(\"materializeProperties\", 'all').V().out('knows')"); + "g.with('timeoutMs', 1000).with(true).with(REQUEST_ID, \"db024fca-ed15-4375-95de-4c6106aef895\").with(\"materializeProperties\", 'all').V().out('knows')"); assertEquals(1000, r.getTimeout().get().longValue()); assertEquals("db024fca-ed15-4375-95de-4c6106aef895", r.getRequestId().get()); assertEquals("all", r.getMaterializeProperties().get()); @@ -249,7 +247,7 @@ public void shouldFindAllResults() { @Test public void shouldParseLong() { - assertEquals(1000, GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).addV().property(id, 'blue').as('b').\n" + + assertEquals(1000, GremlinScriptChecker.parse("g.with('timeoutMs', 1000L).addV().property(id, 'blue').as('b').\n" + " addV().property(id, 'orange').as('o').\n" + " addV().property(id, 'red').as('r').\n" + " addV().property(id, 'green').as('g').\n" + diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java index 6ba9e6d3340..cf8bd5b8d2d 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/GremlinLangTest.java @@ -123,7 +123,7 @@ public static Iterable generateTestParameters() { "by(__.out(\"knows\").values(\"name\").fold())"}, {g.inject(new int[]{5, 6}).union(__.V(Arrays.asList(1, 2)), __.V(Arrays.asList(3L, new int[]{4}))), "g.inject([5,6]).union(__.V([1,2]),__.V([3L,[4]]))"}, - {g.with("evaluationTimeout", 1000).V(), "g.V()"}, + {g.with("timeoutMs", 1000).V(), "g.V()"}, {g.withSideEffect("a", 1).V(), "g.withSideEffect(\"a\",1).V()"}, {g.withStrategies(ReadOnlyStrategy.instance()).V(), "g.withStrategies(ReadOnlyStrategy).V()"}, {g.withoutStrategies(ReadOnlyStrategy.class).V(), "g.withoutStrategies(ReadOnlyStrategy).V()"}, diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs index e843f43d9e4..773b40b45ba 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Messages/RequestMessage.cs @@ -169,13 +169,14 @@ public Builder AddField(string key, object value) public bool HasField(string key) => _fields.ContainsKey(key); /// - /// Sets the evaluation timeout for this request. + /// Sets the timeout in milliseconds for this request. This is the maximum time the request is + /// allowed to execute on the server before it times out. /// - /// The timeout value. + /// The timeout value in milliseconds. /// The . - public Builder AddEvaluationTimeout(object timeout) + public Builder AddTimeoutMs(object timeout) { - _fields[Tokens.ArgsEvalTimeout] = timeout; + _fields[Tokens.ArgsTimeoutMs] = timeout; return this; } diff --git a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs index 7f39308ec00..a9b9b739d28 100644 --- a/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs +++ b/gremlin-dotnet/src/Gremlin.Net/Driver/Tokens.cs @@ -69,10 +69,10 @@ public class Tokens public const string ArgsLanguage = "language"; /// - /// Argument name that allows the override of the server setting that determines the maximum time to wait for a - /// request to execute on the server. + /// Argument name that allows the override of the server setting that determines the maximum time in + /// milliseconds a request is allowed to execute on the server before it times out. /// - public const string ArgsEvalTimeout = "evaluationTimeout"; + public const string ArgsTimeoutMs = "timeoutMs"; /// /// Argument name that allows the override of handling properties. diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs index b67d7a7ecbd..6f6496edfda 100644 --- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Docs/Reference/GremlinVariantsTests.cs @@ -130,7 +130,7 @@ public async Task SubmittingScriptsWithTimeoutTest() var response = await gremlinClient.SubmitWithSingleResultAsync( RequestMessage.Build("g.V().count()"). - AddField(Tokens.ArgsEvalTimeout, 500). + AddField(Tokens.ArgsTimeoutMs, 500). Create()); // end::submittingScriptsWithTimeout[] } diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs index e7ea25f6480..75223d053a8 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs @@ -147,14 +147,14 @@ public async Task ShouldExtractAllowedOptionsStrategyKeys() gl.AddStep("V", Array.Empty()); gl.OptionsStrategies.Add(new OptionsStrategy(new Dictionary { - { Tokens.ArgsEvalTimeout, 5000L }, + { Tokens.ArgsTimeoutMs, 5000L }, { Tokens.ArgsBatchSize, 100 } })); await connection.SubmitAsync(gl); Assert.NotNull(capturedRequest); - Assert.Equal(5000L, capturedRequest!.Fields[Tokens.ArgsEvalTimeout]); + Assert.Equal(5000L, capturedRequest!.Fields[Tokens.ArgsTimeoutMs]); Assert.Equal(100, capturedRequest.Fields[Tokens.ArgsBatchSize]); } diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/HttpRequestContextTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/HttpRequestContextTests.cs index 10522026445..f272282f483 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/HttpRequestContextTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/HttpRequestContextTests.cs @@ -206,7 +206,7 @@ public void SerializeBodyShouldIncludeAllFields() .AddG("g") .AddLanguage("gremlin-lang") .AddBatchSize(100) - .AddEvaluationTimeout(30000) + .AddTimeoutMs(30000) .Create(); var context = new HttpRequestContext("POST", new Uri("http://localhost:8182/gremlin"), new Dictionary(), message); @@ -218,7 +218,7 @@ public void SerializeBodyShouldIncludeAllFields() Assert.Equal("g", json.RootElement.GetProperty("g").GetString()); Assert.Equal("gremlin-lang", json.RootElement.GetProperty("language").GetString()); Assert.Equal(100, json.RootElement.GetProperty("batchSize").GetInt32()); - Assert.Equal(30000, json.RootElement.GetProperty("evaluationTimeout").GetInt32()); + Assert.Equal(30000, json.RootElement.GetProperty("timeoutMs").GetInt32()); } [Fact] diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Messages/RequestMessageTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Messages/RequestMessageTests.cs index 4d669841b56..56dc96cdc54 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Messages/RequestMessageTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/Messages/RequestMessageTests.cs @@ -82,10 +82,10 @@ public void ShouldSetMultipleBindings() public void ShouldSetAdditionalField() { var msg = RequestMessage.Build("g.V()") - .AddField(Tokens.ArgsEvalTimeout, 5000L) + .AddField(Tokens.ArgsTimeoutMs, 5000L) .Create(); - Assert.Equal(5000L, msg.Fields[Tokens.ArgsEvalTimeout]); + Assert.Equal(5000L, msg.Fields[Tokens.ArgsTimeoutMs]); } [Fact] diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs index b80cad97af1..ca3c5d350f0 100644 --- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs +++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs @@ -731,7 +731,7 @@ public void g_WithStrategies_OptionsStrategy_V_Count() { // OptionsStrategy is extracted, not rendered in the script Assert.Equal("g.V().count()", - _g.WithStrategies(new OptionsStrategy(new Dictionary { { "evaluationTimeout", 500 } })).V().Count().GremlinLang.GetGremlin()); + _g.WithStrategies(new OptionsStrategy(new Dictionary { { "timeoutMs", 500 } })).V().Count().GremlinLang.GetGremlin()); } [Fact] diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java index a8b1b49ad69..c9ece41d34b 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/Client.java @@ -234,7 +234,7 @@ public CompletableFuture submitAsync(final String gremlin, final Requ .addChunkSize(batchSize); // apply settings if they were made available - options.getTimeout().ifPresent(timeout -> request.addTimeoutMillis(timeout)); + options.getTimeoutMs().ifPresent(timeout -> request.addTimeoutMillis(timeout)); options.getParameters().ifPresent(params -> request.addBindings(params)); options.getG().ifPresent(g -> request.addG(g)); options.getLanguage().ifPresent(lang -> request.addLanguage(lang)); diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java index a0f16807956..a7be0cfb8c4 100644 --- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java +++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/RequestOptions.java @@ -29,7 +29,7 @@ import static org.apache.tinkerpop.gremlin.util.Tokens.ARGS_BATCH_SIZE; import static org.apache.tinkerpop.gremlin.util.Tokens.BULK_RESULTS; -import static org.apache.tinkerpop.gremlin.util.Tokens.ARGS_EVAL_TIMEOUT; +import static org.apache.tinkerpop.gremlin.util.Tokens.TIMEOUT_MS; import static org.apache.tinkerpop.gremlin.util.Tokens.ARGS_G; import static org.apache.tinkerpop.gremlin.util.Tokens.ARGS_LANGUAGE; import static org.apache.tinkerpop.gremlin.util.Tokens.ARGS_MATERIALIZE_PROPERTIES; @@ -46,7 +46,7 @@ public final class RequestOptions { private final String graphOrTraversalSource; private final String parameters; private final Integer batchSize; - private final Long timeout; + private final Long timeoutMs; private final String language; private final String materializeProperties; private final String bulkResults; @@ -56,7 +56,7 @@ private RequestOptions(final Builder builder) { this.graphOrTraversalSource = builder.graphOrTraversalSource; this.parameters = builder.parametersString; this.batchSize = builder.batchSize; - this.timeout = builder.timeout; + this.timeoutMs = builder.timeoutMs; this.language = builder.language; this.materializeProperties = builder.materializeProperties; this.bulkResults = builder.bulkResults; @@ -75,8 +75,8 @@ public Optional getBatchSize() { return Optional.ofNullable(batchSize); } - public Optional getTimeout() { - return Optional.ofNullable(timeout); + public Optional getTimeoutMs() { + return Optional.ofNullable(timeoutMs); } public Optional getLanguage() { @@ -99,8 +99,8 @@ public static RequestOptions getRequestOptions(final GremlinLang gremlinLang) { while (itty.hasNext()) { final OptionsStrategy optionsStrategy = itty.next(); final Map options = optionsStrategy.getOptions(); - if (options.containsKey(ARGS_EVAL_TIMEOUT)) - builder.timeout(((Number) options.get(ARGS_EVAL_TIMEOUT)).longValue()); + if (options.containsKey(TIMEOUT_MS)) + builder.timeoutMs(((Number) options.get(TIMEOUT_MS)).longValue()); if (options.containsKey(ARGS_BATCH_SIZE)) builder.batchSize(((Number) options.get(ARGS_BATCH_SIZE)).intValue()); if (options.containsKey(ARGS_MATERIALIZE_PROPERTIES)) @@ -126,7 +126,7 @@ public static final class Builder { private Map internalParameters = null; private String parametersString = null; private Integer batchSize = null; - private Long timeout = null; + private Long timeoutMs = null; private String materializeProperties = null; private String language = null; private String bulkResults = null; @@ -142,7 +142,7 @@ public static Builder from(final RequestOptions options) { builder.graphOrTraversalSource = options.graphOrTraversalSource; builder.parametersString = options.parameters; builder.batchSize = options.batchSize; - builder.timeout = options.timeout; + builder.timeoutMs = options.timeoutMs; builder.materializeProperties = options.materializeProperties; builder.language = options.language; builder.bulkResults = options.bulkResults; @@ -208,11 +208,12 @@ public Builder batchSize(final int batchSize) { } /** - * The per client request override in milliseconds for the server configured {@code evaluationTimeout}. - * If this value is not set, then the configuration for the server is used. + * The per client request override in milliseconds for the server configured {@code timeoutMs} (the maximum + * time a request is allowed to execute on the server before it times out). If this value is not set, then the + * configuration for the server is used. */ - public Builder timeout(final long timeout) { - this.timeout = timeout; + public Builder timeoutMs(final long timeoutMs) { + this.timeoutMs = timeoutMs; return this; } diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnectionTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnectionTest.java index 98614968890..63711015067 100644 --- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnectionTest.java +++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/remote/DriverRemoteConnectionTest.java @@ -39,20 +39,20 @@ public void shouldBuildRequestOptions() { g.with("x"). with("y", 100). with(Tokens.ARGS_BATCH_SIZE, 1000). - with(Tokens.ARGS_EVAL_TIMEOUT, 100000L). + with(Tokens.TIMEOUT_MS, 100000L). with(Tokens.ARGS_USER_AGENT, "test"). V().asAdmin().getGremlinLang()); assertEquals(1000, options.getBatchSize().get().intValue()); - assertEquals(100000L, options.getTimeout().get().longValue()); + assertEquals(100000L, options.getTimeoutMs().get().longValue()); } @Test public void shouldBuildRequestOptionsWithNumerics() { final RequestOptions options = getRequestOptions( g.with(Tokens.ARGS_BATCH_SIZE, 100). - with(Tokens.ARGS_EVAL_TIMEOUT, 1000). + with(Tokens.TIMEOUT_MS, 1000). V().asAdmin().getGremlinLang()); assertEquals(Integer.valueOf(100), options.getBatchSize().get()); - assertEquals(Long.valueOf(1000), options.getTimeout().get()); + assertEquals(Long.valueOf(1000), options.getTimeoutMs().get()); } } diff --git a/gremlin-go/driver/client.go b/gremlin-go/driver/client.go index 9bc7a1ae293..c59ee0e80ce 100644 --- a/gremlin-go/driver/client.go +++ b/gremlin-go/driver/client.go @@ -324,7 +324,7 @@ func applyOptionsConfig(builder *RequestOptionsBuilder, config map[string]interf // via SetBindingsString in submitGremlinLang, and including it here would // trigger the mutual exclusion panic between SetBindings and SetBindingsString. setterMap := map[string]string{ - "evaluationTimeout": "SetEvaluationTimeout", + "timeoutMs": "SetTimeoutMs", "batchSize": "SetBatchSize", "userAgent": "SetUserAgent", "materializeProperties": "SetMaterializeProperties", diff --git a/gremlin-go/driver/gremlinlang_test.go b/gremlin-go/driver/gremlinlang_test.go index fad4cf4aa48..65e314049d6 100644 --- a/gremlin-go/driver/gremlinlang_test.go +++ b/gremlin-go/driver/gremlinlang_test.go @@ -599,7 +599,7 @@ func Test_GremlinLang(t *testing.T) { }, { assert: func(g *GraphTraversalSource) *GraphTraversal { - return g.WithStrategies(OptionsStrategy(map[string]interface{}{"evaluationTimeout": 500})).V().Count() + return g.WithStrategies(OptionsStrategy(map[string]interface{}{"timeoutMs": 500})).V().Count() }, // OptionsStrategy are now extracted into request message and is no longer sent with the script equals: "g.V().count()", diff --git a/gremlin-go/driver/request.go b/gremlin-go/driver/request.go index ebf375d49bf..d7ff5c96e23 100644 --- a/gremlin-go/driver/request.go +++ b/gremlin-go/driver/request.go @@ -56,8 +56,8 @@ func MakeStringRequest(stringGremlin string, traversalSource string, requestOpti newFields["bindings"] = requestOptions.bindingsString } - if requestOptions.evaluationTimeout != 0 { - newFields["evaluationTimeout"] = requestOptions.evaluationTimeout + if requestOptions.timeoutMs != 0 { + newFields["timeoutMs"] = requestOptions.timeoutMs } if requestOptions.batchSize != 0 { @@ -89,7 +89,7 @@ func MakeStringRequest(stringGremlin string, traversalSource string, requestOpti // allowedReqArgs contains the arguments that will be extracted from the // bytecode and sent with the request. var allowedReqArgs = map[string]bool{ - "evaluationTimeout": true, + "timeoutMs": true, "batchSize": true, "userAgent": true, "materializeProperties": true, diff --git a/gremlin-go/driver/requestOptions.go b/gremlin-go/driver/requestOptions.go index 53863276d92..cef5766fcd0 100644 --- a/gremlin-go/driver/requestOptions.go +++ b/gremlin-go/driver/requestOptions.go @@ -20,7 +20,7 @@ under the License. package gremlingo type RequestOptions struct { - evaluationTimeout int + timeoutMs int batchSize int userAgent string bindingsString string @@ -30,7 +30,7 @@ type RequestOptions struct { } type RequestOptionsBuilder struct { - evaluationTimeout int + timeoutMs int batchSize int userAgent string bindings map[string]interface{} @@ -40,8 +40,8 @@ type RequestOptionsBuilder struct { transactionId string } -func (builder *RequestOptionsBuilder) SetEvaluationTimeout(evaluationTimeout int) *RequestOptionsBuilder { - builder.evaluationTimeout = evaluationTimeout +func (builder *RequestOptionsBuilder) SetTimeoutMs(timeoutMs int) *RequestOptionsBuilder { + builder.timeoutMs = timeoutMs return builder } @@ -100,7 +100,7 @@ func (builder *RequestOptionsBuilder) AddBinding(key string, binding interface{} func (builder *RequestOptionsBuilder) Create() RequestOptions { requestOptions := new(RequestOptions) - requestOptions.evaluationTimeout = builder.evaluationTimeout + requestOptions.timeoutMs = builder.timeoutMs requestOptions.batchSize = builder.batchSize requestOptions.userAgent = builder.userAgent requestOptions.materializeProperties = builder.materializeProperties diff --git a/gremlin-go/driver/requestOptions_test.go b/gremlin-go/driver/requestOptions_test.go index 851e4d02e1a..9e528b82e1b 100644 --- a/gremlin-go/driver/requestOptions_test.go +++ b/gremlin-go/driver/requestOptions_test.go @@ -26,9 +26,9 @@ import ( ) func TestRequestOptions(t *testing.T) { - t.Run("Test RequestOptionsBuilder with custom evaluationTimeout", func(t *testing.T) { - r := new(RequestOptionsBuilder).SetEvaluationTimeout(1234).Create() - assert.Equal(t, 1234, r.evaluationTimeout) + t.Run("Test RequestOptionsBuilder with custom timeoutMs", func(t *testing.T) { + r := new(RequestOptionsBuilder).SetTimeoutMs(1234).Create() + assert.Equal(t, 1234, r.timeoutMs) }) t.Run("Test RequestOptionsBuilder with custom batchSize", func(t *testing.T) { r := new(RequestOptionsBuilder).SetBatchSize(123).Create() diff --git a/gremlin-go/driver/request_test.go b/gremlin-go/driver/request_test.go index f1752b0f6c7..0c3ecf37a90 100644 --- a/gremlin-go/driver/request_test.go +++ b/gremlin-go/driver/request_test.go @@ -34,10 +34,10 @@ func TestRequest(t *testing.T) { assert.Nil(t, r.Fields["bindings"]) }) - t.Run("Test makeStringRequest() with custom evaluationTimeout", func(t *testing.T) { + t.Run("Test makeStringRequest() with custom timeoutMs", func(t *testing.T) { r := MakeStringRequest("g.V()", "g", - new(RequestOptionsBuilder).SetEvaluationTimeout(1234).Create()) - assert.Equal(t, 1234, r.Fields["evaluationTimeout"]) + new(RequestOptionsBuilder).SetTimeoutMs(1234).Create()) + assert.Equal(t, 1234, r.Fields["timeoutMs"]) }) t.Run("Test makeStringRequest() with custom batchSize", func(t *testing.T) { diff --git a/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTChecker.groovy b/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTChecker.groovy index 35f08b610ac..fe4df46617a 100644 --- a/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTChecker.groovy +++ b/gremlin-groovy/src/main/groovy/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTChecker.groovy @@ -40,8 +40,7 @@ final class GremlinASTChecker { private static final AstBuilder astBuilder = new AstBuilder() public static final Result EMPTY_RESULT = new Result(0) - private static final List tokens = ["evaluationTimeout", "scriptEvaluationTimeout", - "ARGS_EVAL_TIMEOUT", "ARGS_SCRIPT_EVAL_TIMEOUT"] + private static final List tokens = ["timeoutMs", "TIMEOUT_MS"] /** * Parses a Gremlin script and extracts a {@code Result} containing properties that are relevant to the checker. @@ -125,7 +124,7 @@ final class GremlinASTChecker { //import org.apache.commons.lang.RandomStringUtils //rand = new java.util.Random() //engine = new groovy.text.SimpleTemplateEngine() -//baseScript = 'g.with("evaluationTimeout",1).V().out("$a").in().where(outE().has("weight",$b).count().is($c)).order().by("name",desc).limit($d).project("x","y").by("name").by(outE().fold());' +//baseScript = 'g.with("timeoutMs",1).V().out("$a").in().where(outE().has("weight",$b).count().is($c)).order().by("name",desc).limit($d).project("x","y").by("name").by(outE().fold());' //[1,10,50,100,500,1000,5000,10000].collect { // def binding = [a: RandomStringUtils.random(30), b: rand.nextDouble(), c: rand.nextInt(), d: rand.nextInt()] // def longScript = (0..>> plugins; - private final long evaluationTimeout; + private final long timeoutMs; private final Bindings globalBindings; private final ExecutorService executorService; private final ScheduledExecutorService scheduledExecutorService; @@ -101,7 +101,7 @@ private GremlinExecutor(final Builder builder, final boolean suppliedExecutor, this.afterTimeout = builder.afterTimeout; this.afterFailure = builder.afterFailure; this.plugins = builder.plugins; - this.evaluationTimeout = builder.evaluationTimeout; + this.timeoutMs = builder.timeoutMs; this.globalBindings = builder.globalBindings; this.gremlinScriptEngineManager = new CachedGremlinScriptEngineManager(builder.allowedEngineNames); @@ -264,7 +264,7 @@ public CompletableFuture eval(final String gremlin, final String languag public CompletableFuture eval(final String gremlin, final String language, final Bindings boundVars, final Long timeOut, final Function transformResult, final Consumer withResult) { final LifeCycle lifeCycle = LifeCycle.build() - .evaluationTimeoutOverride(timeOut) + .timeoutMsOverride(timeOut) .transformResult(transformResult) .withResult(withResult).create(); @@ -294,7 +294,7 @@ public CompletableFuture eval(final String gremlin, final String languag // options then allow that value to override what's provided on the lifecycle final Optional timeoutDefinedInScript = GremlinScriptChecker.parse(gremlin).getTimeout(); final long scriptEvalTimeOut = timeoutDefinedInScript.orElse( - lifeCycle.getEvaluationTimeoutOverride().orElse(evaluationTimeout)); + lifeCycle.getTimeoutMsOverride().orElse(timeoutMs)); final CompletableFuture evaluationFuture = new CompletableFuture<>(); final FutureTask evalFuture = new FutureTask<>(() -> { @@ -333,7 +333,7 @@ public CompletableFuture eval(final String gremlin, final String languag || root instanceof InterruptedIOException) { lifeCycle.getAfterTimeout().orElse(afterTimeout).accept(bindings, root); evaluationFuture.completeExceptionally(new TimeoutException( - String.format("Evaluation exceeded the configured 'evaluationTimeout' threshold of %s ms or evaluation was otherwise cancelled directly for request [%s]: %s", scriptEvalTimeOut, gremlin, root.getMessage()))); + String.format("Evaluation exceeded the configured 'timeoutMs' threshold of %s ms or evaluation was otherwise cancelled directly for request [%s]: %s", scriptEvalTimeOut, gremlin, root.getMessage()))); } else { lifeCycle.getAfterFailure().orElse(afterFailure).accept(bindings, root); evaluationFuture.completeExceptionally(root); @@ -352,7 +352,7 @@ public CompletableFuture eval(final String gremlin, final String languag final CompletableFuture ef = evaluationFutureRef.get(); if (ef != null) { ef.completeExceptionally(new TimeoutException( - String.format("Evaluation exceeded the configured 'evaluationTimeout' threshold of %s ms or evaluation was otherwise cancelled directly for request [%s]", scriptEvalTimeOut, gremlin))); + String.format("Evaluation exceeded the configured 'timeoutMs' threshold of %s ms or evaluation was otherwise cancelled directly for request [%s]", scriptEvalTimeOut, gremlin))); } } }, scriptEvalTimeOut, TimeUnit.MILLISECONDS); @@ -488,7 +488,7 @@ public static Builder build() { } public final static class Builder { - private long evaluationTimeout = 8000; + private long timeoutMs = 8000; private Map>> plugins = new HashMap<>(); @@ -544,11 +544,11 @@ public Builder globalBindings(final Bindings bindings) { * as well as any time needed for a post result transformation (if the transformation function is supplied * to the {@link GremlinExecutor#eval}). * - * @param evaluationTimeout Time in milliseconds that an evaluation is allowed to run and its + * @param timeoutMs Time in milliseconds that an evaluation is allowed to run and its * results potentially transformed. Set to zero to have no timeout set. */ - public Builder evaluationTimeout(final long evaluationTimeout) { - this.evaluationTimeout = evaluationTimeout; + public Builder timeoutMs(final long timeoutMs) { + this.timeoutMs = timeoutMs; return this; } @@ -655,7 +655,7 @@ public static class LifeCycle { private final Optional> afterSuccess; private final Optional> afterTimeout; private final Optional> afterFailure; - private final Optional evaluationTimeoutOverride; + private final Optional timeoutMsOverride; private LifeCycle(final Builder builder) { beforeEval = Optional.ofNullable(builder.beforeEval); @@ -664,11 +664,11 @@ private LifeCycle(final Builder builder) { afterSuccess = Optional.ofNullable(builder.afterSuccess); afterTimeout = Optional.ofNullable(builder.afterTimeout); afterFailure = Optional.ofNullable(builder.afterFailure); - evaluationTimeoutOverride = Optional.ofNullable(builder.evaluationTimeoutOverride); + timeoutMsOverride = Optional.ofNullable(builder.timeoutMsOverride); } - public Optional getEvaluationTimeoutOverride() { - return evaluationTimeoutOverride; + public Optional getTimeoutMsOverride() { + return timeoutMsOverride; } public Optional> getBeforeEval() { @@ -706,7 +706,7 @@ public static class Builder { private Consumer afterSuccess = null; private BiConsumer afterTimeout = null; private BiConsumer afterFailure = null; - private Long evaluationTimeoutOverride = null; + private Long timeoutMsOverride = null; /** * Specifies the function to execute prior to the script being evaluated. This function can also be @@ -783,11 +783,11 @@ public Builder afterFailure(final BiConsumer afterFailure) } /** - * An override to the global {@code evaluationTimeout} setting on the script engine. If this value + * An override to the global {@code timeoutMs} setting on the script engine. If this value * is set to {@code null} (the default) it will use the global setting. */ - public Builder evaluationTimeoutOverride(final Long evaluationTimeoutOverride) { - this.evaluationTimeoutOverride = evaluationTimeoutOverride; + public Builder timeoutMsOverride(final Long timeoutMsOverride) { + this.timeoutMsOverride = timeoutMsOverride; return this; } diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java index e1329e01b15..485cbac965c 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyCompilerGremlinPlugin.java @@ -93,7 +93,7 @@ public Builder enableThreadInterrupt(final boolean threadInterrupt) { /** * Introduces timed checks to loops and other portions of a script to provide an interrupt for a long running * script. This configuration should not be used in conjunction with the Gremlin Server which has its own - * {@code evaluationTimeout} which performs a similar task but in a more complete way specific to the + * {@code timeoutMs} which performs a similar task but in a more complete way specific to the * server. Configuring both may lead to inconsistent timeout errors returning from the server. This * configuration should only be used if configuring a standalone instance fo the {@link GremlinGroovyScriptEngine}. */ diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorOverGraphTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorOverGraphTest.java index 840c0bb0c25..cbe2000541f 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorOverGraphTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorOverGraphTest.java @@ -54,7 +54,7 @@ public void shouldOverrideTimeoutWithinScript() throws Exception { final ExecutorService evalExecutor = Executors.newSingleThreadExecutor(testingThreadFactory); final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(60000) + .timeoutMs(60000) .afterSuccess(b -> { final GraphTraversalSource ig = (GraphTraversalSource) b.get("g"); if (ig.getGraph().features().graph().supportsTransactions()) @@ -66,11 +66,11 @@ public void shouldOverrideTimeoutWithinScript() throws Exception { bindings.put("g", g); try { - gremlinExecutor.eval("g.with('evaluationTimeout',100).V().repeat(both()).toList()", bindings).get(); + gremlinExecutor.eval("g.with('timeoutMs',100).V().repeat(both()).toList()", bindings).get(); fail("Should have timed out"); } catch (ExecutionException ex) { // should die in 100ms not 60000 - assertThat(ex.getCause().getMessage(), startsWith("Evaluation exceeded the configured 'evaluationTimeout' threshold of 100 ms")); + assertThat(ex.getCause().getMessage(), startsWith("Evaluation exceeded the configured 'timeoutMs' threshold of 100 ms")); } } diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java index 8b0c180ee28..115c8fda235 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/engine/GremlinExecutorTest.java @@ -267,7 +267,7 @@ public void shouldTimeoutSleepingScript() throws Exception { final CountDownLatch timeOutCount = new CountDownLatch(1); final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(250) + .timeoutMs(250) .afterFailure((b, e) -> failureCalled.set(true)) .afterSuccess((b) -> successCalled.set(true)) .afterTimeout((b) -> timeOutCount.countDown()).create(); @@ -294,7 +294,7 @@ public void shouldTimeoutSleepingEval() throws Exception { final CountDownLatch timeOutCount = new CountDownLatch(1); final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(250) + .timeoutMs(250) .afterFailure((b, e) -> failureCalled.set(true)) .afterSuccess((b) -> successCalled.set(true)) .afterTimeout((b) -> timeOutCount.countDown()).create(); @@ -321,13 +321,13 @@ public void shouldTimeoutSleepingScriptViaOverrideOnLifeCycle() throws Exception final CountDownLatch timeOutCount = new CountDownLatch(1); final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(10000) + .timeoutMs(10000) .afterFailure((b, e) -> failureCalled.set(true)) .afterSuccess((b) -> successCalled.set(true)) .afterTimeout((b) -> timeOutCount.countDown()).create(); try { final GremlinExecutor.LifeCycle lifeCycle = GremlinExecutor.LifeCycle.build() - .evaluationTimeoutOverride(250L).create(); + .timeoutMsOverride(250L).create(); gremlinExecutor.eval("Thread.sleep(1000);10", "gremlin-groovy", new SimpleBindings(), lifeCycle).get(); fail("This script should have timed out with an exception"); } catch (Exception ex) { @@ -350,13 +350,13 @@ public void shouldTimeoutSleepingEvalViaOverrideOnLifeCycle() throws Exception { final CountDownLatch timeOutCount = new CountDownLatch(1); final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(10000) + .timeoutMs(10000) .afterFailure((b, e) -> failureCalled.set(true)) .afterSuccess((b) -> successCalled.set(true)) .afterTimeout((b) -> timeOutCount.countDown()).create(); try { final GremlinExecutor.LifeCycle lifeCycle = GremlinExecutor.LifeCycle.build() - .evaluationTimeoutOverride(100L).create(); + .timeoutMsOverride(100L).create(); gremlinExecutor.eval("Thread.sleep(9000);10", "gremlin-groovy", new SimpleBindings(), lifeCycle).get(); fail("This script should have timed out with an exception"); } catch (Exception ex) { @@ -460,28 +460,28 @@ public void shouldCallSuccess() throws Exception { @Test public void shouldCancelTimeoutOnSuccessfulScript() throws Exception { - final long evaluationTimeout = 5_000; + final long timeoutMs = 5_000; final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(evaluationTimeout) + .timeoutMs(timeoutMs) .create(); final long now = System.currentTimeMillis(); assertEquals(2, gremlinExecutor.eval("1+1").get()); gremlinExecutor.close(); - assertTrue(System.currentTimeMillis() - now < evaluationTimeout); + assertTrue(System.currentTimeMillis() - now < timeoutMs); } @Test public void shouldCancelTimeoutOnSuccessfulEval() throws Exception { - final long evaluationTimeout = 5_000; + final long timeoutMs = 5_000; final GremlinExecutor gremlinExecutor = GremlinExecutor.build() - .evaluationTimeout(evaluationTimeout) + .timeoutMs(timeoutMs) .create(); final long now = System.currentTimeMillis(); assertEquals(2, gremlinExecutor.eval("1+1").get()); gremlinExecutor.close(); - assertTrue(System.currentTimeMillis() - now < evaluationTimeout); + assertTrue(System.currentTimeMillis() - now < timeoutMs); } @Test diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTCheckerTest.java b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTCheckerTest.java index 8d913232b4b..9b55adc3774 100644 --- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTCheckerTest.java +++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/ast/GremlinASTCheckerTest.java @@ -41,49 +41,49 @@ public void shouldReturnEmpty() { @Test(expected = MultipleCompilationErrorsException.class) public void shouldNotParse() { - GremlinASTChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows'))"); + GremlinASTChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows'))"); } @Test public void shouldNotFindTimeoutCozWeCommentedItOut() { assertEquals(Optional.empty(), GremlinASTChecker.parse("g.\n" + - " // with('evaluationTimeout', 1000L).\n" + + " // with('timeoutMs', 1000L).\n" + " with(true).V().out('knows')").getTimeout()); } @Test public void shouldIdentifyTimeoutAsStringKey() { - assertEquals(1000, GremlinASTChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinASTChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @Test public void shouldIdentifyTimeoutAsTokenKey() { - assertEquals(1000, GremlinASTChecker.parse("g.with(Tokens.ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinASTChecker.parse("g.with(Tokens.TIMEOUT_MS, 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @Test public void shouldIdentifyTimeoutAsTokenKeyWithoutClassName() { - assertEquals(1000, GremlinASTChecker.parse("g.with(ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')"). + assertEquals(1000, GremlinASTChecker.parse("g.with(TIMEOUT_MS, 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @Test public void shouldIdentifyMultipleTimeouts() { - assertEquals(6000, GremlinASTChecker.parse("g.with('evaluationTimeout', 1000L).with(true).V().out('knows');" + - "g.with('evaluationTimeout', 1000L).with(true).V().out('knows')\n" + - " //g.with('evaluationTimeout', 1000L).with(true).V().out('knows')\n" + - " g.with('evaluationTimeout', 1000L).with(true).V().out('knows')\n" + - " g.with(Tokens.ARGS_SCRIPT_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')\n" + - " g.with(ARGS_EVAL_TIMEOUT, 1000L).with(true).V().out('knows')\n" + - " g.with('scriptEvaluationTimeout', 1000L).with(true).V().out('knows')"). + assertEquals(6000, GremlinASTChecker.parse("g.with('timeoutMs', 1000L).with(true).V().out('knows');" + + "g.with('timeoutMs', 1000L).with(true).V().out('knows')\n" + + " //g.with('timeoutMs', 1000L).with(true).V().out('knows')\n" + + " g.with('timeoutMs', 1000L).with(true).V().out('knows')\n" + + " g.with(Tokens.TIMEOUT_MS, 1000L).with(true).V().out('knows')\n" + + " g.with(TIMEOUT_MS, 1000L).with(true).V().out('knows')\n" + + " g.with('timeoutMs', 1000L).with(true).V().out('knows')"). getTimeout().get().longValue()); } @Test public void shouldParseLong() { - assertEquals(1000, GremlinASTChecker.parse("g.with('evaluationTimeout', 1000L).addV().property(id, 'blue').as('b').\n" + + assertEquals(1000, GremlinASTChecker.parse("g.with('timeoutMs', 1000L).addV().property(id, 'blue').as('b').\n" + " addV().property(id, 'orange').as('o').\n" + " addV().property(id, 'red').as('r').\n" + " addV().property(id, 'green').as('g').\n" + diff --git a/gremlin-js/gremlin-javascript/lib/driver/client.ts b/gremlin-js/gremlin-javascript/lib/driver/client.ts index b13493b208e..1b3809f75da 100644 --- a/gremlin-js/gremlin-javascript/lib/driver/client.ts +++ b/gremlin-js/gremlin-javascript/lib/driver/client.ts @@ -25,7 +25,7 @@ export type RequestOptions = { bindings?: any; language?: string; accept?: string; - evaluationTimeout?: number; + timeoutMs?: number; batchSize?: number; userAgent?: string; materializeProperties?: string; @@ -123,8 +123,8 @@ export default class Client { if (requestOptions?.materializeProperties) { requestBuilder.addMaterializeProperties(requestOptions.materializeProperties); } - if (requestOptions?.evaluationTimeout) { - requestBuilder.addTimeoutMillis(requestOptions.evaluationTimeout); + if (requestOptions?.timeoutMs) { + requestBuilder.addTimeoutMillis(requestOptions.timeoutMs); } // Per-request value wins (including an explicit `false`); otherwise apply the // connection-level default only when it is true. diff --git a/gremlin-js/gremlin-javascript/lib/driver/driver-remote-connection.ts b/gremlin-js/gremlin-javascript/lib/driver/driver-remote-connection.ts index 78caf3bec89..4883fb96448 100644 --- a/gremlin-js/gremlin-javascript/lib/driver/driver-remote-connection.ts +++ b/gremlin-js/gremlin-javascript/lib/driver/driver-remote-connection.ts @@ -83,8 +83,7 @@ export default class DriverRemoteConnection extends RemoteConnection { if (strategies.length > 0) { requestOptions = {}; const allowedKeys = [ - 'evaluationTimeout', - 'scriptEvaluationTimeout', + 'timeoutMs', 'batchSize', 'requestId', 'userAgent', diff --git a/gremlin-js/gremlin-javascript/test/integration/traversal-test.js b/gremlin-js/gremlin-javascript/test/integration/traversal-test.js index 56b1744b729..32d1a5f4ec7 100644 --- a/gremlin-js/gremlin-javascript/test/integration/traversal-test.js +++ b/gremlin-js/gremlin-javascript/test/integration/traversal-test.js @@ -322,8 +322,8 @@ describe('Traversal', function () { }); return g.V().out().iterate().then(() => assert.fail("should have tanked"), (err) => assert.strictEqual(err.statusCode, 500)); }); - it('should allow with_(evaluationTimeout,10)', function() { - const g = anon.traversal().with_(connection).with_('x').with_('evaluationTimeout', 10); + it('should allow with_(timeoutMs,10)', function() { + const g = anon.traversal().with_(connection).with_('x').with_('timeoutMs', 10); return g.V().repeat(__.both()).iterate().then(() => assert.fail("should have tanked"), (err) => assert.strictEqual(err.statusCode, 500)); }); it('should allow SeedStrategy', function () { diff --git a/gremlin-js/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js b/gremlin-js/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js index 4c2a07b11ea..a21961d4cd2 100644 --- a/gremlin-js/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js +++ b/gremlin-js/gremlin-javascript/test/unit/graphbinary/GraphBinaryWriter-test.js @@ -52,16 +52,16 @@ describe('GraphBinaryWriter', () => { }); describe('fields with entries', () => { - it('map with evaluationTimeout entry', () => { + it('map with timeoutMs entry', () => { const fields = new Map(); - fields.set('evaluationTimeout', 1000); + fields.set('timeoutMs', 1000); const result = writer.writeRequest({ gremlin: 'g.V()', fields }); const expected = Buffer.from([ 0x84, // version 0x00, 0x00, 0x00, 0x01, // map length=1 0x03, 0x00, // key type_code=STRING, value_flag=0x00 - 0x00, 0x00, 0x00, 0x11, // key string length=17 - 0x65, 0x76, 0x61, 0x6C, 0x75, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x54, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, // "evaluationTimeout" + 0x00, 0x00, 0x00, 0x09, // key string length=9 + 0x74, 0x69, 0x6D, 0x65, 0x6F, 0x75, 0x74, 0x4D, 0x73, // "timeoutMs" 0x01, 0x00, // value type_code=INT, value_flag=0x00 0x00, 0x00, 0x03, 0xE8, // value int=1000 0x00, 0x00, 0x00, 0x05, // gremlin string length=5 diff --git a/gremlin-js/gremlin-javascript/test/unit/gremlin-lang-test.js b/gremlin-js/gremlin-javascript/test/unit/gremlin-lang-test.js index a04039d4c63..69f3c7d7b75 100644 --- a/gremlin-js/gremlin-javascript/test/unit/gremlin-lang-test.js +++ b/gremlin-js/gremlin-javascript/test/unit/gremlin-lang-test.js @@ -225,9 +225,9 @@ describe('GremlinLang', function () { // #93 [g.withStrategies(new ReadOnlyStrategy(), new SubgraphStrategy({vertices: __.has('region','US-TX')})).V().count(), "g.withStrategies(ReadOnlyStrategy,new SubgraphStrategy(vertices:__.has('region','US-TX'))).V().count()"], // #94 - OptionsStrategy extracted, not serialized - [g.with_('evaluationTimeout',500).V().count(), 'g.V().count()'], + [g.with_('timeoutMs',500).V().count(), 'g.V().count()'], // #95 - OptionsStrategy extracted, not serialized - [g.withStrategies(new OptionsStrategy({evaluationTimeout: 500})).V().count(), 'g.V().count()'], + [g.withStrategies(new OptionsStrategy({timeoutMs: 500})).V().count(), 'g.V().count()'], // #96 [g.withStrategies(new PartitionStrategy({partitionKey: '_partition', writePartition: 'a', readPartitions: ['a','b']})).addV('test'), "g.withStrategies(new PartitionStrategy(partitionKey:'_partition',writePartition:'a',readPartitions:['a','b'])).addV('test')"], // #97 @@ -372,7 +372,7 @@ describe('GremlinLang', function () { }); it('should handle OptionsStrategy extraction', function () { - const t = g.with_('evaluationTimeout', 500).V().count(); + const t = g.with_('timeoutMs', 500).V().count(); assert.strictEqual(t.getGremlinLang().getGremlin(), 'g.V().count()'); assert.strictEqual(t.getGremlinLang().getOptionsStrategies().length, 1); }); diff --git a/gremlin-python/src/main/python/gremlin_python/driver/request.py b/gremlin-python/src/main/python/gremlin_python/driver/request.py index 119c76c0a94..5a91c6e638b 100644 --- a/gremlin-python/src/main/python/gremlin_python/driver/request.py +++ b/gremlin-python/src/main/python/gremlin_python/driver/request.py @@ -24,5 +24,5 @@ 'RequestMessage', ['fields', 'gremlin']) Tokens = ['batchSize', 'bindings', 'g', 'gremlin', 'language', - 'evaluationTimeout', 'materializeProperties', 'timeoutMs', 'userAgent', 'bulkResults', + 'materializeProperties', 'timeoutMs', 'userAgent', 'bulkResults', 'transactionId'] diff --git a/gremlin-python/src/main/python/tests/integration/driver/test_driver_remote_connection.py b/gremlin-python/src/main/python/tests/integration/driver/test_driver_remote_connection.py index de9c7bf3aef..5fba346e22d 100644 --- a/gremlin-python/src/main/python/tests/integration/driver/test_driver_remote_connection.py +++ b/gremlin-python/src/main/python/tests/integration/driver/test_driver_remote_connection.py @@ -46,20 +46,20 @@ def test_bulk_request_option(self, remote_connection): def test_extract_request_options(self, remote_connection): g = traversal().with_(remote_connection) - t = g.with_("evaluationTimeout", 1000).with_("batchSize", 100).V().count() + t = g.with_("timeoutMs", 1000).with_("batchSize", 100).V().count() assert remote_connection.extract_request_options(t.gremlin_lang) == {'batchSize': 100, - 'evaluationTimeout': 1000, + 'timeoutMs': 1000, 'bulkResults': True} assert 6 == t.to_list()[0] @pytest.mark.skip(reason="TINKERPOP-3126: g.V() with a variable/parameter argument fails to parse in gremlin-lang") def test_extract_request_options_with_params(self, remote_connection): g = traversal().with_(remote_connection) - t = g.with_("evaluationTimeout", + t = g.with_("timeoutMs", 1000).with_("batchSize", 100).with_("userAgent", "test").V(GValue('ids', [1, 2, 3])).count() assert remote_connection.extract_request_options(t.gremlin_lang) == {'batchSize': 100, - 'evaluationTimeout': 1000, + 'timeoutMs': 1000, 'userAgent': 'test', 'bulkResults': True, 'bindings': "['ids':[1,2,3]]"} diff --git a/gremlin-python/src/main/python/tests/unit/driver/test_client_options.py b/gremlin-python/src/main/python/tests/unit/driver/test_client_options.py index 215891e9661..e4b8ee8e180 100644 --- a/gremlin-python/src/main/python/tests/unit/driver/test_client_options.py +++ b/gremlin-python/src/main/python/tests/unit/driver/test_client_options.py @@ -115,10 +115,10 @@ def test_resubmit_does_not_accumulate_fields(self): original = RequestMessage(fields={'g': 'g'}, gremlin='g.V()') - client.submit_async(original, request_options={'evaluationTimeout': 1000}) + client.submit_async(original, request_options={'timeoutMs': 1000}) # The caller's original message must be untouched. assert 'batchSize' not in original.fields - assert 'evaluationTimeout' not in original.fields + assert 'timeoutMs' not in original.fields assert original.fields == {'g': 'g'} # Resubmit the same message with different options; it must not carry @@ -126,7 +126,7 @@ def test_resubmit_does_not_accumulate_fields(self): client.submit_async(original, request_options={'batchSize': 5}) sent = conn.write.call_args[0][0] assert sent.fields['batchSize'] == 5 - assert 'evaluationTimeout' not in sent.fields + assert 'timeoutMs' not in sent.fields # And the original is still pristine. assert original.fields == {'g': 'g'} diff --git a/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py b/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py index 2f176ae1008..137e03bd0a6 100644 --- a/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py +++ b/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py @@ -362,11 +362,11 @@ def test_gremlin_lang(self): "g.withStrategies(ReadOnlyStrategy,new SubgraphStrategy(vertices:__.has('region','US-TX'))).V().count()"]) # 95 Note with_() options are now extracted into request message and is no longer sent with the script - tests.append([g.with_('evaluationTimeout', 500).V().count(), + tests.append([g.with_('timeoutMs', 500).V().count(), "g.V().count()"]) # 96 Note OptionsStrategy are now extracted into request message and is no longer sent with the script - tests.append([g.with_strategies(OptionsStrategy(evaluationTimeout=500)).V().count(), + tests.append([g.with_strategies(OptionsStrategy(timeoutMs=500)).V().count(), "g.V().count()"]) # 97 diff --git a/gremlin-server/conf/gremlin-server-airroutes.yaml b/gremlin-server/conf/gremlin-server-airroutes.yaml index c4c4529f8fd..42e07c17e16 100644 --- a/gremlin-server/conf/gremlin-server-airroutes.yaml +++ b/gremlin-server/conf/gremlin-server-airroutes.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-server/conf/gremlin-server-classic.yaml b/gremlin-server/conf/gremlin-server-classic.yaml index b421c3f2763..495b734f4bf 100644 --- a/gremlin-server/conf/gremlin-server-classic.yaml +++ b/gremlin-server/conf/gremlin-server-classic.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 graphs: { graph: conf/tinkergraph-empty.properties} lifecycleHooks: diff --git a/gremlin-server/conf/gremlin-server-modern-readonly.yaml b/gremlin-server/conf/gremlin-server-modern-readonly.yaml index 2ef586eef08..698c2538071 100644 --- a/gremlin-server/conf/gremlin-server-modern-readonly.yaml +++ b/gremlin-server/conf/gremlin-server-modern-readonly.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 graphs: { graph: { configuration: conf/tinkergraph-empty.properties, diff --git a/gremlin-server/conf/gremlin-server-modern.yaml b/gremlin-server/conf/gremlin-server-modern.yaml index 4a1fe9803ec..869d72f5f89 100644 --- a/gremlin-server/conf/gremlin-server-modern.yaml +++ b/gremlin-server/conf/gremlin-server-modern.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-server/conf/gremlin-server-rest-modern.yaml b/gremlin-server/conf/gremlin-server-rest-modern.yaml index 3b66b58177d..7389b86f5e4 100644 --- a/gremlin-server/conf/gremlin-server-rest-modern.yaml +++ b/gremlin-server/conf/gremlin-server-rest-modern.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-server/conf/gremlin-server-rest-secure.yaml b/gremlin-server/conf/gremlin-server-rest-secure.yaml index 642033b31d1..f3c310c9223 100644 --- a/gremlin-server/conf/gremlin-server-rest-secure.yaml +++ b/gremlin-server/conf/gremlin-server-rest-secure.yaml @@ -25,7 +25,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-server/conf/gremlin-server-secure.yaml b/gremlin-server/conf/gremlin-server-secure.yaml index 644b275f702..836e8948ad2 100644 --- a/gremlin-server/conf/gremlin-server-secure.yaml +++ b/gremlin-server/conf/gremlin-server-secure.yaml @@ -25,7 +25,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-server/conf/gremlin-server-spark.yaml b/gremlin-server/conf/gremlin-server-spark.yaml index e088106d323..9f79e87f660 100644 --- a/gremlin-server/conf/gremlin-server-spark.yaml +++ b/gremlin-server/conf/gremlin-server-spark.yaml @@ -40,7 +40,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/hadoop-gryo.properties} diff --git a/gremlin-server/conf/gremlin-server-transaction.yaml b/gremlin-server/conf/gremlin-server-transaction.yaml index 6db62912a94..1227adaacf3 100644 --- a/gremlin-server/conf/gremlin-server-transaction.yaml +++ b/gremlin-server/conf/gremlin-server-transaction.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkertransactiongraph-empty.properties} diff --git a/gremlin-server/conf/gremlin-server.yaml b/gremlin-server/conf/gremlin-server.yaml index bb93d8e1f36..508f05e8171 100644 --- a/gremlin-server/conf/gremlin-server.yaml +++ b/gremlin-server/conf/gremlin-server.yaml @@ -17,7 +17,7 @@ host: localhost port: 8182 -evaluationTimeout: 30000 +timeoutMs: 30000 channelizer: org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer graphs: { graph: conf/tinkergraph-empty.properties} diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Context.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Context.java index 598514ed6c0..9d0d73c4901 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Context.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Context.java @@ -103,7 +103,7 @@ public ScheduledFuture getTimeoutExecutor() { /** * The timeout for the request. If the request is a script it examines the script for a timeout setting using * {@code with()}. If that is not found then it examines the request itself to see if the timeout is provided by - * {@link Tokens#TIMEOUT_MS}. If that is not provided then the {@link Settings#evaluationTimeout} is + * {@link Tokens#TIMEOUT_MS}. If that is not provided then the {@link Settings#timeoutMs} is * utilized as the default. */ public long getRequestTimeout() { @@ -208,10 +208,9 @@ public GremlinExecutor getGremlinExecutor() { } private long determineTimeout() { - // timeout override - handle both deprecated and newly named configuration. earlier logic should prevent - // both configurations from being submitted at the same time + // per-request timeout override falls back to the server-configured default when not supplied final Long timeoutMs = requestMessage.getField(Tokens.TIMEOUT_MS); - final long seto = (null != timeoutMs) ? timeoutMs : settings.getEvaluationTimeout(); + final long seto = (null != timeoutMs) ? timeoutMs : settings.getTimeoutMs(); // override the timeout if the lifecycle has a value assigned. if the script contains with(timeout) // options then allow that value to override what's provided on the lifecycle diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java index c8f718a774f..a6a18bc2d39 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/Settings.java @@ -105,9 +105,10 @@ public Settings() { public int threadPoolBoss = 1; /** - * Time in milliseconds to wait for a request to complete execution. Defaults to 30000. + * The maximum time in milliseconds that a request is allowed to execute on the server before it times out. + * Serves as the server-wide default which may be overridden on a per-request basis. Defaults to 30000. */ - public long evaluationTimeout = 30000L; + public long timeoutMs = 30000L; /** * Number of items in a particular resultset to iterate and serialize prior to pushing the data down the wire @@ -188,7 +189,7 @@ public Settings() { * Time in milliseconds that a transaction can remain idle (no operation running or queued) before it is * automatically rolled back. This prevents resource leaks from abandoned transactions. The idle timer is suspended * while an operation is in progress, so a long-running operation does not trip it (its duration is instead bounded - * by {@link #evaluationTimeout}). Set to {@code 0} to disable idle reclamation entirely. Default is 60000 + * by {@link #timeoutMs}). Set to {@code 0} to disable idle reclamation entirely. Default is 60000 * (1 minute). */ public long idleTransactionTimeout = 60000L; @@ -210,7 +211,7 @@ public Settings() { * {@link #idleTransactionTimeout} (which only reclaims idle transactions), this cap fires even while an operation is * running, interrupting it and rolling the transaction back, so it bounds how long a single transaction can hold its * dedicated worker thread and concurrency slot. The bound on transaction lifetime and slot occupancy is absolute; - * the bound on thread occupancy is best-effort in the same way {@link #evaluationTimeout} is, since interrupting a + * the bound on thread occupancy is best-effort in the same way {@link #timeoutMs} is, since interrupting a * running operation only takes effect when it reaches an interruptible point. Set to {@code 0} to disable the cap. * Default is 600000 (10 minutes). */ @@ -330,8 +331,8 @@ public Optional optionalSsl() { return Optional.ofNullable(ssl); } - public long getEvaluationTimeout() { - return evaluationTimeout; + public long getTimeoutMs() { + return timeoutMs; } /** diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java index eed9428c1d9..098541d3790 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandler.java @@ -192,10 +192,9 @@ public void channelRead0(final ChannelHandlerContext ctx, final RequestMessage r final Optional txForRequest = isTransactionalOp ? transactionManager.get(requestCtx.getTransactionId()) : Optional.empty(); - // timeout override - handle both deprecated and newly named configuration. earlier logic should prevent - // both configurations from being submitted at the same time + // per-request timeout override falls back to the server-configured default when not supplied final Long timeoutMs = requestMessage.getField(Tokens.TIMEOUT_MS); - final long seto = (null != timeoutMs) ? timeoutMs : requestCtx.getSettings().getEvaluationTimeout(); + final long seto = (null != timeoutMs) ? timeoutMs : requestCtx.getSettings().getTimeoutMs(); final FutureTask evalFuture = new FutureTask<>(() -> { try { @@ -323,7 +322,7 @@ public void channelRead0(final ChannelHandlerContext ctx, final RequestMessage r executionFuture.cancel(true); // If the lifetime cap fired for this same operation (it flags the Context before interrupting), // report the cap's 504 even when this eval-timeout task is the one that writes - so a cap-kill is - // never mislabeled as a generic "increase evaluationTimeout" 500 just because of writer ordering. + // never mislabeled as a generic "increase timeoutMs" 500 just because of writer ordering. coordinator.writeError(requestCtx.isClosedByLifetimeCap() ? GremlinError.transactionTimeout(requestCtx.getTransactionId(), "execute") : GremlinError.timeout(requestMessage)); @@ -403,7 +402,7 @@ GremlinError formErrorResponseMessage(Throwable t, RequestMessage requestMessage // An interrupt here is normally an evaluation timeout, but it is also how a transaction's absolute lifetime // cap stops a running operation. In the cap case the transaction flagged this request's Context before // interrupting, so report an accurate transaction-timeout (504) rather than the generic "increase - // evaluationTimeout" error (500), whose advice would be misleading for a lifetime-cap kill. + // timeoutMs" error (500), whose advice would be misleading for a lifetime-cap kill. if (requestCtx != null && requestCtx.isClosedByLifetimeCap()) { return GremlinError.transactionTimeout(requestCtx.getTransactionId(), "execute"); } diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/transaction/UnmanagedTransaction.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/transaction/UnmanagedTransaction.java index 25bd36ee5cc..486d41ad255 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/transaction/UnmanagedTransaction.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/transaction/UnmanagedTransaction.java @@ -212,7 +212,7 @@ public Future submit(final FutureTask task, final Context context) { * Invoked from {@link SingleThreadTransactionExecutor#beforeExecute} and, as a backstop, from {@link #submit}. *

* A long-running operation must not trip the idle timeout: while an operation is in progress the idle timer is - * simply not armed (the operation's own duration is bounded by the per-request {@code evaluationTimeout} instead). + * simply not armed (the operation's own duration is bounded by the per-request {@code timeoutMs} instead). */ private void cancelIdleTimer() { idleFuture.updateAndGet(future -> { diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinError.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinError.java index e0e74c26d0c..027a8868cdb 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinError.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/GremlinError.java @@ -100,7 +100,7 @@ public static GremlinError parsing(final GremlinParserException error) { // execution errors public static GremlinError timeout(final RequestMessage requestMessage ) { - final String message = String.format("A timeout occurred during traversal evaluation of [%s] - consider increasing the limit given to evaluationTimeout", + final String message = String.format("A timeout occurred during traversal evaluation of [%s] - consider increasing the limit given to timeoutMs (the maximum time in milliseconds a request may execute on the server)", requestMessage); return new GremlinError(HttpResponseStatus.INTERNAL_SERVER_ERROR, message, "ServerTimeoutExceededException"); } diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java index b8ff46ab59b..82fe8f82dff 100644 --- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java +++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/util/ServerGremlinExecutor.java @@ -143,7 +143,7 @@ public ServerGremlinExecutor(final Settings settings, final ExecutorService grem allowedEngines.add("gremlin-lang"); final GremlinExecutor.Builder gremlinExecutorBuilder = GremlinExecutor.build() - .evaluationTimeout(settings.getEvaluationTimeout()) + .timeoutMs(settings.getTimeoutMs()) .afterFailure((b, e) -> this.graphManager.rollbackAll()) .beforeEval(b -> this.graphManager.rollbackAll()) .afterTimeout((b, e) -> this.graphManager.rollbackAll()) @@ -179,7 +179,7 @@ public ServerGremlinExecutor(final Settings settings, final ExecutorService grem if (!engineName.equals("gremlin-lang") && !engineName.equals("groovy-test")) { // use no timeout on the engine initialization - perhaps this can be a configuration later final GremlinExecutor.LifeCycle lifeCycle = GremlinExecutor.LifeCycle.build(). - evaluationTimeoutOverride(0L).create(); + timeoutMsOverride(0L).create(); gremlinExecutor.eval("1+1", engineName, new SimpleBindings(Collections.emptyMap()), lifeCycle).join(); } diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java index b8fc66423fb..63d4813f1a4 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/AbstractGremlinServerIntegrationTest.java @@ -69,14 +69,14 @@ public Settings overrideSettings(final Settings settings) { } /** - * This method may be called after {@link #startServer()} to (re-)set the evaluation timeout in + * This method may be called after {@link #startServer()} to (re-)set the request timeout in * the running server. - * @param timeoutInMillis new evaluation timeout + * @param timeoutInMillis new request timeout in milliseconds */ - protected void overrideEvaluationTimeout(final long timeoutInMillis) { + protected void overrideTimeoutMs(final long timeoutInMillis) { // Note: overriding settings in a running server is not guaranteed to work for all settings. - // It works for the evaluation timeout, though, because GremlinExecutor is re-created for each evaluation. - overriddenSettings.evaluationTimeout = timeoutInMillis; + // It works for the timeout, though, because GremlinExecutor is re-created for each evaluation. + overriddenSettings.timeoutMs = timeoutInMillis; } public InputStream getSettingsInputStream() { diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ClientWithOptionsIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ClientWithOptionsIntegrateTest.java index 204bc6a7c4b..7abb97e8134 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ClientWithOptionsIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ClientWithOptionsIntegrateTest.java @@ -48,7 +48,7 @@ public void shouldTimeOutnonAliasedClientSendingByteCode() { final Client client = cluster.connect(); final GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(client, "ggrateful")); assertThrows(CompletionException.class, () -> { - final List res = g.with("evaluationTimeout", 1).V().both().both().both().toList(); + final List res = g.with("timeoutMs", 1).V().both().both().both().toList(); fail("Failed to time out. Result: " + res); }); } @@ -58,7 +58,7 @@ public void shouldTimeOutAliasedClientSubmittingScript() { final Cluster cluster = TestClientFactory.build().create(); final Client client = cluster.connect().alias("ggrateful"); assertThrows(ExecutionException.class, () -> { - final List res = client.submit("g.with(\"evaluationTimeout\", 1).V().both().both().both();").all().get(); + final List res = client.submit("g.with(\"timeoutMs\", 1).V().both().both().both();").all().get(); fail("Failed to time out. Result: " + res); }); } @@ -68,7 +68,7 @@ public void shouldTimeOutNonAliasedClientSubmittingScript() { final Cluster cluster = TestClientFactory.build().create(); final Client client = cluster.connect(); assertThrows(ExecutionException.class, () -> { - final List res = client.submit("ggrateful.with(\"evaluationTimeout\", 1).V().both().both().both();").all().get(); + final List res = client.submit("ggrateful.with(\"timeoutMs\", 1).V().both().both().both();").all().get(); fail("Failed to time out. Result: " + res); }); } diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ContextTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ContextTest.java index ba55728d9fb..5cb8344e098 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ContextTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/ContextTest.java @@ -53,7 +53,7 @@ public void shouldParseParametersFromScriptRequest() { final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); final RequestMessage request = - RequestMessage.build("g.with('evaluationTimeout', 1000).with(true).with('materializeProperties', 'tokens').V().out('knows')") + RequestMessage.build("g.with('timeoutMs', 1000).with(true).with('materializeProperties', 'tokens').V().out('knows')") .create(); final Settings settings = new Settings(); final Context context = new Context(request, ctx, settings, null, null, null); @@ -67,7 +67,7 @@ public void shouldSkipInvalidMaterializePropertiesParameterFromScriptRequest() { final ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); final RequestMessage request = - RequestMessage.build("g.with('evaluationTimeout', 1000).with(true).with('materializeProperties', 'some-invalid-value').V().out('knows')") + RequestMessage.build("g.with('timeoutMs', 1000).with(true).with('materializeProperties', 'some-invalid-value').V().out('knows')") .create(); final Settings settings = new Settings(); final Context context = new Context(request, ctx, settings, null, null, null); diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java index 83118a179a9..44872310b04 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinDriverIntegrateTest.java @@ -156,12 +156,12 @@ public Settings overrideSettings(final Settings settings) { useTinkerTransactionGraph(settings); break; case "shouldProcessSessionRequestsInOrderAfterTimeout": - settings.evaluationTimeout = 250; + settings.timeoutMs = 250; settings.threadPoolWorker = 1; break; case "shouldProcessTraversalInterruption": case "shouldProcessEvalInterruption": - settings.evaluationTimeout = 1500; + settings.timeoutMs = 1500; break; } diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java index c67a0add0d3..8965360a329 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpIntegrateTest.java @@ -138,8 +138,8 @@ public Settings overrideSettings(final Settings settings) { case "should200OnPOSTWithAuthorizationHeader": configureForAuthentication(settings); break; - case "should500OnPOSTWithEvaluationTimeout": - settings.evaluationTimeout = 5000; + case "should500OnPOSTWithTimeoutMs": + settings.timeoutMs = 5000; settings.gremlinPool = 1; break; case "shouldRespectCorsAllowedOrigins": @@ -924,7 +924,7 @@ public void should200OnPOSTWithGremlinQueryStringArgumentCallingDatetimeFunction } @Test(timeout = 10000) // Add test timeout to prevent incorrect timeout behavior from stopping test run. - public void should500OnPOSTWithEvaluationTimeout() throws Exception { + public void should500OnPOSTWithTimeoutMs() throws Exception { // Related to TINKERPOP-2769. This is a similar test to the one for the WebSocketChannelizer. final CloseableHttpClient firstClient = HttpClients.createDefault(); final CloseableHttpClient secondClient = HttpClients.createDefault(); diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpTransactionIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpTransactionIntegrateTest.java index 4d1ec785c3d..f3a70965af3 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpTransactionIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerHttpTransactionIntegrateTest.java @@ -547,7 +547,7 @@ public void shouldRollbackAbandonedTransaction() throws Exception { public void shouldNotIdleTimeoutLongRunningOperation() throws Exception { // With a short idle timeout (500ms), a single operation that runs LONGER than the idle timeout must still // succeed -- the idle timer is suspended while an operation is in progress, so a long-running op is not - // reclaimed mid-execution (it is instead bounded by evaluationTimeout, left at its default here). + // reclaimed mid-execution (it is instead bounded by timeoutMs, left at its default here). final String txId = beginTx(client, GTX); // Seed two vertices and an edge so repeat(both()) has something to traverse and keeps the executor busy. Each diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java index 07e8e4ce717..c80b07fda1f 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java @@ -82,7 +82,7 @@ import static org.apache.tinkerpop.gremlin.process.remote.RemoteConnection.GREMLIN_REMOTE; import static org.apache.tinkerpop.gremlin.process.remote.RemoteConnection.GREMLIN_REMOTE_CONNECTION_CLASS; import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal; -import static org.apache.tinkerpop.gremlin.util.Tokens.ARGS_EVAL_TIMEOUT; +import static org.apache.tinkerpop.gremlin.util.Tokens.TIMEOUT_MS; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -152,7 +152,7 @@ public Settings overrideSettings(final Settings settings) { settings.writeBufferLowWaterMark = 32; break; case "shouldReceiveFailureTimeOutOnScriptEval": - settings.evaluationTimeout = 1000; + settings.timeoutMs = 1000; break; case "shouldBlockRequestWhenTooBig": settings.maxRequestContentLength = 1024; @@ -177,7 +177,7 @@ public Settings overrideSettings(final Settings settings) { settings.maxParameters = 1; break; case "shouldTimeOutRemoteTraversal": - settings.evaluationTimeout = 500; + settings.timeoutMs = 500; break; case "ensureScriptEngineDefaultsToGremlinLang": settings.scriptEngines = new HashMap<>(); @@ -388,7 +388,7 @@ public void shouldTimeOutRemoteTraversalWithPerRequestOption() throws Exception try { // tests sleeping thread - g.with(ARGS_EVAL_TIMEOUT, 500L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate(); + g.with(TIMEOUT_MS, 500L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(10000)")).iterate(); fail("This traversal should have timed out"); } catch (Exception ex) { final Throwable t = ex.getCause(); @@ -401,7 +401,7 @@ public void shouldTimeOutRemoteTraversalWithPerRequestOption() throws Exception try { // tests an "unending" traversal - g.with(ARGS_EVAL_TIMEOUT, 500L).V().repeat(__.out()).until(__.outE().count().is(0)).iterate(); + g.with(TIMEOUT_MS, 500L).V().repeat(__.out()).until(__.outE().count().is(0)).iterate(); fail("This traversal should have timed out"); } catch (Exception ex) { final Throwable t = ex.getCause(); @@ -429,7 +429,7 @@ public void shouldProduceProperExceptionOnTimeout() throws Exception { // Note: this test may have a false negative result, but a failure would indicate a real problem. for(int i = 0; i < 30; i++) { int timeout = 1 + i; - overrideEvaluationTimeout(timeout); + overrideTimeoutMs(timeout); try { client.submit("g.inject(2)").all().get().get(0).getInt(); @@ -712,7 +712,7 @@ public void shouldReceiveFailureTimeOutOnEvalUsingOverride() throws Exception { public void shouldReceiveFailureTimeOutOnScriptEvalOfOutOfControlLoop() throws Exception { try (SimpleClient client = TestClientFactory.createSimpleHttpClient()){ // timeout configured for 1 second so the timed interrupt should trigger prior to the - // evaluationTimeout which is at 30 seconds by default + // timeoutMs which is at 30 seconds by default final List responses = client.submit( RequestMessage.build("while(true){}").addLanguage("gremlin-groovy").create() ); @@ -963,9 +963,9 @@ public void shouldGenerateTemporaryErrorResponseStatusCode() throws Exception { public void shouldHandleMultipleLambdaTranslationsInParallel() throws Exception { final GraphTraversalSource g = traversal().withRemote(conf); - final CompletableFuture> firstRes = g.with("evaluationTimeout", 90000L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(100)")).promise(Traversal::iterate); - final CompletableFuture> secondRes = g.with("evaluationTimeout", 90000L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(100)")).promise(Traversal::iterate); - final CompletableFuture> thirdRes = g.with("evaluationTimeout", 90000L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(100)")).promise(Traversal::iterate); + final CompletableFuture> firstRes = g.with("timeoutMs", 90000L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(100)")).promise(Traversal::iterate); + final CompletableFuture> secondRes = g.with("timeoutMs", 90000L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(100)")).promise(Traversal::iterate); + final CompletableFuture> thirdRes = g.with("timeoutMs", 90000L).inject(1).sideEffect(Lambda.consumer("Thread.sleep(100)")).promise(Traversal::iterate); try { firstRes.get(); diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandlerTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandlerTest.java index 04db1163621..8d6b50c0008 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandlerTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/handler/HttpGremlinEndpointHandlerTest.java @@ -85,7 +85,7 @@ public void shouldMapInterruptToTransactionTimeoutWhenClosedByLifetimeCap() { } @Test - public void shouldMapInterruptToEvaluationTimeoutWhenNotClosedByLifetimeCap() { + public void shouldMapInterruptToTimeoutMsWhenNotClosedByLifetimeCap() { // An ordinary evaluation-timeout interrupt (cap flag unset) must keep the existing 500 timeout behavior. final RequestMessage message = RequestMessage.build("g.V()").create(); final Context ctx = mock(Context.class); diff --git a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml index ff84e4a5e0b..67252f1af27 100644 --- a/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml +++ b/gremlin-server/src/test/resources/org/apache/tinkerpop/gremlin/server/gremlin-server-integration.yaml @@ -30,7 +30,7 @@ host: 0.0.0.0 port: 45940 -evaluationTimeout: 30000 +timeoutMs: 30000 # Set below the code default (600000) so SettingsTest can confirm a YAML-provided value is honored; still far larger # than any integration test's runtime (8 minutes), so it never fires during a test. maxTransactionLifetime: 480000 diff --git a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinGroovyScriptEngineBenchmark.java b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinGroovyScriptEngineBenchmark.java index 99dbd79843c..1182eba0c9e 100644 --- a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinGroovyScriptEngineBenchmark.java +++ b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinGroovyScriptEngineBenchmark.java @@ -104,7 +104,7 @@ private String generateScript(final Integer id, final boolean binding) { if (binding && id != null) throw new IllegalArgumentException("If binding is true then the id should be null"); final StringBuilder b = new StringBuilder(); - b.append("g.with('evaluationTimeout', 1000L).addV('person').property(id,"); + b.append("g.with('timeoutMs', 1000L).addV('person').property(id,"); if (!binding) b.append("'"); b.append(null == id ? "x" : id); diff --git a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinScriptCheckerBenchmark.java b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinScriptCheckerBenchmark.java index 9100e595303..e6b317cd619 100644 --- a/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinScriptCheckerBenchmark.java +++ b/gremlin-tools/gremlin-benchmark/src/main/java/org/apache/tinkerpop/jsr223/GremlinScriptCheckerBenchmark.java @@ -44,6 +44,6 @@ public Optional testParseMaterializeProperties() { @Benchmark public GremlinScriptChecker.Result testParseAll() { - return GremlinScriptChecker.parse("g.with('evaluationTimeout', 1000L).with('materializeProperties', 'all').with('requestId', '4F53FB59-CFC9-4984-B477-452073A352FD').with(true).V().out('knows')"); + return GremlinScriptChecker.parse("g.with('timeoutMs', 1000L).with('materializeProperties', 'all').with('requestId', '4F53FB59-CFC9-4984-B477-452073A352FD').with(true).V().out('knows')"); } } diff --git a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/Tokens.java b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/Tokens.java index 2668b8c66df..40d54126db6 100644 --- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/Tokens.java +++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/Tokens.java @@ -68,12 +68,6 @@ public static final class Headers { */ public static final String ARGS_LANGUAGE = "language"; - /** - * Argument name that allows the override of the server setting that determines the maximum time to wait for a - * request to execute on the server. - */ - public static final String ARGS_EVAL_TIMEOUT = "evaluationTimeout"; - /** * The name of the argument that allows to control the serialization of properties on the server. */ @@ -92,7 +86,9 @@ public static final class Headers { public static final String MATERIALIZE_PROPERTIES_TOKENS = "tokens"; /** - * The key for the per request server-side timeout in milliseconds. + * The key for the per request server-side timeout in milliseconds. This overrides the server's configured + * default ({@code timeoutMs}) and determines the maximum time a request is allowed to execute on the server + * before it times out. */ public static final String TIMEOUT_MS = "timeoutMs";