You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2019/11/22 00:51:43 UTC
[couchdb] branch expiring-cache updated: Documentation & cleanup
This is an automated email from the ASF dual-hosted git repository.
jaydoane pushed a commit to branch expiring-cache
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/expiring-cache by this push:
new 43894b1 Documentation & cleanup
43894b1 is described below
commit 43894b11f31792d0f028182eb7202104998d3c7b
Author: Jay Doane <ja...@apache.org>
AuthorDate: Thu Nov 21 15:23:30 2019 -0800
Documentation & cleanup
---
src/couch_expiring_cache/README.md | 19 +++++++++-
.../include/couch_expiring_cache.hrl | 14 ++++++++
.../src/couch_expiring_cache.erl | 16 +++++++--
.../src/couch_expiring_cache_fdb.erl | 12 +++++--
.../src/couch_expiring_cache_server.erl | 42 ++++++++++++----------
.../test/couch_expiring_cache_tests.erl | 6 ++--
6 files changed, 81 insertions(+), 28 deletions(-)
diff --git a/src/couch_expiring_cache/README.md b/src/couch_expiring_cache/README.md
index 34cbc09..049b787 100644
--- a/src/couch_expiring_cache/README.md
+++ b/src/couch_expiring_cache/README.md
@@ -1,3 +1,20 @@
# Couch Expiring Cache
-Key value cache with expiring entries.
+Key value cache with entries which are automatically deleted after
+they expire.
+
+This is a description of some of the modules:
+
+* `couch_expiring_cache`: The API module, it contains functions for
+ inserting and looking up cache entries, which are simply
+ pass-throughs to `couch_expiring_cache_fdb`.
+
+* `couch_expiring_cache_fdb`: The module which interacts with FDB, in
+ addition to insertion and lookup functions, it also contains a
+ function to clear an expired range.
+
+* `couch_expiring_cache_server`: A gen_server, this module
+ periodically removes expired cache entries using configurable
+ parameters for period, jitter, and batch size. It also fetches the
+ layer prefix on startup, and caches it in an ets table for
+ performance.
diff --git a/src/couch_expiring_cache/include/couch_expiring_cache.hrl b/src/couch_expiring_cache/include/couch_expiring_cache.hrl
index fe771c5..0d24025 100644
--- a/src/couch_expiring_cache/include/couch_expiring_cache.hrl
+++ b/src/couch_expiring_cache/include/couch_expiring_cache.hrl
@@ -1 +1,15 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
-define(TIME_UNIT, millisecond).
+
+-type millisecond() :: non_neg_integer().
diff --git a/src/couch_expiring_cache/src/couch_expiring_cache.erl b/src/couch_expiring_cache/src/couch_expiring_cache.erl
index 61f4c20..3e6a48a 100644
--- a/src/couch_expiring_cache/src/couch_expiring_cache.erl
+++ b/src/couch_expiring_cache/src/couch_expiring_cache.erl
@@ -1,3 +1,15 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
-module(couch_expiring_cache).
-export([
@@ -6,11 +18,11 @@
]).
--type millisecond() :: non_neg_integer().
+-include_lib("couch_expiring_cache/include/couch_expiring_cache.hrl").
-spec insert(Name :: binary(), Key :: binary(), Value :: binary(),
- StaleTS :: millisecond(), ExpiresTS :: millisecond()) -> ok.
+ StaleTS :: millisecond(), ExpiresTS :: millisecond()) -> ok.
insert(Name, Key, Value, StaleTS, ExpiresTS) ->
couch_expiring_cache_fdb:insert(Name, Key, Value, StaleTS, ExpiresTS).
diff --git a/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl b/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl
index febf103..a9aac82 100644
--- a/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl
+++ b/src/couch_expiring_cache/src/couch_expiring_cache_fdb.erl
@@ -34,6 +34,8 @@
% (?XC, ?EXP, ExpireTS, Name, Key) := ()
+-spec insert(Name :: binary(), Key :: binary(), Value :: binary(),
+ StaleTS :: millisecond(), ExpiresTS :: millisecond()) -> ok.
insert(Name, Key, Val, StaleTS, ExpiresTS) ->
LayerPrefix = couch_expiring_cache_server:layer_prefix(),
PK = primary_key(Name, Key, LayerPrefix),
@@ -46,6 +48,8 @@ insert(Name, Key, Val, StaleTS, ExpiresTS) ->
end).
+-spec lookup(Name :: binary(), Key :: binary()) ->
+ not_found | {fresh, Val :: binary()} | {stale, Val :: binary()} | expired.
lookup(Name, Key) ->
LayerPrefix = couch_expiring_cache_server:layer_prefix(),
PK = primary_key(Name, Key, LayerPrefix),
@@ -65,17 +69,19 @@ lookup(Name, Key) ->
end).
+-spec clear_expired_range(EndTS :: millisecond(), Limit :: non_neg_integer()) ->
+ OldestTS :: integer().
clear_expired_range(EndTS, Limit) when Limit > 0 ->
+ LayerPrefix = couch_expiring_cache_server:layer_prefix(),
+ ExpiresPrefix = erlfdb_tuple:pack({?XC, ?EXP}, LayerPrefix),
Callback = fun
(TS, 0) when TS > 0 -> TS;
(TS, Acc) -> min(TS, Acc)
end,
- LayerPrefix = couch_expiring_cache_server:layer_prefix(),
- ExpiresPrefix = erlfdb_tuple:pack({?XC, ?EXP}, LayerPrefix),
fabric2_fdb:transactional(fun(Tx) ->
fabric2_fdb:fold_range({tx, Tx}, ExpiresPrefix, fun({K, _V}, Acc) ->
Unpacked = erlfdb_tuple:unpack(K, ExpiresPrefix),
- couch_log:info("~p clearing ~p", [?MODULE, Unpacked]),
+ couch_log:debug("~p clearing ~p", [?MODULE, Unpacked]),
{ExpiresTS, Name, Key} = Unpacked,
clear_expired(Tx, ExpiresTS, Name, Key, LayerPrefix),
Callback(ExpiresTS, Acc)
diff --git a/src/couch_expiring_cache/src/couch_expiring_cache_server.erl b/src/couch_expiring_cache/src/couch_expiring_cache_server.erl
index e14e863..b2ab221 100644
--- a/src/couch_expiring_cache/src/couch_expiring_cache_server.erl
+++ b/src/couch_expiring_cache/src/couch_expiring_cache_server.erl
@@ -46,11 +46,12 @@ start_link() ->
init(_) ->
?MODULE = ets:new(?MODULE, [named_table, public, {read_concurrency, true}]),
- true = set_layer_prefix(),
+ true = ets_insert_layer_prefix(),
{ok, #{
timer_ref => schedule_remove_expired(),
- last_removal => 0,
oldest_ts => 0,
+ elapsed => 0,
+ largest_elapsed => 0,
lag => 0}}.
@@ -66,15 +67,24 @@ handle_cast(Msg, St) ->
{stop, {bad_cast, Msg}, St}.
-handle_info(remove_expired, St = #{oldest_ts := OldestTS0}) ->
- Now = erlang:system_time(?TIME_UNIT),
- OldestTS = max(OldestTS0, remove_expired(Now)),
- Ref = schedule_remove_expired(),
+handle_info(remove_expired, St) ->
+ #{
+ oldest_ts := OldestTS0,
+ largest_elapsed := LargestElapsed
+ } = St,
+ BatchSize = batch_size(),
+
+ NowTS = erlang:system_time(?TIME_UNIT),
+ OldestTS = max(OldestTS0,
+ couch_expiring_cache_fdb:clear_expired_range(NowTS, BatchSize)),
+ Elapsed = erlang:system_time(?TIME_UNIT) - NowTS,
+
{noreply, St#{
- timer_ref := Ref,
- last_removal := Now,
+ timer_ref := schedule_remove_expired(),
oldest_ts := OldestTS,
- lag := Now - OldestTS}};
+ elapsed := Elapsed,
+ largest_elapsed := max(Elapsed, LargestElapsed),
+ lag := NowTS - OldestTS}};
handle_info(Msg, St) ->
{stop, {bad_info, Msg}, St}.
@@ -92,15 +102,11 @@ layer_prefix() ->
%% Private
-set_layer_prefix() ->
- fabric2_fdb:transactional(fun(Tx) ->
- LayerPrefix = fabric2_fdb:get_dir(Tx),
- true = ets:insert(?MODULE, {layer_prefix, LayerPrefix})
- end).
-
-
-remove_expired(EndTS) ->
- couch_expiring_cache_fdb:clear_expired_range(EndTS, batch_size()).
+ets_insert_layer_prefix() ->
+ Prefix = fabric2_fdb:transactional(fun(Tx) ->
+ fabric2_fdb:get_dir(Tx)
+ end),
+ true = ets:insert(?MODULE, {layer_prefix, Prefix}).
schedule_remove_expired() ->
diff --git a/src/couch_expiring_cache/test/couch_expiring_cache_tests.erl b/src/couch_expiring_cache/test/couch_expiring_cache_tests.erl
index 95748e2..808d5cd 100644
--- a/src/couch_expiring_cache/test/couch_expiring_cache_tests.erl
+++ b/src/couch_expiring_cache/test/couch_expiring_cache_tests.erl
@@ -42,8 +42,7 @@ setup_couch() ->
teardown_couch(Ctx) ->
- test_util:stop_couch(Ctx),
- meck:unload().
+ test_util:stop_couch(Ctx).
setup() ->
@@ -54,8 +53,7 @@ setup() ->
teardown(#{}) ->
- application:stop(couch_expiring_cache),
- meck:unload().
+ application:stop(couch_expiring_cache).
simple_lifecycle(#{}) ->