-
Notifications
You must be signed in to change notification settings - Fork 21
Implement and test configurable transaction timeouts #197
Changes from 12 commits
213fae6
5caed4a
1ad353b
5edba1b
929d7f8
892b74a
a93032e
7eed859
e77b84a
4de4eb9
ec036f2
b1fc1ae
7ab502d
adba8df
5b7781e
0a66f3e
c074d17
f14db6e
a13bfc6
a35d1cd
ae3c735
6c808c5
2e16729
11f67fd
debad9b
513ca53
1935793
70b1a52
3f31ea6
9c5ac16
e05c95a
3efdfa9
dbdff45
2e77538
2291c2d
64305c9
c994ed9
6000f1e
7937d34
81b6d02
d0f135f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,9 +19,9 @@ | |
* under the License. | ||
*/ | ||
|
||
import { Options } from "typedb-protocol/common/options_pb"; | ||
import { ErrorMessage } from "../../common/errors/ErrorMessage"; | ||
import { TypeDBClientError } from "../../common/errors/TypeDBClientError"; | ||
import {Options} from "typedb-protocol/common/options_pb"; | ||
import {ErrorMessage} from "../../common/errors/ErrorMessage"; | ||
import {TypeDBClientError} from "../../common/errors/TypeDBClientError"; | ||
import NEGATIVE_VALUE_NOT_ALLOWED = ErrorMessage.Client.NEGATIVE_VALUE_NOT_ALLOWED; | ||
|
||
namespace Opts { | ||
|
@@ -33,6 +33,7 @@ namespace Opts { | |
prefetchSize?: number; | ||
prefetch?: boolean; | ||
sessionIdleTimeoutMillis?: number; | ||
transactionTimeoutMillis?: number; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new transaction option: millis before timeout |
||
schemaLockAcquireTimeoutMillis?: number; | ||
} | ||
|
||
|
@@ -50,6 +51,7 @@ namespace Opts { | |
if (options.prefetchSize != null) optionsProto.setPrefetchSize(options.prefetchSize); | ||
if (options.prefetch != null) optionsProto.setPrefetch(options.prefetch); | ||
if (options.sessionIdleTimeoutMillis != null) optionsProto.setSessionIdleTimeoutMillis(options.sessionIdleTimeoutMillis); | ||
if (options.transactionTimeoutMillis != null) optionsProto.setTransactionTimeoutMillis(options.transactionTimeoutMillis); | ||
if (options.schemaLockAcquireTimeoutMillis != null) optionsProto.setSchemaLockAcquireTimeoutMillis(options.schemaLockAcquireTimeoutMillis); | ||
if (options.isCluster()) { | ||
const clusterOptions = options as Opts.Cluster; | ||
|
@@ -69,6 +71,7 @@ export class TypeDBOptions implements Opts.Core { | |
private _prefetchSize: number; | ||
private _prefetch: boolean; | ||
private _sessionIdleTimeoutMillis: number; | ||
private _transactionTimeoutMillis: number; | ||
private _schemaLockAcquireTimeoutMillis: number; | ||
|
||
constructor(obj: { [K in keyof Opts.Core]: Opts.Core[K] } = {}) { | ||
|
@@ -138,11 +141,22 @@ export class TypeDBOptions implements Opts.Core { | |
return this._sessionIdleTimeoutMillis; | ||
} | ||
|
||
set sessionIdleTimeoutMillis(value: number) { | ||
if (value < 1) { | ||
throw new TypeDBClientError(NEGATIVE_VALUE_NOT_ALLOWED.message(value)); | ||
set sessionIdleTimeoutMillis(millis: number) { | ||
if (millis < 1) { | ||
throw new TypeDBClientError(NEGATIVE_VALUE_NOT_ALLOWED.message(millis)); | ||
} | ||
this._sessionIdleTimeoutMillis = millis; | ||
} | ||
|
||
get transactionTimeoutMillis() { | ||
return this._transactionTimeoutMillis; | ||
} | ||
|
||
set transactionTimeoutMillis(millis: number) { | ||
if (millis < 1) { | ||
throw new TypeDBClientError(NEGATIVE_VALUE_NOT_ALLOWED.message(millis)); | ||
} | ||
this._sessionIdleTimeoutMillis = value; | ||
this._transactionTimeoutMillis = millis; | ||
Comment on lines
+151
to
+159
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. setter/getter for transaction timeouts |
||
} | ||
|
||
get schemaLockAcquireTimeoutMillis() { | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -76,21 +76,22 @@ export namespace ErrorMessage { | |||||
export const SESSION_ID_EXISTS = new Client(1, (args: Stringable[]) => `The newly opened session id '${args[0]}' already exists`); | ||||||
export const SESSION_CLOSED = new Client(2, () => `Session is closed.`); | ||||||
export const TRANSACTION_CLOSED = new Client(3, () => `The transaction has been closed and no further operation is allowed.`); | ||||||
export const UNABLE_TO_CONNECT = new Client(4, () => `Unable to connect to TypeDB server.`); | ||||||
export const NEGATIVE_VALUE_NOT_ALLOWED = new Client(5, (args: Stringable[]) => `Value cannot be less than 1, was: '${args[0]}'.`); | ||||||
export const MISSING_DB_NAME = new Client(6, () => `Database name cannot be null.`); | ||||||
export const DB_DOES_NOT_EXIST = new Client(7, (args: Stringable[]) => `The database '${args[0]}' does not exist.`); | ||||||
export const UNKNOWN_STREAM_STATE = new Client(8, (args: Stringable[]) => `RPC transaction stream response '${args[0]}' is unknown.`); | ||||||
export const MISSING_RESPONSE = new Client(9, (args: Stringable[]) => `The required field 'res' of type '${args[0]}' was not set.`); | ||||||
export const UNKNOWN_REQUEST_ID = new Client(10, (args: Stringable[]) => `Received a response with unknown request id '${args[0]}'.`); | ||||||
export const CLUSTER_NO_PRIMARY_REPLICA_YET = new Client(11, (args: Stringable[]) => `No replica has been marked as the primary replica for latest known term '${args[0]}'.`); | ||||||
export const CLUSTER_UNABLE_TO_CONNECT = new Client(12, (args: Stringable[]) => `Unable to connect to TypeDB Cluster. Attempted connecting to the cluster members, but none are available: '${args[0]}'.`); | ||||||
export const CLUSTER_REPLICA_NOT_PRIMARY = new Client(13, () => `The replica is not the primary replica.`); | ||||||
export const CLUSTER_ALL_NODES_FAILED = new Client(14, (args: Stringable[]) => `Attempted connecting to all cluster members, but the following errors occurred: \n'${args[0]}'`); | ||||||
export const CLUSTER_USER_DOES_NOT_EXIST = new Client(15, (args: Stringable[]) => `The user '${args[0]}' does not exist.`); | ||||||
export const CLUSTER_TOKEN_CREDENTIAL_INVALID = new Client(16, (args: Stringable[]) => `Invalid token credential.`); | ||||||
export const CLUSTER_INVALID_ROOT_CA_PATH = new Client(17, (args: Stringable[]) => `The provided Root CA path '${args[0]}' does not exist`); | ||||||
export const UNRECOGNISED_SESSION_TYPE = new Client(18, (args: Stringable[]) => `Session type '${args[0]}' was not recognised.`); | ||||||
export const TRANSACTION_CLOSED_WITH_ERRORS = new Client(4, (args) => `The transaction has been closed with error(s): \n${args[0]}.`) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new exception to report a transaction is closed with errors There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for consistency with other constants in this file let's add the type annotation of
Suggested change
|
||||||
export const UNABLE_TO_CONNECT = new Client(5, () => `Unable to connect to TypeDB server.`); | ||||||
export const NEGATIVE_VALUE_NOT_ALLOWED = new Client(6, (args: Stringable[]) => `Value cannot be less than 1, was: '${args[0]}'.`); | ||||||
export const MISSING_DB_NAME = new Client(7, () => `Database name cannot be null.`); | ||||||
export const DB_DOES_NOT_EXIST = new Client(8, (args: Stringable[]) => `The database '${args[0]}' does not exist.`); | ||||||
export const UNKNOWN_STREAM_STATE = new Client(9, (args: Stringable[]) => `RPC transaction stream response '${args[0]}' is unknown.`); | ||||||
export const MISSING_RESPONSE = new Client(10, (args: Stringable[]) => `The required field 'res' of type '${args[0]}' was not set.`); | ||||||
export const UNKNOWN_REQUEST_ID = new Client(11, (args: Stringable[]) => `Received a response with unknown request id '${args[0]}'.`); | ||||||
export const CLUSTER_NO_PRIMARY_REPLICA_YET = new Client(12, (args: Stringable[]) => `No replica has been marked as the primary replica for latest known term '${args[0]}'.`); | ||||||
export const CLUSTER_UNABLE_TO_CONNECT = new Client(13, (args: Stringable[]) => `Unable to connect to TypeDB Cluster. Attempted connecting to the cluster members, but none are available: '${args[1]}'.`); | ||||||
export const CLUSTER_REPLICA_NOT_PRIMARY = new Client(14, () => `The replica is not the primary replica.`); | ||||||
export const CLUSTER_ALL_NODES_FAILED = new Client(15, (args: Stringable[]) => `Attempted connecting to all cluster members, but the following errors occurred: \n'${args[0]}'`); | ||||||
export const CLUSTER_USER_DOES_NOT_EXIST = new Client(16, (args: Stringable[]) => `The user '${args[0]}' does not exist.`); | ||||||
export const CLUSTER_TOKEN_CREDENTIAL_INVALID = new Client(17, (args: Stringable[]) => `Invalid token credential.`); | ||||||
export const CLUSTER_INVALID_ROOT_CA_PATH = new Client(18, (args: Stringable[]) => `The provided Root CA path '${args[0]}' does not exist`); | ||||||
export const UNRECOGNISED_SESSION_TYPE = new Client(19, (args: Stringable[]) => `Session type '${args[0]}' was not recognised.`); | ||||||
} | ||||||
|
||||||
export class Concept extends ErrorMessage { | ||||||
|
@@ -132,5 +133,6 @@ export namespace ErrorMessage { | |||||
export namespace Internal { | ||||||
export const ILLEGAL_CAST = new Internal(1, (args: Stringable[]) => `Illegal casting operation from '${args[0]}' to '${args[1]}'.`); | ||||||
export const ILLEGAL_ARGUMENT = new Internal(2, (args: Stringable[]) => `Illegal argument provided: '${args[0]}'`); | ||||||
export const ILLEGAL_STATE = new Internal(3, () => `Illegal state.`); | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,22 +19,24 @@ | |
* under the License. | ||
*/ | ||
|
||
import { Transaction } from "typedb-protocol/common/transaction_pb"; | ||
import { ConceptManager } from "../api/concept/ConceptManager"; | ||
import { TypeDBOptions } from "../api/connection/TypeDBOptions"; | ||
import { TransactionType, TypeDBTransaction } from "../api/connection/TypeDBTransaction"; | ||
import { LogicManager } from "../api/logic/LogicManager"; | ||
import { QueryManager } from "../api/query/QueryManager"; | ||
import { ErrorMessage } from "../common/errors/ErrorMessage"; | ||
import { TypeDBClientError } from "../common/errors/TypeDBClientError"; | ||
import { RequestBuilder } from "../common/rpc/RequestBuilder"; | ||
import { Stream } from "../common/util/Stream"; | ||
import { ConceptManagerImpl } from "../concept/ConceptManagerImpl"; | ||
import { LogicManagerImpl } from "../logic/LogicManagerImpl"; | ||
import { QueryManagerImpl } from "../query/QueryManagerImpl"; | ||
import { BidirectionalStream } from "../stream/BidirectionalStream"; | ||
import { TypeDBSessionImpl } from "./TypeDBSessionImpl"; | ||
import {Transaction} from "typedb-protocol/common/transaction_pb"; | ||
import {ConceptManager} from "../api/concept/ConceptManager"; | ||
import {TypeDBOptions} from "../api/connection/TypeDBOptions"; | ||
import {TransactionType, TypeDBTransaction} from "../api/connection/TypeDBTransaction"; | ||
import {LogicManager} from "../api/logic/LogicManager"; | ||
import {QueryManager} from "../api/query/QueryManager"; | ||
import {ErrorMessage} from "../common/errors/ErrorMessage"; | ||
import {TypeDBClientError} from "../common/errors/TypeDBClientError"; | ||
import {RequestBuilder} from "../common/rpc/RequestBuilder"; | ||
import {Stream} from "../common/util/Stream"; | ||
import {ConceptManagerImpl} from "../concept/ConceptManagerImpl"; | ||
import {LogicManagerImpl} from "../logic/LogicManagerImpl"; | ||
import {QueryManagerImpl} from "../query/QueryManagerImpl"; | ||
import {BidirectionalStream} from "../stream/BidirectionalStream"; | ||
import {TypeDBSessionImpl} from "./TypeDBSessionImpl"; | ||
import assert = require("assert"); | ||
Comment on lines
+22
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. auto format.... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We've never used Unlike in Java, there is no clean way to turn off assertions in NodeJS. (Methods typically used include hot module replacement - literally stripping the statements out of the source code before running it - and modifying the I think we're better off replacing it with
flyingsilverfin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import TRANSACTION_CLOSED = ErrorMessage.Client.TRANSACTION_CLOSED; | ||
import TRANSACTION_CLOSED_WITH_ERRORS = ErrorMessage.Client.TRANSACTION_CLOSED_WITH_ERRORS; | ||
|
||
export class TypeDBTransactionImpl implements TypeDBTransaction.Extended { | ||
private readonly _session: TypeDBSessionImpl; | ||
|
@@ -105,13 +107,20 @@ export class TypeDBTransactionImpl implements TypeDBTransaction.Extended { | |
} | ||
|
||
public async rpcExecute(request: Transaction.Req, batch?: boolean): Promise<Transaction.Res> { | ||
if (!this.isOpen()) throw new TypeDBClientError(TRANSACTION_CLOSED); | ||
if (!this.isOpen()) this.throwTransactionClosed() | ||
const useBatch = batch !== false; | ||
return this._bidirectionalStream.single(request, useBatch); | ||
} | ||
|
||
public rpcStream(request: Transaction.Req): Stream<Transaction.ResPart> { | ||
if (!this.isOpen()) throw new TypeDBClientError(TRANSACTION_CLOSED); | ||
if (!this.isOpen()) this.throwTransactionClosed(); | ||
return this._bidirectionalStream.stream(request); | ||
} | ||
|
||
private throwTransactionClosed(): void { | ||
assert(!this.isOpen()); | ||
const errors = this._bidirectionalStream.getErrors(); | ||
if (errors.length == 0) throw new TypeDBClientError(TRANSACTION_CLOSED); | ||
else throw new TypeDBClientError(TRANSACTION_CLOSED_WITH_ERRORS.message(errors)); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can differentiate between a transaction closed with errors and one without errors |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ def vaticle_typedb_artifacts(): | |
artifact_name = "typedb-server-{platform}-{version}.{ext}", | ||
tag_source = deployment["artifact.release"], | ||
commit_source = deployment["artifact.snapshot"], | ||
commit = "6ed020e52fe379d1100f64511805ed344c7a68db" | ||
commit = "2367157bdd898e474198726d0ef5446372a73314", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update core artifact with transaction timeout |
||
) | ||
|
||
def vaticle_typedb_cluster_artifacts(): | ||
|
@@ -39,5 +39,5 @@ def vaticle_typedb_cluster_artifacts(): | |
artifact_name = "typedb-cluster-all-{platform}-{version}.{ext}", | ||
tag_source = deployment_private["artifact.release"], | ||
commit_source = deployment_private["artifact.snapshot"], | ||
commit = "f6d9eae58c83c165d932c0433a3a0d858e206fab", | ||
commit = "f6d9eae58c83c165d932c0433a3a0d858e206fab" | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,12 +32,12 @@ def vaticle_typedb_common(): | |
git_repository( | ||
name = "vaticle_typedb_common", | ||
remote = "https://github.com/vaticle/typedb-common", | ||
tag = "2.5.0" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common | ||
commit = "a436f7c9b64060d7fed718a3be60895c15bd893f" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common | ||
) | ||
|
||
def vaticle_typedb_behaviour(): | ||
git_repository( | ||
name = "vaticle_typedb_behaviour", | ||
remote = "https://github.com/vaticle/typedb-behaviour", | ||
commit = "042cbf2a6c3b8b9d7a8c3b8d74e796da968523fd", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour | ||
commit = "d92d840dd40cc8393936d6f6042820ebcd3a9cef", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour | ||
Comment on lines
32
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bump dependencies |
||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
following other clients' we extract the
wait
steps into their ownUtilSteps
file