summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <jean-sebastien@rabbitmq.com>2015-08-06 15:57:08 +0200
committerJean-Sébastien Pédron <jean-sebastien@rabbitmq.com>2015-08-06 16:08:49 +0200
commit41b40e3d080e2b1f4ef5cba9426c71e1b59d4e52 (patch)
tree6c4b6248c861857b45e0095aac9649967377c85e
parent06ce1d512c96ee0b2be6c387123570f03798e133 (diff)
downloadrabbitmq-server-git-41b40e3d080e2b1f4ef5cba9426c71e1b59d4e52.tar.gz
Priority queue: Fix a crash when querying 'head_message_timestamp'
Before the fix, the code would consider it an integer which could be summed. It crashed if the head message had no timestamp at all (the underlying queue returned ''). Now, we have a special case, exactly like 'backing_queue_status'. The code first finds a priority with queued messages, then it queries the underlying queue for the 'head_message_timestamp'. Fixes #245.
-rw-r--r--src/rabbit_priority_queue.erl16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/rabbit_priority_queue.erl b/src/rabbit_priority_queue.erl
index 206d674abc..a839badfc4 100644
--- a/src/rabbit_priority_queue.erl
+++ b/src/rabbit_priority_queue.erl
@@ -376,6 +376,8 @@ info(backing_queue_status, #state{bq = BQ, bqss = BQSs}) ->
fold0(fun (P, BQSN, Acc) ->
combine_status(P, BQ:info(backing_queue_status, BQSN), Acc)
end, nothing, BQSs);
+info(head_message_timestamp, #state{bq = BQ, bqss = BQSs}) ->
+ find_head_message_timestamp(BQ, BQSs, '');
info(Item, #state{bq = BQ, bqss = BQSs}) ->
fold0(fun (_P, BQSN, Acc) ->
Acc + BQ:info(Item, BQSN)
@@ -582,3 +584,17 @@ cse(_, infinity) -> infinity;
cse(A, B) when is_number(A) -> A + B;
cse({delta, _, _, _}, _) -> {delta, todo, todo, todo};
cse(A, B) -> exit({A, B}).
+
+%% When asked about 'head_message_timestamp' fro this priority queue, we
+%% walk all the backing queues, starting by the highest priority. Once a
+%% backing queue having messages (ready or unacknowledged) is found, its
+%% 'head_message_timestamp' is returned even if it is null.
+
+find_head_message_timestamp(BQ, [{_, BQSN} | Rest], Timestamp) ->
+ MsgCount = BQ:len(BQSN) + BQ:info(messages_unacknowledged_ram, BQSN),
+ if
+ MsgCount =/= 0 -> BQ:info(head_message_timestamp, BQSN);
+ true -> find_head_message_timestamp(BQ, Rest, Timestamp)
+ end;
+find_head_message_timestamp(_, [], Timestamp) ->
+ Timestamp.