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 2017/07/06 18:49:18 UTC

[couchdb] branch optimize-ddoc-cache updated (32cd254 -> 85b5385)

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

davisp pushed a change to branch optimize-ddoc-cache
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


    from 32cd254  FIXUP: Evict unused entries
     new 0e9aadc  FIXUP: Comment on use of no_ddocid
     new 85b5385  FIXUP: Reuse fabric lookup results

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.


Summary of changes:
 src/ddoc_cache/src/ddoc_cache_entry.erl            | 33 +++++++++++++++---
 src/ddoc_cache/src/ddoc_cache_entry_custom.erl     |  7 +++-
 src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl     | 13 +++++++-
 src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl | 12 ++++++-
 .../src/ddoc_cache_entry_validation_funs.erl       |  7 +++-
 src/ddoc_cache/src/ddoc_cache_lru.erl              | 34 ++++++++++++++-----
 src/ddoc_cache/test/ddoc_cache_basic_test.erl      | 39 +++++++++++++++++-----
 src/ddoc_cache/test/ddoc_cache_entry_test.erl      |  6 ++--
 src/ddoc_cache/test/ddoc_cache_eviction_test.erl   |  6 ++--
 src/ddoc_cache/test/ddoc_cache_no_cache_test.erl   |  1 +
 src/ddoc_cache/test/ddoc_cache_open_error_test.erl |  2 +-
 src/ddoc_cache/test/ddoc_cache_refresh_test.erl    | 17 +++++++---
 src/ddoc_cache/test/ddoc_cache_remove_test.erl     | 30 +++++++++++++----
 13 files changed, 165 insertions(+), 42 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
['"commits@couchdb.apache.org" <co...@couchdb.apache.org>'].

[couchdb] 01/02: FIXUP: Comment on use of no_ddocid

Posted by da...@apache.org.
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 0e9aadc37ed89235ae0aa4d974f6d3f8e02ad4d6
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Thu Jul 6 13:07:55 2017 -0500

    FIXUP: Comment on use of no_ddocid
---
 src/ddoc_cache/src/ddoc_cache_lru.erl | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ddoc_cache/src/ddoc_cache_lru.erl b/src/ddoc_cache/src/ddoc_cache_lru.erl
index 5d47639..cbe481e 100644
--- a/src/ddoc_cache/src/ddoc_cache_lru.erl
+++ b/src/ddoc_cache/src/ddoc_cache_lru.erl
@@ -158,6 +158,10 @@ handle_cast({do_refresh, DbName, DDocIdList}, St) ->
     #st{
         dbs = Dbs
     } = St,
+    % We prepend no_ddocid to the DDocIdList below
+    % so that we refresh all custom and validation
+    % function entries which load data from all
+    % design documents.
     case khash:lookup(Dbs, DbName) of
         {value, DDocIds} ->
             lists:foreach(fun(DDocId) ->

-- 
To stop receiving notification emails like this one, please contact
"commits@couchdb.apache.org" <co...@couchdb.apache.org>.

[couchdb] 02/02: FIXUP: Reuse fabric lookup results

Posted by da...@apache.org.
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 85b53855255be0a4166bbb14697c010ff4468d20
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Thu Jul 6 13:48:15 2017 -0500

    FIXUP: Reuse fabric lookup results
    
    On suggestion from @chewbranca I've gone ahead and made the optimization
    to insert the revid or non-revid specific version of the request design
    document.
---
 src/ddoc_cache/src/ddoc_cache_entry.erl            | 33 +++++++++++++++---
 src/ddoc_cache/src/ddoc_cache_entry_custom.erl     |  7 +++-
 src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl     | 13 +++++++-
 src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl | 12 ++++++-
 .../src/ddoc_cache_entry_validation_funs.erl       |  7 +++-
 src/ddoc_cache/src/ddoc_cache_lru.erl              | 30 ++++++++++++-----
 src/ddoc_cache/test/ddoc_cache_basic_test.erl      | 39 +++++++++++++++++-----
 src/ddoc_cache/test/ddoc_cache_entry_test.erl      |  6 ++--
 src/ddoc_cache/test/ddoc_cache_eviction_test.erl   |  6 ++--
 src/ddoc_cache/test/ddoc_cache_no_cache_test.erl   |  1 +
 src/ddoc_cache/test/ddoc_cache_open_error_test.erl |  2 +-
 src/ddoc_cache/test/ddoc_cache_refresh_test.erl    | 17 +++++++---
 src/ddoc_cache/test/ddoc_cache_remove_test.erl     | 30 +++++++++++++----
 13 files changed, 161 insertions(+), 42 deletions(-)

diff --git a/src/ddoc_cache/src/ddoc_cache_entry.erl b/src/ddoc_cache/src/ddoc_cache_entry.erl
index 914e32e..79c3dcf 100644
--- a/src/ddoc_cache/src/ddoc_cache_entry.erl
+++ b/src/ddoc_cache/src/ddoc_cache_entry.erl
@@ -18,8 +18,9 @@
     dbname/1,
     ddocid/1,
     recover/1,
+    insert/2,
 
-    start_link/1,
+    start_link/2,
     shutdown/1,
     open/2,
     accessed/1,
@@ -65,8 +66,12 @@ recover({Mod, Arg}) ->
     Mod:recover(Arg).
 
 
-start_link(Key) ->
-    Pid = proc_lib:spawn_link(?MODULE, init, [Key]),
+insert({Mod, Arg}, Value) ->
+    Mod:insert(Arg, Value).
+
+
+start_link(Key, Default) ->
+    Pid = proc_lib:spawn_link(?MODULE, init, [{Key, Default}]),
     {ok, Pid}.
 
 
@@ -99,7 +104,7 @@ refresh(Pid) ->
     gen_server:cast(Pid, force_refresh).
 
 
-init(Key) ->
+init({Key, undefined}) ->
     true = ets:update_element(?CACHE, Key, {#entry.pid, self()}),
     St = #st{
         key = Key,
@@ -108,6 +113,26 @@ init(Key) ->
         accessed = 1
     },
     ?EVENT(started, Key),
+    gen_server:enter_loop(?MODULE, [], St);
+
+init({Key, Default}) ->
+    Updates = [
+        {#entry.val, Default},
+        {#entry.pid, self()}
+    ],
+    NewTs = os:timestamp(),
+    true = ets:update_element(?CACHE, Key, Updates),
+    true = ets:insert(?LRU, {{NewTs, Key, self()}}),
+    Msg = {'$gen_cast', refresh},
+    St = #st{
+        key = Key,
+        val = {open_ok, {ok, Default}},
+        opener = erlang:send_after(?REFRESH_TIMEOUT, self(), Msg),
+        waiters = undefined,
+        ts = NewTs,
+        accessed = 1
+    },
+    ?EVENT(default_started, Key),
     gen_server:enter_loop(?MODULE, [], St).
 
 
diff --git a/src/ddoc_cache/src/ddoc_cache_entry_custom.erl b/src/ddoc_cache/src/ddoc_cache_entry_custom.erl
index d858ad6..9eaf16f 100644
--- a/src/ddoc_cache/src/ddoc_cache_entry_custom.erl
+++ b/src/ddoc_cache/src/ddoc_cache_entry_custom.erl
@@ -16,7 +16,8 @@
 -export([
     dbname/1,
     ddocid/1,
-    recover/1
+    recover/1,
+    insert/2
 ]).
 
 
@@ -30,3 +31,7 @@ ddocid(_) ->
 
 recover({DbName, Mod}) ->
     Mod:recover(DbName).
+
+
+insert(_, _) ->
+    ok.
diff --git a/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl b/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl
index cac9abc..5248469 100644
--- a/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl
+++ b/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl
@@ -16,7 +16,8 @@
 -export([
     dbname/1,
     ddocid/1,
-    recover/1
+    recover/1,
+    insert/2
 ]).
 
 
@@ -33,3 +34,13 @@ ddocid({_, DDocId}) ->
 
 recover({DbName, DDocId}) ->
     fabric:open_doc(DbName, DDocId, [ejson_body, ?ADMIN_CTX]).
+
+
+insert({DbName, DDocId}, {ok, #doc{revs = Revs} = DDoc}) ->
+    {Depth, [RevId | _]} = Revs,
+    Rev = {Depth, RevId},
+    Key = {ddoc_cache_entry_ddocid_rev, {DbName, DDocId, Rev}},
+    spawn(fun() -> ddoc_cache_lru:insert(Key, DDoc) end);
+
+insert(_, _) ->
+    ok.
diff --git a/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl b/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl
index 012abab..868fa77 100644
--- a/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl
+++ b/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl
@@ -16,7 +16,8 @@
 -export([
     dbname/1,
     ddocid/1,
-    recover/1
+    recover/1,
+    insert/2
 ]).
 
 
@@ -35,3 +36,12 @@ recover({DbName, DDocId, Rev}) ->
     Opts = [ejson_body, ?ADMIN_CTX],
     {ok, [Resp]} = fabric:open_revs(DbName, DDocId, [Rev], Opts),
     Resp.
+
+
+insert({DbName, DDocId, _Rev}, {ok, #doc{} = DDoc}) ->
+    Key = {ddoc_cache_entry_ddocid, {DbName, DDocId}},
+    spawn(fun() -> ddoc_cache_lru:insert(Key, DDoc) end);
+
+insert(_, _) ->
+    ok.
+
diff --git a/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl b/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
index 3d43f7a..2182dea 100644
--- a/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
+++ b/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
@@ -16,7 +16,8 @@
 -export([
     dbname/1,
     ddocid/1,
-    recover/1
+    recover/1,
+    insert/2
 ]).
 
 
@@ -37,3 +38,7 @@ recover(DbName) ->
         end
     end, DDocs),
     {ok, Funs}.
+
+
+insert(_, _) ->
+    ok.
diff --git a/src/ddoc_cache/src/ddoc_cache_lru.erl b/src/ddoc_cache/src/ddoc_cache_lru.erl
index cbe481e..6ae4de4 100644
--- a/src/ddoc_cache/src/ddoc_cache_lru.erl
+++ b/src/ddoc_cache/src/ddoc_cache_lru.erl
@@ -18,6 +18,7 @@
 -export([
     start_link/0,
     open/1,
+    insert/2,
     refresh/2
 ]).
 
@@ -53,9 +54,9 @@ start_link() ->
 open(Key) ->
     try ets:lookup(?CACHE, Key) of
         [] ->
-            lru_start(Key);
+            lru_start(Key, true);
         [#entry{pid = undefined}] ->
-            lru_start(Key);
+            lru_start(Key, false);
         [#entry{val = undefined, pid = Pid}] ->
             couch_stats:increment_counter([ddoc_cache, miss]),
             ddoc_cache_entry:open(Pid, Key);
@@ -69,6 +70,15 @@ open(Key) ->
     end.
 
 
+insert(Key, Value) ->
+    case ets:lookup(?CACHE, Key) of
+        [] ->
+            gen_server:call(?MODULE, {start, Key, Value}, infinity);
+        [#entry{}] ->
+            ok
+    end.
+
+
 refresh(DbName, DDocIds) ->
     gen_server:cast(?MODULE, {refresh, DbName, DDocIds}).
 
@@ -96,7 +106,7 @@ terminate(_Reason, St) ->
     ok.
 
 
-handle_call({start, Key}, _From, St) ->
+handle_call({start, Key, Default}, _From, St) ->
     #st{
         pids = Pids,
         dbs = Dbs,
@@ -108,7 +118,7 @@ handle_call({start, Key}, _From, St) ->
             case trim(St, CurSize, max(0, MaxSize)) of
                 {ok, N} ->
                     true = ets:insert_new(?CACHE, #entry{key = Key}),
-                    {ok, Pid} = ddoc_cache_entry:start_link(Key),
+                    {ok, Pid} = ddoc_cache_entry:start_link(Key, Default),
                     true = ets:update_element(?CACHE, Key, {#entry.pid, Pid}),
                     ok = khash:put(Pids, Pid, Key),
                     store_key(Dbs, Key, Pid),
@@ -167,7 +177,7 @@ handle_cast({do_refresh, DbName, DDocIdList}, St) ->
             lists:foreach(fun(DDocId) ->
                 case khash:lookup(DDocIds, DDocId) of
                     {value, Keys} ->
-                        khash:fold(Keys, fun(_, Pid, _) ->
+                        khash:fold(Keys, fun(Key, Pid, _) ->
                             ddoc_cache_entry:refresh(Pid)
                         end, nil);
                     not_found ->
@@ -222,11 +232,15 @@ handle_db_event(_DbName, _Event, St) ->
     {ok, St}.
 
 
-lru_start(Key) ->
-    case gen_server:call(?MODULE, {start, Key}, infinity) of
+lru_start(Key, DoInsert) ->
+    case gen_server:call(?MODULE, {start, Key, undefined}, infinity) of
         {ok, Pid} ->
             couch_stats:increment_counter([ddoc_cache, miss]),
-            ddoc_cache_entry:open(Pid, Key);
+            Resp = ddoc_cache_entry:open(Pid, Key),
+            if not DoInsert -> ok; true ->
+                ddoc_cache_entry:insert(Key, Resp)
+            end,
+            Resp;
         full ->
             couch_stats:increment_counter([ddoc_cache, recovery]),
             ddoc_cache_entry:recover(Key)
diff --git a/src/ddoc_cache/test/ddoc_cache_basic_test.erl b/src/ddoc_cache/test/ddoc_cache_basic_test.erl
index f908c78..7f6dbc9 100644
--- a/src/ddoc_cache/test/ddoc_cache_basic_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_basic_test.erl
@@ -27,11 +27,22 @@ recover(DbName) ->
     {ok, {DbName, totes_custom}}.
 
 
+start_couch() ->
+    Ctx = ddoc_cache_tutil:start_couch(),
+    meck:new(ddoc_cache_ev, [passthrough]),
+    Ctx.
+
+
+stop_couch(Ctx) ->
+    meck:unload(),
+    ddoc_cache_tutil:stop_couch(Ctx).
+
+
 check_basic_test_() ->
     {
         setup,
-        fun ddoc_cache_tutil:start_couch/0,
-        fun ddoc_cache_tutil:stop_couch/1,
+        fun start_couch/0,
+        fun stop_couch/1,
         {with, [
             fun cache_ddoc/1,
             fun cache_ddoc_rev/1,
@@ -58,25 +69,31 @@ check_no_vdu_test_() ->
 
 cache_ddoc({DbName, _}) ->
     ddoc_cache_tutil:clear(),
+    meck:reset(ddoc_cache_ev),
     ?assertEqual(0, ets:info(?CACHE, size)),
     Resp1 = ddoc_cache:open_doc(DbName, ?FOOBAR),
     ?assertMatch({ok, #doc{id = ?FOOBAR}}, Resp1),
-    ?assertEqual(1, ets:info(?CACHE, size)),
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+    ?assertEqual(2, ets:info(?CACHE, size)),
     Resp2 = ddoc_cache:open_doc(DbName, ?FOOBAR),
     ?assertEqual(Resp1, Resp2),
-    ?assertEqual(1, ets:info(?CACHE, size)).
+    ?assertEqual(2, ets:info(?CACHE, size)).
 
 
 cache_ddoc_rev({DbName, _}) ->
     ddoc_cache_tutil:clear(),
+    meck:reset(ddoc_cache_ev),
     Rev = ddoc_cache_tutil:get_rev(DbName, ?FOOBAR),
     ?assertEqual(0, ets:info(?CACHE, size)),
     Resp1 = ddoc_cache:open_doc(DbName, ?FOOBAR, Rev),
     ?assertMatch({ok, #doc{id = ?FOOBAR}}, Resp1),
-    ?assertEqual(1, ets:info(?CACHE, size)),
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+    ?assertEqual(2, ets:info(?CACHE, size)),
     Resp2 = ddoc_cache:open_doc(DbName, ?FOOBAR, Rev),
     ?assertEqual(Resp1, Resp2),
-    ?assertEqual(1, ets:info(?CACHE, size)),
+    ?assertEqual(2, ets:info(?CACHE, size)),
 
     % Assert that the non-rev cache entry is separate
     Resp3 = ddoc_cache:open_doc(DbName, ?FOOBAR),
@@ -108,12 +125,16 @@ cache_custom({DbName, _}) ->
 
 cache_ddoc_refresher_unchanged({DbName, _}) ->
     ddoc_cache_tutil:clear(),
+    meck:reset(ddoc_cache_ev),
     ?assertEqual(0, ets:info(?CACHE, size)),
     ddoc_cache:open_doc(DbName, ?FOOBAR),
-    [Entry1] = ets:lookup(?CACHE, ets:first(?CACHE)),
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+    Tab1 = [_, _] = lists:sort(ets:tab2list(?CACHE)),
     ddoc_cache:open_doc(DbName, ?FOOBAR),
-    [Entry2] = ets:lookup(?CACHE, ets:first(?CACHE)),
-    ?assertEqual(Entry1, Entry2).
+    meck:wait(ddoc_cache_ev, event, [accessed, '_'], 1000),
+    Tab2 = lists:sort(ets:tab2list(?CACHE)),
+    ?assertEqual(Tab2, Tab1).
 
 
 dont_cache_not_found({DbName, _}) ->
diff --git a/src/ddoc_cache/test/ddoc_cache_entry_test.erl b/src/ddoc_cache/test/ddoc_cache_entry_test.erl
index e593bf7..381185c 100644
--- a/src/ddoc_cache/test/ddoc_cache_entry_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_entry_test.erl
@@ -61,7 +61,7 @@ check_entry_test_() ->
 cancel_and_replace_opener(_) ->
     Key = {ddoc_cache_entry_custom, {<<"foo">>, ?MODULE}},
     true = ets:insert_new(?CACHE, #entry{key = Key}),
-    {ok, Entry} = ddoc_cache_entry:start_link(Key),
+    {ok, Entry} = ddoc_cache_entry:start_link(Key, undefined),
     Opener1 = element(4, sys:get_state(Entry)),
     Ref1 = erlang:monitor(process, Opener1),
     gen_server:cast(Entry, force_refresh),
@@ -78,7 +78,7 @@ condenses_access_messages({DbName, _}) ->
     meck:reset(ddoc_cache_ev),
     Key = {ddoc_cache_entry_custom, {DbName, ?MODULE}},
     true = ets:insert(?CACHE, #entry{key = Key}),
-    {ok, Entry} = ddoc_cache_entry:start_link(Key),
+    {ok, Entry} = ddoc_cache_entry:start_link(Key, undefined),
     erlang:suspend_process(Entry),
     lists:foreach(fun(_) ->
         gen_server:cast(Entry, accessed)
@@ -105,7 +105,7 @@ evict_when_not_accessed(_) ->
     meck:reset(ddoc_cache_ev),
     Key = {ddoc_cache_entry_custom, {<<"bar">>, ?MODULE}},
     true = ets:insert_new(?CACHE, #entry{key = Key}),
-    {ok, Entry} = ddoc_cache_entry:start_link(Key),
+    {ok, Entry} = ddoc_cache_entry:start_link(Key, undefined),
     Ref = erlang:monitor(process, Entry),
     ?assertEqual(1, element(7, sys:get_state(Entry))),
     ok = gen_server:cast(Entry, refresh),
diff --git a/src/ddoc_cache/test/ddoc_cache_eviction_test.erl b/src/ddoc_cache/test/ddoc_cache_eviction_test.erl
index 0b9f57b..30b4fb7 100644
--- a/src/ddoc_cache/test/ddoc_cache_eviction_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_eviction_test.erl
@@ -86,8 +86,10 @@ check_upgrade_clause({DbName, _}) ->
     ddoc_cache_tutil:clear(),
     meck:reset(ddoc_cache_ev),
     {ok, _} = ddoc_cache:open_doc(DbName, ?FOOBAR),
-    ?assertEqual(1, ets:info(?CACHE, size)),
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+    ?assertEqual(2, ets:info(?CACHE, size)),
     gen_server:cast(ddoc_cache_opener, {do_evict, DbName}),
     meck:wait(ddoc_cache_ev, event, [evicted, DbName], 1000),
-    meck:wait(ddoc_cache_ev, event, [removed, '_'], 1000),
+    meck:wait(2, ddoc_cache_ev, event, [removed, '_'], 1000),
     ?assertEqual(0, ets:info(?CACHE, size)).
diff --git a/src/ddoc_cache/test/ddoc_cache_no_cache_test.erl b/src/ddoc_cache/test/ddoc_cache_no_cache_test.erl
index a5a5751..637a6e8 100644
--- a/src/ddoc_cache/test/ddoc_cache_no_cache_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_no_cache_test.erl
@@ -20,6 +20,7 @@
 ddoc(DDocId) ->
     {ok, #doc{
         id = DDocId,
+        revs = {1, [<<"deadbeefdeadbeef">>]},
         body = {[
             {<<"ohai">>, null}
         ]}
diff --git a/src/ddoc_cache/test/ddoc_cache_open_error_test.erl b/src/ddoc_cache/test/ddoc_cache_open_error_test.erl
index 0ac2390..f3a9b10 100644
--- a/src/ddoc_cache/test/ddoc_cache_open_error_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_open_error_test.erl
@@ -31,7 +31,7 @@ stop_couch(Ctx) ->
     ddoc_cache_tutil:stop_couch(Ctx).
 
 
-check_basic_test_() ->
+check_open_error_test_() ->
     {
         setup,
         fun start_couch/0,
diff --git a/src/ddoc_cache/test/ddoc_cache_refresh_test.erl b/src/ddoc_cache/test/ddoc_cache_refresh_test.erl
index 7bc1704..f145987 100644
--- a/src/ddoc_cache/test/ddoc_cache_refresh_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_refresh_test.erl
@@ -58,8 +58,11 @@ refresh_ddoc({DbName, _}) ->
     ddoc_cache_tutil:clear(),
     meck:reset(ddoc_cache_ev),
     {ok, _} = ddoc_cache:open_doc(DbName, ?FOOBAR),
-    ?assertEqual(1, ets:info(?CACHE, size)),
-    [#entry{key = Key, val = DDoc}] = ets:tab2list(?CACHE),
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+
+    ?assertEqual(2, ets:info(?CACHE, size)),
+    [#entry{key = Key, val = DDoc}, _] = lists:sort(ets:tab2list(?CACHE)),
     NewDDoc = DDoc#doc{
         body = {[{<<"foo">>, <<"baz">>}]}
     },
@@ -69,7 +72,7 @@ refresh_ddoc({DbName, _}) ->
     },
     meck:wait(ddoc_cache_ev, event, [updated, {Key, Expect}], 1000),
     ?assertMatch({ok, Expect}, ddoc_cache:open_doc(DbName, ?FOOBAR)),
-    ?assertEqual(1, ets:info(?CACHE, size)).
+    ?assertEqual(2, ets:info(?CACHE, size)).
 
 
 refresh_ddoc_rev({DbName, _}) ->
@@ -77,7 +80,11 @@ refresh_ddoc_rev({DbName, _}) ->
     meck:reset(ddoc_cache_ev),
     Rev = ddoc_cache_tutil:get_rev(DbName, ?FOOBAR),
     {ok, RevDDoc} = ddoc_cache:open_doc(DbName, ?FOOBAR, Rev),
-    [#entry{key = Key, val = DDoc}] = ets:tab2list(?CACHE),
+
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+
+    [_, #entry{key = Key, val = DDoc}] = lists:sort(ets:tab2list(?CACHE)),
     NewDDoc = DDoc#doc{
         body = {[{<<"foo">>, <<"kazam">>}]}
     },
@@ -86,7 +93,7 @@ refresh_ddoc_rev({DbName, _}) ->
     % getting the same original response from the cache
     meck:wait(ddoc_cache_ev, event, [update_noop, Key], 1000),
     ?assertMatch({ok, RevDDoc}, ddoc_cache:open_doc(DbName, ?FOOBAR, Rev)),
-    ?assertEqual(1, ets:info(?CACHE, size)).
+    ?assertEqual(2, ets:info(?CACHE, size)).
 
 
 refresh_vdu({DbName, _}) ->
diff --git a/src/ddoc_cache/test/ddoc_cache_remove_test.erl b/src/ddoc_cache/test/ddoc_cache_remove_test.erl
index 7596b99..8787482 100644
--- a/src/ddoc_cache/test/ddoc_cache_remove_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_remove_test.erl
@@ -67,16 +67,26 @@ remove_ddoc({DbName, _}) ->
     meck:reset(ddoc_cache_ev),
     ?assertEqual(0, ets:info(?CACHE, size)),
     {ok, _} = ddoc_cache:open_doc(DbName, ?FOOBAR),
-    ?assertEqual(1, ets:info(?CACHE, size)),
-    [#entry{key = Key, val = DDoc}] = ets:tab2list(?CACHE),
+
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+
+    [#entry{val = DDoc}, #entry{val = DDoc}] = ets:tab2list(?CACHE),
+    {Depth, [RevId | _]} = DDoc#doc.revs,
     NewDDoc = DDoc#doc{
         deleted = true,
         body = {[]}
     },
     {ok, _} = fabric:update_doc(DbName, NewDDoc, [?ADMIN_CTX]),
-    meck:wait(ddoc_cache_ev, event, [removed, Key], 1000),
+
+    DDocIdKey = {ddoc_cache_entry_ddocid, {DbName, ?FOOBAR}},
+    Rev = {Depth, RevId},
+    DDocIdRevKey = {ddoc_cache_entry_ddocid_rev, {DbName, ?FOOBAR, Rev}},
+    meck:wait(ddoc_cache_ev, event, [removed, DDocIdKey], 1000),
+    meck:wait(ddoc_cache_ev, event, [update_noop, DDocIdRevKey], 1000),
+
     ?assertMatch({not_found, deleted}, ddoc_cache:open_doc(DbName, ?FOOBAR)),
-    ?assertEqual(0, ets:info(?CACHE, size)).
+    ?assertEqual(1, ets:info(?CACHE, size)).
 
 
 remove_ddoc_rev({DbName, _}) ->
@@ -84,7 +94,15 @@ remove_ddoc_rev({DbName, _}) ->
     meck:reset(ddoc_cache_ev),
     Rev = ddoc_cache_tutil:get_rev(DbName, ?VDU),
     {ok, _} = ddoc_cache:open_doc(DbName, ?VDU, Rev),
-    [#entry{key = Key, val = DDoc, pid = Pid}] = ets:tab2list(?CACHE),
+
+    meck:wait(ddoc_cache_ev, event, [started, '_'], 1000),
+    meck:wait(ddoc_cache_ev, event, [default_started, '_'], 1000),
+
+    % Notice the sort so that we know we're getting the
+    % revid version second.
+    [_, #entry{key = Key, val = DDoc, pid = Pid}]
+            = lists:sort(ets:tab2list(?CACHE)),
+
     NewDDoc = DDoc#doc{
         body = {[{<<"an">>, <<"update">>}]}
     },
@@ -101,7 +119,7 @@ remove_ddoc_rev({DbName, _}) ->
             {{not_found, missing}, _},
             ddoc_cache:open_doc(DbName, ?VDU, Rev)
         ),
-    ?assertEqual(0, ets:info(?CACHE, size)).
+    ?assertEqual(1, ets:info(?CACHE, size)).
 
 
 remove_ddoc_rev_only({DbName, _}) ->

-- 
To stop receiving notification emails like this one, please contact
"commits@couchdb.apache.org" <co...@couchdb.apache.org>.