diff options
author | Jay Doane <jaydoane@apache.org> | 2021-12-09 19:17:19 -0800 |
---|---|---|
committer | Jay Doane <jaydoane@apache.org> | 2022-01-12 08:50:20 -0800 |
commit | 7e943e39826ae816d7f4526ca08d8669ae4a534c (patch) | |
tree | 8e4449de8afdf4d40b135975612b504ce3e1a478 | |
parent | 6e8713d3be142ac8a55727aa097a1ba52d087702 (diff) | |
download | couchdb-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.erl | 28 |
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) -> |