summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Doane <jaydoane@apache.org>2021-12-09 19:17:19 -0800
committerJay Doane <jaydoane@apache.org>2022-01-12 08:50:20 -0800
commit7e943e39826ae816d7f4526ca08d8669ae4a534c (patch)
tree8e4449de8afdf4d40b135975612b504ce3e1a478
parent6e8713d3be142ac8a55727aa097a1ba52d087702 (diff)
downloadcouchdb-ddoc-cache-lru-remove-key-crash.tar.gz
Handle `not_found` lookups removing ddoc cache keyddoc-cache-lru-remove-key-crash
Current implementation of `ddoc_cache_lru:remove_key/2` assumes that lookups always return values, but these log entries beg to differ: [error] 2021-12-10T02:25:21.622743Z node1@127.0.0.1 <0.18923.9> -------- gen_server ddoc_cache_lru terminated with reason: no match of right hand value not_found at ddoc_cache_lru:remove_key/2(line:308) <= ddoc_cache_lru:handle_info/2(line:219) <= gen_server:try_dispatch/4(line:637) <= gen_server:handle_msg/6(line:711) <= proc_lib:init_p_do_apply/3(line:249) [error] 2021-12-10T02:25:21.623418Z node1@127.0.0.1 <0.18923.9> -------- CRASH REPORT Process ddoc_cache_lru (<0.18923.9>) with 0 neighbors crashed with reason: no match of right hand value not_found at ddoc_cache_lru:remove_key/2(line:308) <= ddoc_cache_lru:handle_info/2(line:219) <= gen_server:try_dispatch/4(line:637) <= gen_server:handle_msg/6(line:711) <= proc_lib:init_p_do_apply/3(line:249); initial_call: {ddoc_cache_lru,init,['Argument__1']}, ancestors: [ddoc_cache_sup,<0.4537.0>], message_queue_len: 2, links: [<0.4541.0>], dictionary: [], trap_exit: true, status: running, heap_size: 1598, stack_size: 27, reductions: 545194 [error] 2021-12-10T02:25:21.623898Z node1@127.0.0.1 <0.4541.0> -------- Supervisor ddoc_cache_sup had child ddoc_cache_lru started with ddoc_cache_lru:start_link() at <0.18923.9> exit with reason no match of right hand value not_found at ddoc_cache_lru:remove_key/2(line:308) <= ddoc_cache_lru:handle_info/2(line:219) <= gen_server:try_dispatch/4(line:637) <= gen_server:handle_msg/6(line:711) <= proc_lib:init_p_do_apply/3(line:249) in context child_terminated This checks the return values of `khash:lookup` and only proceeds to delete keys if the results are other than `not_found`.
-rw-r--r--src/ddoc_cache/src/ddoc_cache_lru.erl28
1 files changed, 18 insertions, 10 deletions
diff --git a/src/ddoc_cache/src/ddoc_cache_lru.erl b/src/ddoc_cache/src/ddoc_cache_lru.erl
index ec8f5caaa..d2b226710 100644
--- a/src/ddoc_cache/src/ddoc_cache_lru.erl
+++ b/src/ddoc_cache/src/ddoc_cache_lru.erl
@@ -296,16 +296,24 @@ remove_key(St, Key) ->
} = St,
DbName = ddoc_cache_entry:dbname(Key),
DDocId = ddoc_cache_entry:ddocid(Key),
- {value, DDocIds} = khash:lookup(Dbs, DbName),
- {value, Keys} = khash:lookup(DDocIds, DDocId),
- khash:del(Keys, Key),
- case khash:size(Keys) of
- 0 -> khash:del(DDocIds, DDocId);
- _ -> ok
- end,
- case khash:size(DDocIds) of
- 0 -> khash:del(Dbs, DbName);
- _ -> ok
+ case khash:lookup(Dbs, DbName) of
+ {value, DDocIds} ->
+ case khash:lookup(DDocIds, DDocId) of
+ {value, Keys} ->
+ ok = khash:del(Keys, Key),
+ case khash:size(Keys) of
+ 0 -> khash:del(DDocIds, DDocId);
+ _ -> ok
+ end,
+ case khash:size(DDocIds) of
+ 0 -> khash:del(Dbs, DbName);
+ _ -> ok
+ end;
+ not_found ->
+ ok
+ end;
+ not_found ->
+ ok
end.
unlink_and_flush(Pid) ->