You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2020/10/24 06:53:03 UTC

[couchdb] branch handle-insert-conflict created (now 855652b)

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

jaydoane pushed a change to branch handle-insert-conflict
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


      at 855652b  Sleep and retry after insert conflict

This branch includes the following new commits:

     new 59d799c  Fix dialyzer warnings
     new 855652b  Sleep and retry after insert conflict

The 2 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/02: Fix dialyzer warnings

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

jaydoane pushed a commit to branch handle-insert-conflict
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 59d799c37d609863a80f564bb70f874ed5a2472b
Author: Jay Doane <ja...@apache.org>
AuthorDate: Fri Oct 23 23:36:52 2020 -0700

    Fix dialyzer warnings
    
    Fix specs to eliminate dialyzer warnings.
---
 src/couch_expiring_cache/.suppressed                      | 1 +
 src/couch_expiring_cache/src/couch_expiring_cache.erl     | 5 +++--
 src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl | 6 +++---
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/couch_expiring_cache/.suppressed b/src/couch_expiring_cache/.suppressed
new file mode 100644
index 0000000..3baad65
--- /dev/null
+++ b/src/couch_expiring_cache/.suppressed
@@ -0,0 +1 @@
+no_return
diff --git a/src/couch_expiring_cache/src/couch_expiring_cache.erl b/src/couch_expiring_cache/src/couch_expiring_cache.erl
index b26556e..f1ce202 100644
--- a/src/couch_expiring_cache/src/couch_expiring_cache.erl
+++ b/src/couch_expiring_cache/src/couch_expiring_cache.erl
@@ -31,8 +31,9 @@ insert(Name, Key, Value, StaleTS, ExpiresTS)
     insert(undefined, Name, Key, Value, StaleTS, ExpiresTS).
 
 
--spec insert(Tx :: jtx(), Name :: binary(), Key :: binary(), Value :: binary(),
-    StaleTS :: ?TIME_UNIT(), ExpiresTS :: ?TIME_UNIT()) -> ok.
+-spec insert(Tx :: jtx() | undefined, Name :: binary(), Key :: binary(),
+    Value :: binary(), StaleTS :: ?TIME_UNIT(), ExpiresTS :: ?TIME_UNIT()) -> ok.
+-dialyzer({no_return, insert/6}).
 insert(Tx, Name, Key, Value, StaleTS, ExpiresTS)
         when is_binary(Name), is_binary(Key), is_binary(Value),
         is_integer(StaleTS), is_integer(ExpiresTS) ->
diff --git a/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl b/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl
index 7c4ad8f..3f6e1aa 100644
--- a/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl
+++ b/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl
@@ -37,7 +37,7 @@
 
 
 -spec insert(JTx :: jtx(), Name :: binary(), Key :: binary(), Value :: binary(),
-    StaleTS :: ?TIME_UNIT, ExpiresTS :: ?TIME_UNIT) -> ok.
+    StaleTS :: millisecond(), ExpiresTS :: millisecond()) -> ok.
 insert(#{jtx := true} = JTx, Name, Key, Val, StaleTS, ExpiresTS) ->
     #{tx := Tx, layer_prefix := LayerPrefix} = couch_jobs_fdb:get_jtx(JTx),
     PK = primary_key(Name, Key, LayerPrefix),
@@ -86,7 +86,7 @@ clear_all(Name) ->
     end).
 
 
--spec clear_range_to(Name :: binary(), EndTS :: ?TIME_UNIT,
+-spec clear_range_to(Name :: binary(), EndTS :: millisecond(),
     Limit :: non_neg_integer()) ->
         OldestTS :: ?TIME_UNIT.
 clear_range_to(Name, EndTS, Limit) when Limit > 0 ->
@@ -98,7 +98,7 @@ clear_range_to(Name, EndTS, Limit) when Limit > 0 ->
         end, 0).
 
 
--spec get_range_to(Name :: binary(), EndTS :: ?TIME_UNIT,
+-spec get_range_to(Name :: binary(), EndTS :: millisecond(),
     Limit :: non_neg_integer()) ->
         [{Key :: binary(), Val :: binary()}].
 get_range_to(Name, EndTS, Limit) when Limit > 0 ->


[couchdb] 02/02: Sleep and retry after insert conflict

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

jaydoane pushed a commit to branch handle-insert-conflict
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 855652b3eaf2f3efe03d88c0e4ce97746c51262c
Author: Jay Doane <ja...@apache.org>
AuthorDate: Fri Oct 23 23:52:18 2020 -0700

    Sleep and retry after insert conflict
    
    Too many parallel attempts to insert the same keys can result in
    `{erlfdb_error, 1020}`, which translates to:
    "Transaction not committed due to conflict with another transaction"
    
    This attempts to mitigate the problem by lowering the transaction
    retry limit, catching transaction conflict errors, and sleeping for
    a random time before retrying a final time.
---
 .../src/couch_expiring_cache.erl                   | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/couch_expiring_cache/src/couch_expiring_cache.erl b/src/couch_expiring_cache/src/couch_expiring_cache.erl
index f1ce202..efabf5d 100644
--- a/src/couch_expiring_cache/src/couch_expiring_cache.erl
+++ b/src/couch_expiring_cache/src/couch_expiring_cache.erl
@@ -23,6 +23,9 @@
 -include_lib("couch_expiring_cache/include/couch_expiring_cache.hrl").
 
 
+-define(DEFAULT_MAX_RETRY_DELAY_MS, 100).
+
+
 -spec insert(Name :: binary(), Key :: binary(), Value :: binary(),
     StaleTS :: ?TIME_UNIT(), ExpiresTS :: ?TIME_UNIT()) -> ok.
 insert(Name, Key, Value, StaleTS, ExpiresTS)
@@ -38,8 +41,18 @@ insert(Tx, Name, Key, Value, StaleTS, ExpiresTS)
         when is_binary(Name), is_binary(Key), is_binary(Value),
         is_integer(StaleTS), is_integer(ExpiresTS) ->
     couch_jobs_fdb:tx(couch_jobs_fdb:get_jtx(Tx), fun(JTx) ->
-        couch_expiring_cache_fdb:insert(
-            JTx, Name, Key, Value, StaleTS, ExpiresTS)
+        try
+            #{tx := Tx0} = JTx,
+            erlfdb:set_option(Tx0, retry_limit, 1),
+            couch_expiring_cache_fdb:insert(
+                JTx, Name, Key, Value, StaleTS, ExpiresTS)
+        catch
+            error:{erlfdb_error, 1020} -> % conflict with another transaction
+                Delay = rand:uniform(max_retry_delay()),
+                timer:sleep(Delay),
+                couch_expiring_cache_fdb:insert(
+                    JTx, Name, Key, Value, StaleTS, ExpiresTS)
+        end
     end).
 
 
@@ -55,3 +68,8 @@ lookup(Tx, Name, Key) when is_binary(Name), is_binary(Key) ->
     couch_jobs_fdb:tx(couch_jobs_fdb:get_jtx(Tx), fun(JTx) ->
         couch_expiring_cache_fdb:lookup(JTx, Name, Key)
     end).
+
+
+max_retry_delay() ->
+    config:get_integer(
+        "couch_expiring_cache", "max_retry_delay", ?DEFAULT_MAX_RETRY_DELAY_MS).