You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2021/10/15 15:18:57 UTC

[couchdb] branch fix-fabric-get-db-timeout-badarith created (now 533627a)

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a change to branch fix-fabric-get-db-timeout-badarith
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


      at 533627a  Fix badarith error in get_db_timeout when request timeout = infinity

This branch includes the following new commits:

     new 533627a  Fix badarith error in get_db_timeout when request timeout = infinity

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[couchdb] 01/01: Fix badarith error in get_db_timeout when request timeout = infinity

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch fix-fabric-get-db-timeout-badarith
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 533627ae5db24f6bb942828596d880b5feccf5ee
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Fri Oct 15 11:00:03 2021 -0400

    Fix badarith error in get_db_timeout when request timeout = infinity
    
    `infinity` it turns out is a valid configuration value for fabric
    request_timeout. We can pass that to Erlang `receive` statement, any arithmetic
    with it would fail.
    
    To guard against the crash use the max small int value (60 bits). With enough
    shards, due to the exponential nature of the algorithm, we still get a nice
    progression from the minimum 100 msec all the way up to the large int value.
    This case is illustrated in the test.
    
    Issue: https://github.com/apache/couchdb/issues/3789
---
 src/fabric/src/fabric_util.erl | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/fabric/src/fabric_util.erl b/src/fabric/src/fabric_util.erl
index e07ab7b..4c40316 100644
--- a/src/fabric/src/fabric_util.erl
+++ b/src/fabric/src/fabric_util.erl
@@ -138,6 +138,10 @@ get_shard([#shard{node = Node, name = Name} | Rest], Opts, Timeout, Factor) ->
         rexi_monitor:stop(Mon)
     end.
 
+get_db_timeout(N, Factor, MinTimeout, infinity) ->
+    % MaxTimeout may be infinity so we just use the largest Erlang small int to
+    % avoid blowing up the arithmetic
+    get_db_timeout(N, Factor, MinTimeout, 1 bsl 59);
 get_db_timeout(N, Factor, MinTimeout, MaxTimeout) ->
     %
     % The progression of timeouts forms a geometric series:
@@ -460,4 +464,8 @@ get_db_timeout_test() ->
     ?assertEqual(28346, get_db_timeout(2 * 3, 2, 100, 3600000)),
 
     % No shards at all
-    ?assertEqual(60000, get_db_timeout(0, 2, 100, 60000)).
+    ?assertEqual(60000, get_db_timeout(0, 2, 100, 60000)),
+
+    % request_timeout was set to infinity, with enough shards it still gets to
+    % 100 min timeout at the start from the exponential logic
+    ?assertEqual(100, get_db_timeout(64, 2, 100, infinity)).