Skip to content

Commit

Permalink
Fix timeout in couchdb_views_test for couchdb_1283
Browse files Browse the repository at this point in the history
I believe the race here was that the query could return before the
actual index updating process exited. Then it was just a race to
creating a database before the monitor is released.

If we do end up creating the database before the monitor is released
then the database we want to have closed ends up being ignored as its
not idle. The second two created databases then don't end up forcing the
database from couch_server's LRU which leads us to the timeout waiting
for DatabaseMonRef to fire.

Fixes #655
  • Loading branch information
davisp committed Jul 12, 2017
1 parent 94f2907 commit a50dd7e
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/couch/test/couchdb_views_tests.erl
Expand Up @@ -345,6 +345,13 @@ couchdb_1283() ->
% monitor db and index pids
{ok, DDPid} = couch_index_server:get_index(
couch_mrview_index, MDb1#db.name, <<"_design/foo">>),

% Our query could have run after a partial update
% so we need to make sure that the updater has
% exited and released its monitor on the database
% fd.
wait_for_updater_exit(DDPid),

DesignDocMonRef = erlang:monitor(process, DDPid),
DatabaseMonRef = erlang:monitor(process, MDb1#db.main_pid),

Expand Down Expand Up @@ -629,6 +636,26 @@ wait_view_compact_done(DbName, DDocId, N) ->
wait_view_compact_done(DbName, DDocId, N - 1)
end.

% This is a bit of a dirty hack fishing through various
% state records but at least its better than putting
% a sleep on it and calling it fixed.
wait_for_updater_exit(DDPid) ->
% #st record from couch_index.erl
IdxState = sys:get_state(DDPid),
UpdaterPid = element(4, IdxState),

% #st record from couch_index_updater.erl
UpdaterState = sys:get_state(UpdaterPid),
RunnerPid = element(4, UpdaterState),

% RunnerPid can be nil, undefined, or a pid so
% just check if its a pid and wait on it to
% exit
if not is_pid(RunnerPid) -> ok; true ->
Ref = erlang:monitor(process, RunnerPid),
receive {'DOWN', Ref, _, _, _} -> ok end
end.

spawn_writer(DbName) ->
Parent = self(),
spawn(fun() ->
Expand Down

0 comments on commit a50dd7e

Please sign in to comment.