summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2013-06-18 15:59:27 +0100
committerSimon MacMullen <simon@rabbitmq.com>2013-06-18 15:59:27 +0100
commit2a1a5da1bc937b537f356c5b67866679a84d2652 (patch)
tree12324019f8305bc68e74daaed599528d01242142
parent484f2158f0c17c4833951e1c7d693a347a1891eb (diff)
parentb106047a4df6a5d230097a4ada549be69fade0c7 (diff)
downloadrabbitmq-server-2a1a5da1bc937b537f356c5b67866679a84d2652.tar.gz
Merge bug25612
-rw-r--r--src/rabbit_msg_store.erl17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/rabbit_msg_store.erl b/src/rabbit_msg_store.erl
index c63321b5..b783aa18 100644
--- a/src/rabbit_msg_store.erl
+++ b/src/rabbit_msg_store.erl
@@ -627,7 +627,10 @@ client_update_flying(Diff, MsgId, #client_msstate { flying_ets = FlyingEts,
Key = {MsgId, CRef},
case ets:insert_new(FlyingEts, {Key, Diff}) of
true -> ok;
- false -> try ets:update_counter(FlyingEts, Key, {2, Diff})
+ false -> try ets:update_counter(FlyingEts, Key, {2, Diff}) of
+ 0 -> ok;
+ Diff -> ok;
+ Err -> throw({bad_flying_ets_update, Diff, Err, Key})
catch error:badarg ->
%% this is guaranteed to succeed since the
%% server only removes and updates flying_ets
@@ -975,13 +978,21 @@ update_flying(Diff, MsgId, CRef, #msstate { flying_ets = FlyingEts }) ->
NDiff = -Diff,
case ets:lookup(FlyingEts, Key) of
[] -> ignore;
- [{_, Diff}] -> ignore;
+ [{_, Diff}] -> ignore; %% [1]
[{_, NDiff}] -> ets:update_counter(FlyingEts, Key, {2, Diff}),
true = ets:delete_object(FlyingEts, {Key, 0}),
process;
[{_, 0}] -> true = ets:delete_object(FlyingEts, {Key, 0}),
- ignore
+ ignore;
+ [{_, Err}] -> throw({bad_flying_ets_record, Diff, Err, Key})
end.
+%% [1] We can get here, for example, in the following scenario: There
+%% is a write followed by a remove in flight. The counter will be 0,
+%% so on processing the write the server attempts to delete the
+%% entry. If at that point the client injects another write it will
+%% either insert a new entry, containing +1, or increment the existing
+%% entry to +1, thus preventing its removal. Either way therefore when
+%% the server processes the read, the counter will be +1.
write_action({true, not_found}, _MsgId, State) ->
{ignore, undefined, State};