You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2019/12/05 19:35:39 UTC

[couchdb] 06/11: Reuse read-only transactions during HTTP requests

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

davisp pushed a commit to branch opentracing-davisp
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 486cbc7d2f8561b1cfc622379cd7306e4745be21
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Tue Nov 5 11:26:13 2019 -0600

    Reuse read-only transactions during HTTP requests
---
 src/chttpd/src/chttpd.erl      |  1 +
 src/fabric/include/fabric2.hrl |  1 +
 src/fabric/src/fabric2_fdb.erl | 34 +++++++++++++++++++++++++++++++++-
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index 284b325..a28a33c 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -152,6 +152,7 @@ stop() ->
     mochiweb_http:stop(?MODULE).
 
 handle_request(MochiReq0) ->
+    fabric2_fdb:clear_state(),
     ctrace:start_span('http.request'),
     erlang:put(?REWRITE_COUNT, 0),
     MochiReq = couch_httpd_vhost:dispatch_host(MochiReq0),
diff --git a/src/fabric/include/fabric2.hrl b/src/fabric/include/fabric2.hrl
index a5c12ae..2112116 100644
--- a/src/fabric/include/fabric2.hrl
+++ b/src/fabric/include/fabric2.hrl
@@ -64,6 +64,7 @@
 -define(PDICT_TX_ID_KEY, '$fabric_tx_id').
 -define(PDICT_TX_RES_KEY, '$fabric_tx_result').
 -define(PDICT_ON_COMMIT_FUN, '$fabric_on_commit_fun').
+-define(PDICT_PREV_TRANSACTION, '$fabric_prev_transaction').
 -define(COMMIT_UNKNOWN_RESULT, 1021).
 
 
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 95b2d67..a77a1e9 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -18,6 +18,8 @@
     transactional/3,
     transactional/2,
 
+    clear_state/0,
+
     create/2,
     open/2,
     reopen/1,
@@ -116,6 +118,10 @@ transactional(#{tx := {erlfdb_transaction, _}} = Db, Fun) ->
     end).
 
 
+clear_state() ->
+    erase(?PDICT_PREV_TRANSACTION).
+
+
 with_span(OpName, ExtraTags, Fun) ->
     case ctrace:is_enabled() of
         true ->
@@ -138,7 +144,7 @@ with_span(OpName, ExtraTags, Fun) ->
 do_transaction(Fun, LayerPrefix) when is_function(Fun, 1) ->
     Db = get_db_handle(),
     try
-        erlfdb:transactional(Db, fun(Tx) ->
+        maybe_reuse_transaction(Db, fun(Tx) ->
             case get(erlfdb_trace) of
                 Name when is_binary(Name) ->
                     erlfdb:set_option(Tx, transaction_logging_enable, Name);
@@ -161,6 +167,32 @@ do_transaction(Fun, LayerPrefix) when is_function(Fun, 1) ->
     end.
 
 
+maybe_reuse_transaction(Db, UserFun) ->
+    Tx = case get(?PDICT_PREV_TRANSACTION) of
+        undefined ->
+            erlfdb:create_transaction(Db);
+        PrevTx ->
+            PrevTx
+    end,
+    try
+        Ret = UserFun(Tx),
+        case erlfdb:is_read_only(Tx) of
+            true ->
+                put(?PDICT_PREV_TRANSACTION, Tx);
+            false ->
+                erlfdb:wait(erlfdb:commit(Tx)),
+                erase(?PDICT_PREV_TRANSACTION)
+        end,
+        Ret
+    catch error:{erlfdb_error, Code} ->
+        couch_log:error("XKCD: ~p", [Code]),
+        erase(?PDICT_PREV_TRANSACTION),
+        put('$erlfdb_error', Code),
+        erlfdb:wait(erlfdb:on_error(Tx, Code)),
+        maybe_reuse_transaction(Db, UserFun)
+    end.
+
+
 create(#{} = Db0, Options) ->
     #{
         name := DbName,