summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@gmail.com>2021-04-26 15:25:42 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2021-04-27 14:32:15 -0400
commitd7011765673e649ac2adcde3db2beede920f40be (patch)
tree3cfef9377d0d1ada484f18724d3cc39a0019a1a8
parent33ca7540bab8e7cab82ea19b7b0a252ab74a632d (diff)
downloadcouchdb-d7011765673e649ac2adcde3db2beede920f40be.tar.gz
Improve tx retry resilience when transaction restart
When running integration tests with a "buggified" client [1], sometimes `fold_range_not_progressing` is triggered since it's possible retriable errors might be thrown 3 times in a row. Instead of bumping it arbitrarily, since we already have a retry limit in fabric2_server, start using that. [1] ``` ERL_ZFLAGS="-erlfdb network_options '[client_buggify_enable, {client_buggify_section_activated_probability, 25}, {client_buggify_section_fired_probability, 25}]'" make elixir tests=test/elixir/test/basics_test.exs ```
-rw-r--r--src/fabric/src/fabric2_fdb.erl6
-rw-r--r--src/fabric/src/fabric2_server.erl9
-rw-r--r--src/fabric/test/fabric2_changes_fold_tests.erl4
3 files changed, 14 insertions, 5 deletions
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index a4c3f89dd..e86b03778 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -91,9 +91,6 @@
-include("fabric2.hrl").
--define(MAX_FOLD_RANGE_RETRIES, 3).
-
-
-record(fold_acc, {
db,
restart_tx,
@@ -1882,10 +1879,11 @@ restart_fold(Tx, #fold_acc{} = Acc) ->
ok = erlfdb:reset(Tx),
+ MaxRetries = fabric2_server:get_retry_limit(),
case {erase(?PDICT_FOLD_ACC_STATE), Acc#fold_acc.retries} of
{#fold_acc{db = Db} = Acc1, _} ->
Acc1#fold_acc{db = check_db_instance(Db), retries = 0};
- {undefined, Retries} when Retries < ?MAX_FOLD_RANGE_RETRIES ->
+ {undefined, Retries} when Retries < MaxRetries ->
Db = check_db_instance(Acc#fold_acc.db),
Acc#fold_acc{db = Db, retries = Retries + 1};
{undefined, _} ->
diff --git a/src/fabric/src/fabric2_server.erl b/src/fabric/src/fabric2_server.erl
index e427f2013..8a4a8d8df 100644
--- a/src/fabric/src/fabric2_server.erl
+++ b/src/fabric/src/fabric2_server.erl
@@ -27,7 +27,8 @@
maybe_remove/1,
fdb_directory/0,
- fdb_cluster/0
+ fdb_cluster/0,
+ get_retry_limit/0
]).
@@ -194,6 +195,12 @@ fdb_directory() ->
fdb_cluster() ->
get_env(?FDB_CLUSTER).
+
+get_retry_limit() ->
+ Default = list_to_integer(?DEFAULT_RETRY_LIMIT),
+ config:get_integer(?TX_OPTIONS_SECTION, "retry_limit", Default).
+
+
get_env(Key) ->
case get(Key) of
undefined ->
diff --git a/src/fabric/test/fabric2_changes_fold_tests.erl b/src/fabric/test/fabric2_changes_fold_tests.erl
index a8578f96b..2f6388388 100644
--- a/src/fabric/test/fabric2_changes_fold_tests.erl
+++ b/src/fabric/test/fabric2_changes_fold_tests.erl
@@ -81,6 +81,7 @@ changes_fold_test_() ->
setup_all() ->
Ctx = test_util:start_couch([fabric]),
meck:new(erlfdb, [passthrough]),
+ meck:new(fabric2_server, [passthrough]),
Ctx.
@@ -91,6 +92,7 @@ teardown_all(Ctx) ->
setup() ->
fabric2_test_util:tx_too_old_mock_erlfdb(),
+ meck:expect(fabric2_server, get_retry_limit, 0, 3),
{ok, Db} = fabric2_db:create(?tempdb(), [{user_ctx, ?ADMIN_USER}]),
Rows = lists:map(fun(Val) ->
DocId = fabric2_util:uuid(),
@@ -111,6 +113,8 @@ setup() ->
cleanup({Db, _DocIdRevs}) ->
+ meck:reset(fabric2_server),
+ meck:expect(fabric2_server, get_retry_limit, 0, meck:passthrough()),
fabric2_test_util:tx_too_old_reset_errors(),
ok = fabric2_db:delete(fabric2_db:name(Db), []).