You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2019/08/22 20:02:32 UTC
[couchdb] branch prototype/fdb-layer-fix-db-reopen created (now
a7bd1f6)
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a change to branch prototype/fdb-layer-fix-db-reopen
in repository https://gitbox.apache.org/repos/asf/couchdb.git.
at a7bd1f6 Fix DB reopen behavior
This branch includes the following new commits:
new a7bd1f6 Fix DB reopen behavior
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[couchdb] 01/01: Fix DB reopen behavior
Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch prototype/fdb-layer-fix-db-reopen
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit a7bd1f6cda2198672ded096ee49b5ad32403d8b9
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Thu Aug 22 15:53:15 2019 -0400
Fix DB reopen behavior
Previously if a VDU was updated in the `before_doc_update/3` handlers, the Db
handle wasn't refreshed soon enough such that the `prepare_and_validate/3`
would not see the newly update VDU and would not run it.
To fix make a stale Db throws an exception which bubbles up all the way to
`fabric2_fdb:transactional/2` where the transaction is retried again with a
reopened Db.
During `reopen/1` make sure to properly transfer the `user_ctx` property to the
new handle, and also make sure `user_ctx` is removed from `db_options` to avoid
caching it in `fabric2_server`.
---
src/fabric/src/fabric2_fdb.erl | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index c58b5f6..df37096 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -78,10 +78,22 @@ transactional(DbName, Options, Fun) when is_binary(DbName) ->
transactional(#{tx := undefined} = Db, Fun) ->
- #{layer_prefix := LayerPrefix} = Db,
- do_transaction(fun(Tx) ->
- Fun(Db#{tx => Tx})
- end, LayerPrefix);
+ try
+ Reopen = maps:get(reopen, Db, false),
+ Db1 = maps:remove(reopen, Db),
+ LayerPrefix = case Reopen of
+ true -> undefined;
+ false -> maps:get(layer_prefix, Db1)
+ end,
+ do_transaction(fun(Tx) ->
+ case Reopen of
+ true -> Fun(reopen(Db1#{tx => Tx}));
+ false -> Fun(Db1#{tx => Tx})
+ end
+ end, LayerPrefix)
+ catch throw:{?MODULE, reopen} ->
+ transactional(Db#{reopen => true}, Fun)
+ end;
transactional(#{tx := {erlfdb_transaction, _}} = Db, Fun) ->
Fun(Db).
@@ -150,6 +162,7 @@ create(#{} = Db0, Options) ->
end, Defaults),
UserCtx = fabric2_util:get_value(user_ctx, Options, #user_ctx{}),
+ Options1 = lists:keydelete(user_ctx, 1, Options),
Db#{
uuid => UUID,
@@ -165,7 +178,7 @@ create(#{} = Db0, Options) ->
after_doc_read => undefined,
% All other db things as we add features,
- db_options => Options
+ db_options => Options1
}.
@@ -186,6 +199,7 @@ open(#{} = Db0, Options) ->
DbVersion = erlfdb:wait(erlfdb:get(Tx, DbVersionKey)),
UserCtx = fabric2_util:get_value(user_ctx, Options, #user_ctx{}),
+ Options1 = lists:keydelete(user_ctx, 1, Options),
Db2 = Db1#{
db_prefix => DbPrefix,
@@ -201,7 +215,7 @@ open(#{} = Db0, Options) ->
before_doc_update => undefined,
after_doc_read => undefined,
- db_options => Options
+ db_options => Options1
},
Db3 = lists:foldl(fun({Key, Val}, DbAcc) ->
@@ -223,9 +237,11 @@ reopen(#{} = OldDb) ->
#{
tx := Tx,
name := DbName,
- db_options := Options
+ db_options := Options,
+ user_ctx := UserCtx
} = OldDb,
- open(init_db(Tx, DbName, Options), Options).
+ Options1 = lists:keystore(user_ctx, 1, Options, {user_ctx, UserCtx}),
+ open(init_db(Tx, DbName, Options1), Options1).
delete(#{} = Db) ->
@@ -1132,7 +1148,7 @@ ensure_current(#{} = Db, CheckDbVersion) ->
case erlfdb:wait(erlfdb:get(Tx, ?METADATA_VERSION_KEY)) of
MetaDataVersion -> Db;
- _NewVersion -> reopen(Db)
+ _NewVersion -> throw({?MODULE, reopen})
end,
AlreadyChecked = get(?PDICT_CHECKED_DB_IS_CURRENT),
@@ -1150,7 +1166,7 @@ ensure_current(#{} = Db, CheckDbVersion) ->
Db;
_NewDBVersion ->
fabric2_server:remove(maps:get(name, Db)),
- reopen(Db)
+ throw({?MODULE, reopen})
end
end.