Skip to content

Commit a9fd5c3

Browse files
committed
Added retryOnConflict
Fixes #763.
1 parent e526750 commit a9fd5c3

File tree

4 files changed

+36
-0
lines changed

4 files changed

+36
-0
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ This driver uses semantic versioning:
1616

1717
## [Unreleased]
1818

19+
### Added
20+
21+
- Added `retryOnConflict` option to `db.query` and `route.request`
22+
23+
This option allows specifying the number of times the request will be retried
24+
if it results in a write-write conflict.
25+
1926
## [7.7.0] - 2022-01-26
2027

2128
### Changed

src/connection.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ import { Database } from "./database";
1616
import {
1717
ArangoError,
1818
HttpError,
19+
isArangoError,
1920
isArangoErrorResponse,
2021
isSystemError,
2122
} from "./error";
2223
import { btoa } from "./lib/btoa";
24+
import { ERROR_ARANGO_CONFLICT } from "./lib/codes";
2325
import { Errback } from "./lib/errback";
2426
import { normalizeUrl } from "./lib/normalizeUrl";
2527
import {
@@ -254,6 +256,13 @@ export type RequestOptions = {
254256
* a non-authoritative server.
255257
*/
256258
allowDirtyRead?: boolean;
259+
/**
260+
* If set to a positive number, the request will automatically be retried at
261+
* most this many times if it results in a write-write conflict.
262+
*
263+
* Default: `0`
264+
*/
265+
retryOnConflict?: number;
257266
/**
258267
* HTTP headers to pass along with this request in addition to the default
259268
* headers generated by arangojs.
@@ -288,6 +297,7 @@ type Task = {
288297
host?: number;
289298
stack?: () => string;
290299
allowDirtyRead: boolean;
300+
retryOnConflict: number;
291301
resolve: (res: ArangojsResponse) => void;
292302
reject: (error: Error) => void;
293303
retries: number;
@@ -632,6 +642,13 @@ export class Connection {
632642
this._activeHost = (this._activeHost + 1) % this._hosts.length;
633643
}
634644
if (
645+
isArangoError(err) &&
646+
err.errorNum === ERROR_ARANGO_CONFLICT &&
647+
task.retryOnConflict > 0
648+
) {
649+
task.retryOnConflict -= 1;
650+
this._queue.push(task);
651+
} else if (
635652
!task.host &&
636653
this._shouldRetry &&
637654
task.retries < (this._maxRetries || this._hosts.length - 1) &&
@@ -878,6 +895,7 @@ export class Connection {
878895
expectBinary = false,
879896
isBinary = false,
880897
allowDirtyRead = false,
898+
retryOnConflict = 0,
881899
timeout = 0,
882900
headers,
883901
...urlInfo
@@ -911,6 +929,7 @@ export class Connection {
911929
retries: 0,
912930
host,
913931
allowDirtyRead,
932+
retryOnConflict,
914933
options: {
915934
url: this._buildUrl(urlInfo),
916935
headers: { ...extraHeaders, ...headers },

src/database.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ export type QueryOptions = {
218218
* `maxRuntime` option for limiting the execution time within ArangoDB.
219219
*/
220220
timeout?: number;
221+
/**
222+
* If set to a positive number, the query will automatically be retried at
223+
* most this many times if it results in a write-write conflict.
224+
*
225+
* Default: `0`
226+
*/
227+
retryOnConflict?: number;
221228
/**
222229
* Unless set to `false`, the number of result values in the result set will
223230
* be returned in the `count` attribute. This may be disabled by default in
@@ -3579,6 +3586,7 @@ export class Database {
35793586
}
35803587
const {
35813588
allowDirtyRead,
3589+
retryOnConflict,
35823590
count,
35833591
batchSize,
35843592
cache,
@@ -3602,6 +3610,7 @@ export class Database {
36023610
options: opts,
36033611
},
36043612
allowDirtyRead,
3613+
retryOnConflict,
36053614
timeout,
36063615
},
36073616
(res) =>

src/lib/codes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
export const TRANSACTION_NOT_FOUND = 10;
12+
export const ERROR_ARANGO_CONFLICT = 1200;
1213
export const ANALYZER_NOT_FOUND = 1202;
1314
export const DOCUMENT_NOT_FOUND = 1202;
1415
export const COLLECTION_NOT_FOUND = 1203;

0 commit comments

Comments
 (0)