This is an automated email from the ASF dual-hosted git repository. davisp pushed a commit to branch couch-server-improvements-with-deadline in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit d2bf663482168036f408de39a74ed01ead472a9b Author: Paul J. Davis <[email protected]> AuthorDate: Mon Sep 10 14:32:20 2018 -0500 Add a deadline for open messages with a timeout There's no point in performing the work for messages from workers that have abandoned listening for a request from couch_server. This change adds a deadline value to each timeout open message. If couch_server sees one of these after the deadline has passed it will return an error (although the process may not even be alive any longer) and then continue handling messages. --- src/couch/src/couch_server.erl | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/couch/src/couch_server.erl b/src/couch/src/couch_server.erl index c4b7bf1..330404d 100644 --- a/src/couch/src/couch_server.erl +++ b/src/couch/src/couch_server.erl @@ -85,10 +85,17 @@ open(DbName, Options0) -> {ok, Db1} = couch_db:incref(Db0), couch_db:set_user_ctx(Db1, Ctx); _ -> - Options = maybe_add_sys_db_callbacks(DbName, Options0), - Timeout = couch_util:get_value(timeout, Options, infinity), + Options1 = maybe_add_sys_db_callbacks(DbName, Options0), + Timeout = couch_util:get_value(timeout, Options1, infinity), Create = couch_util:get_value(create_if_missing, Options, false), - case gen_server:call(couch_server, {open, DbName, Options}, Timeout) of + Msg = case Timeout of + infinity -> + {open, DbName, Options}; + _ when is_integer(Timeout), Timeout >= 0 -> + Deadline = make_deadline(Timeout), + {open, DbName, Options, Deadline} + end, + case gen_server:call(couch_server, Msg, Timeout) of {ok, Db0} -> {ok, Db1} = couch_db:incref(Db0), couch_db:set_user_ctx(Db1, Ctx); @@ -100,6 +107,15 @@ open(DbName, Options0) -> end end. +make_deadline(Timeout) when is_integer(Timeout), Timeoue >= 0 -> + {MegaNow, SecNow, MicroNow} = os:timestamp(), + Now = MegaNow * 1000000 * 1000000 + SecNow * 1000000 + MicroNow, + Deadline = Now + round(Timeout * 1.25), + MegaFuture = (Deadline div 1000000) div 1000000, + SecFuture = (Deadline div 1000000) rem 1000000, + MicroFuture = Deadline rem 1000000, + {MegaFuture, SecFuture, MicroFuture}. + update_lru(DbName, Options) -> case config:get_boolean("couchdb", "update_lru_on_read", false) of true -> @@ -468,6 +484,13 @@ handle_call({open_result, _T0, DbName, Error}, {Opener, _}, Server) -> % was in our mailbox and is now stale. Ignore it. {reply, ok, Server} end; +handle_call({open, DbName, Options, Deadline}, From, Server) -> + case timer:now_diff(Deadline, os:timestamp()) of + N when N < 0 -> + {reply, {error, deadline_exceeded}, Server}; + _ -> + handle_call({open, DbName, Options}, From, Server) + end; handle_call({open, DbName, Options}, From, Server) -> case ets:lookup(couch_dbs, DbName) of [] ->
