summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2020-06-04 15:54:01 -0500
committerPaul J. Davis <paul.joseph.davis@gmail.com>2020-06-25 11:31:26 -0500
commit596715783514a9edaa1295757e23f03c6f87e38f (patch)
tree9aeed904f8979e9b68c5a9992a2f1f518cd15cbe
parent49949de441e1bd458aa1fab326c8b6c3c626f829 (diff)
downloadcouchdb-596715783514a9edaa1295757e23f03c6f87e38f.tar.gz
Condition cache storage/eviction on db_version
Now that db_version is comparable we can use that for cache control.
-rw-r--r--src/fabric/src/fabric2_server.erl10
-rw-r--r--src/fabric/test/fabric2_db_misc_tests.erl23
2 files changed, 19 insertions, 14 deletions
diff --git a/src/fabric/src/fabric2_server.erl b/src/fabric/src/fabric2_server.erl
index b557da8c7..067cf4949 100644
--- a/src/fabric/src/fabric2_server.erl
+++ b/src/fabric/src/fabric2_server.erl
@@ -94,12 +94,12 @@ store(#{name := DbName} = Db0) when is_binary(DbName) ->
maybe_update(#{name := DbName} = Db0) when is_binary(DbName) ->
#{
uuid := UUID,
- md_version := MDVer
+ db_version := DBVer
} = Db0,
Db1 = sanitize(Db0),
Head = {DbName, UUID, '$1', '_'},
- Guard = {'=<', '$1', MDVer},
- Body = {DbName, UUID, MDVer, {const, Db1}},
+ Guard = {'=<', '$1', DBVer},
+ Body = {DbName, UUID, DBVer, {const, Db1}},
try
1 =:= ets:select_replace(?MODULE, [{Head, [Guard], [{Body}]}])
catch
@@ -116,10 +116,10 @@ remove(DbName) when is_binary(DbName) ->
maybe_remove(#{name := DbName} = Db) when is_binary(DbName) ->
#{
uuid := UUID,
- md_version := MDVer
+ db_version := DBVer
} = Db,
Head = {DbName, UUID, '$1', '_'},
- Guard = {'=<', '$1', MDVer},
+ Guard = {'=<', '$1', DBVer},
1 =:= ets:select_delete(?MODULE, [{Head, [Guard], [true]}]).
diff --git a/src/fabric/test/fabric2_db_misc_tests.erl b/src/fabric/test/fabric2_db_misc_tests.erl
index a8a267763..cad91a530 100644
--- a/src/fabric/test/fabric2_db_misc_tests.erl
+++ b/src/fabric/test/fabric2_db_misc_tests.erl
@@ -340,13 +340,18 @@ metadata_bump({DbName, _, _}) ->
% Perform a random operation which calls ensure_current
{ok, _} = fabric2_db:get_db_info(Db),
+ % After previous operation, the cache should have been cleared
+ ?assertMatch(undefined, fabric2_server:fetch(DbName, undefined)),
+
+ % Call open again and check that we have the latest db version
+ {ok, Db2} = fabric2_db:open(DbName, [{user_ctx, ?ADMIN_USER}]),
+
% Check that db handle in the cache got the new metadata version
% and that check_current_ts was updated
- CachedDb = fabric2_server:fetch(DbName, undefined),
?assertMatch(#{
md_version := NewMDVersion,
check_current_ts := Ts
- } when Ts >= TsBeforeEnsureCurrent, CachedDb).
+ } when Ts >= TsBeforeEnsureCurrent, Db2).
db_version_bump({DbName, _, _}) ->
@@ -358,12 +363,12 @@ db_version_bump({DbName, _, _}) ->
% regular db open + update security doc or something like that to make sure
% we don't touch the local cache
#{db_prefix := DbPrefix} = Db,
- DbVersionKey = erlfdb_tuple:pack({?DB_VERSION}, DbPrefix),
{ok, Fdb} = application:get_env(fabric, db),
- NewDbVersion = fabric2_util:uuid(),
erlfdb:transactional(Fdb, fun(Tx) ->
- erlfdb:set(Tx, DbVersionKey, NewDbVersion),
- erlfdb:set_versionstamped_value(Tx, ?METADATA_VERSION_KEY, <<0:112>>)
+ DbVersionKey = erlfdb_tuple:pack({?DB_VERSION}, DbPrefix),
+ DbVersion = fabric2_fdb:new_versionstamp(Tx),
+ DbVersionVal = erlfdb_tuple:pack_vs({DbVersion}),
+ ok = erlfdb:set_versionstamped_value(Tx, DbVersionKey, DbVersionVal)
end),
% Perform a random operation which calls ensure_current
@@ -375,15 +380,15 @@ db_version_bump({DbName, _, _}) ->
% Call open again and check that we have the latest db version
{ok, Db2} = fabric2_db:open(DbName, [{user_ctx, ?ADMIN_USER}]),
- % Check that db handle in the cache got the new metadata version
- ?assertMatch(#{db_version := NewDbVersion}, Db2).
+ % Check that db handle in the cache got a newer version
+ ?assert(maps:get(db_version, Db) < maps:get(db_version, Db2)).
db_cache_doesnt_evict_newer_handles({DbName, _, _}) ->
{ok, Db} = fabric2_db:open(DbName, [{user_ctx, ?ADMIN_USER}]),
CachedDb = fabric2_server:fetch(DbName, undefined),
- StaleDb = Db#{md_version := <<0>>},
+ StaleDb = Db#{db_version := <<0>>},
ok = fabric2_server:store(StaleDb),
?assertEqual(CachedDb, fabric2_server:fetch(DbName, undefined)),