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 <[email protected]> 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,
