This is an automated email from the ASF dual-hosted git repository. davisp pushed a commit to branch optimize-ddoc-cache in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 8e66b07bb3b983a95e1745aa575a9550fa88f57c Author: Paul J. Davis <[email protected]> AuthorDate: Thu Jul 20 14:02:57 2017 -0500 FIXUP: Process processes in the process of dying Turns out we could go to evict an entry just after it had decided to leave the cache (i.e., its ddoc was just deleted). When that happens ddoc_cache_lru would die trying to shut the process down becuase the process died normal earlier than expected. --- src/ddoc_cache/src/ddoc_cache_entry.erl | 27 ++++++++++++++++++++++----- src/ddoc_cache/test/ddoc_cache_entry_test.erl | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/ddoc_cache/src/ddoc_cache_entry.erl b/src/ddoc_cache/src/ddoc_cache_entry.erl index 63a2efa..ed292f2 100644 --- a/src/ddoc_cache/src/ddoc_cache_entry.erl +++ b/src/ddoc_cache/src/ddoc_cache_entry.erl @@ -45,6 +45,13 @@ -include("ddoc_cache.hrl"). +-ifndef(TEST). +-define(ENTRY_SHUTDOWN_TIMEOUT, 5000). +-else. +-define(ENTRY_SHUTDOWN_TIMEOUT, 500). +-endif. + + -record(st, { key, val, @@ -77,7 +84,17 @@ start_link(Key, Default) -> shutdown(Pid) -> - ok = gen_server:call(Pid, shutdown). + Ref = erlang:monitor(process, Pid), + ok = gen_server:cast(Pid, shutdown), + receive + {'DOWN', Ref, process, Pid, normal} -> + ok; + {'DOWN', Ref, process, Pid, Reason} -> + erlang:exit(Reason) + after ?ENTRY_SHUTDOWN_TIMEOUT -> + erlang:demonitor(Ref, [flush]), + erlang:exit({timeout, {entry_shutdown, Pid}}) + end. open(Pid, Key) -> @@ -170,10 +187,6 @@ handle_call(open, From, #st{opener = Pid} = St) when is_pid(Pid) -> handle_call(open, _From, St) -> {reply, St#st.val, St}; -handle_call(shutdown, _From, St) -> - remove_from_cache(St), - {stop, normal, ok, St}; - handle_call(Msg, _From, St) -> {stop, {bad_call, Msg}, {bad_call, Msg}, St}. @@ -227,6 +240,10 @@ handle_cast(refresh, #st{opener = Pid} = St) when is_pid(Pid) -> }, {noreply, NewSt}; +handle_cast(shutdown, St) -> + remove_from_cache(St), + {stop, normal, St}; + handle_cast(Msg, St) -> {stop, {bad_cast, Msg}, St}. diff --git a/src/ddoc_cache/test/ddoc_cache_entry_test.erl b/src/ddoc_cache/test/ddoc_cache_entry_test.erl index 381185c..49b24a9 100644 --- a/src/ddoc_cache/test/ddoc_cache_entry_test.erl +++ b/src/ddoc_cache/test/ddoc_cache_entry_test.erl @@ -137,3 +137,21 @@ handles_bad_messages(_) -> handles_code_change(_) -> CCExpect = {ok, bar}, ?assertEqual(CCExpect, ddoc_cache_entry:code_change(foo, bar, baz)). + + +handles_bad_shutdown_test_() -> + {timeout, 10, ?_test(begin + ErrorPid = spawn(fun() -> + receive + _ -> exit(bad_shutdown) + end + end), + ?assertExit(bad_shutdown, ddoc_cache_entry:shutdown(ErrorPid)), + NotDeadYetPid = spawn(fun() -> + timer:sleep(infinity) + end), + ?assertExit( + {timeout, {entry_shutdown, NotDeadYetPid}}, + ddoc_cache_entry:shutdown(NotDeadYetPid) + ) + end)}. -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
