Packages

rabbit_common

3.6.15-rc.1
4.2.1 4.2.0 retired 4.2.0-rc.1 retired 4.1.6 4.1.5 retired 4.1.5-rc.2 retired 4.1.5-rc.1 4.0.3 4.0.3-rc.1 4.0.2 4.0.2-rc.2 4.0.2-rc.1 4.0.1 4.0.0 4.0.0-rc.2 4.0.0-rc.1 3.13.7 3.13.6 3.13.5 3.13.4 3.13.3 3.13.2 3.13.2-rc.1 3.13.1 3.13.0 3.13.0-rc.6 3.13.0-rc.5 3.13.0-rc.4 3.13.0-rc.3 3.13.0-rc.2 3.13.0-rc.1 3.12.14 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.2 3.12.1 3.12.0 3.12.0-rc.4 3.12.0-rc.3 3.12.0-rc.2 3.12.0-rc.1 3.11.28 3.11.27 3.11.26 3.11.25 3.11.24 3.11.23 3.11.22 3.11.21 3.11.20 3.11.19 3.11.18 3.11.17 3.11.16 3.11.15 3.11.14 3.11.13 3.11.12 3.11.11 3.11.10 3.11.9 3.11.8 3.11.7 3.11.6 3.11.5 3.11.4 3.11.3 3.11.2 3.11.1 3.11.0 3.11.0-rc.2 3.11.0-rc.1 3.11.0-1 3.10.25 3.10.24 3.10.23 3.10.22 3.10.21 3.10.20 3.10.19 3.10.18 3.10.17 3.10.16 3.10.15 3.10.14 3.10.13 3.10.12 3.10.11 3.10.10 3.10.9 3.10.8 3.10.7 3.10.6 3.10.5 3.10.4 3.10.3 3.10.2 3.10.1 3.10.0 3.10.0-rc.6 3.10.0-rc.5 3.9.29 3.9.28 3.9.27 3.9.26 3.9.25 3.9.24 3.9.23 3.9.22 3.9.21 3.9.20 3.9.19 3.9.18 3.9.17 3.9.16 3.9.15 3.9.11 3.9.10 3.9.9 3.9.8 3.9.7 3.9.6 3.9.5 3.9.4 3.9.3 3.9.2 3.9.1 3.8.35 3.8.34 3.8.33 3.8.32 3.8.31 3.8.30 3.8.26 3.8.25 3.8.24 3.8.23 3.8.22 3.8.21 3.8.20 3.8.19 3.8.14 3.8.12-rc.3 3.8.12-rc.2 3.8.12-rc.1 3.8.11 3.8.10 3.8.10-rc.6 3.8.10-rc.5 3.8.10-rc.1 3.8.9 3.8.8 3.8.7 3.8.6 3.8.6-rc.2 3.8.6-rc.1 3.8.5 3.8.5-rc.2 3.8.5-rc.1 3.8.4 3.8.4-rc.3 3.8.4-rc.1 3.8.3 3.8.3-rc.2 3.8.3-rc.1 3.8.2 3.8.2-rc.1 3.8.1 3.8.1-rc.1 3.8.0 3.8.0-rc.3 3.8.0-rc.2 3.8.0-rc.1 3.7.28 3.7.27 3.7.27-rc.2 3.7.27-rc.1 3.7.26 3.7.25 3.7.25-rc.1 3.7.24 3.7.24-rc.2 3.7.24-rc.1 3.7.23 3.7.23-rc.1 3.7.22 3.7.22-rc.2 3.7.22-rc.1 3.7.21 3.7.20 3.7.20-rc.2 3.7.20-rc.1 3.7.19 3.7.18 3.7.18-rc.1 3.7.17 3.7.17-rc.3 3.7.17-rc.2 3.7.17-rc.1 retired 3.7.16 retired 3.7.16-rc.4 retired 3.7.16-rc.3 retired 3.7.16-rc.2 retired 3.7.16-rc.1 retired 3.7.16-beta.1 3.7.15 3.7.14 3.7.14-rc.2 3.7.14-rc.1 3.7.13 3.7.13-rc.2 3.7.13-rc.1 3.7.12 3.7.12-rc.2 3.7.12-rc.1 3.7.11 3.7.11-rc.2 3.7.11-rc.1 3.7.10-rc.4 3.7.10-rc.3 3.7.10-rc.2 3.7.10-rc.1 3.7.9 3.7.9-rc.3 3.7.9-rc.2 3.7.8 3.7.8-rc.4 3.7.8-rc.3 3.7.8-rc.2 3.7.8-rc.1 3.7.7 3.7.7-rc.2 3.7.7-rc.1 3.7.6 3.7.6-rc.2 3.7.6-rc.1 3.7.5 3.7.5-rc.1 3.7.4 3.7.4-rc.4 3.7.4-rc.3 3.7.4-rc.2 3.7.4-rc.1 3.7.3 3.7.3-rc.2 3.7.3-rc.1 3.7.2 3.7.1 3.7.0-rc.2 3.7.0-alpha.544 3.7.0-alpha.542 3.6.16 3.6.16-rc.1 3.6.15 3.6.15-rc.1 3.6.14 3.6.13 3.6.12 3.6.11 3.6.10 3.6.9 3.6.8 3.6.7 3.6.7-pre.1 3.5.6 3.5.0 3.4.0 3.3.5 3.0.2 0.0.0-rc.1

Modules shared by rabbitmq-server and rabbitmq-erlang-client

Current section

Files

Jump to
rabbit_common src rabbit_backing_queue.erl
Raw

src/rabbit_backing_queue.erl

%% The contents of this file are subject to the Mozilla Public License
%% Version 1.1 (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.mozilla.org/MPL/
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and
%% limitations under the License.
%%
%% The Original Code is RabbitMQ.
%%
%% The Initial Developer of the Original Code is GoPivotal, Inc.
%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
%%
-module(rabbit_backing_queue).
-export([info_keys/0]).
-define(INFO_KEYS, [messages_ram, messages_ready_ram,
messages_unacknowledged_ram, messages_persistent,
message_bytes, message_bytes_ready,
message_bytes_unacknowledged, message_bytes_ram,
message_bytes_persistent, head_message_timestamp,
disk_reads, disk_writes, backing_queue_status,
messages_paged_out, message_bytes_paged_out]).
%% We can't specify a per-queue ack/state with callback signatures
-type ack() :: any().
-type state() :: any().
-type flow() :: 'flow' | 'noflow'.
-type msg_ids() :: [rabbit_types:msg_id()].
-type publish() :: {rabbit_types:basic_message(),
rabbit_types:message_properties(), boolean()}.
-type delivered_publish() :: {rabbit_types:basic_message(),
rabbit_types:message_properties()}.
-type fetch_result(Ack) ::
('empty' | {rabbit_types:basic_message(), boolean(), Ack}).
-type drop_result(Ack) ::
('empty' | {rabbit_types:msg_id(), Ack}).
-type recovery_terms() :: [term()] | 'non_clean_shutdown'.
-type recovery_info() :: 'new' | recovery_terms().
-type purged_msg_count() :: non_neg_integer().
-type async_callback() ::
fun ((atom(), fun ((atom(), state()) -> state())) -> 'ok').
-type duration() :: ('undefined' | 'infinity' | number()).
-type msg_fun(A) :: fun ((rabbit_types:basic_message(), ack(), A) -> A).
-type msg_pred() :: fun ((rabbit_types:message_properties()) -> boolean()).
-type queue_mode() :: atom().
-spec info_keys() -> rabbit_types:info_keys().
%% Called on startup with a list of durable queue names. The queues
%% aren't being started at this point, but this call allows the
%% backing queue to perform any checking necessary for the consistency
%% of those queues, or initialise any other shared resources.
%%
%% The list of queue recovery terms returned as {ok, Terms} must be given
%% in the same order as the list of queue names supplied.
-callback start([rabbit_amqqueue:name()]) -> rabbit_types:ok(recovery_terms()).
%% Called to tear down any state/resources. NB: Implementations should
%% not depend on this function being called on shutdown and instead
%% should hook into the rabbit supervision hierarchy.
-callback stop() -> 'ok'.
%% Initialise the backing queue and its state.
%%
%% Takes
%% 1. the amqqueue record
%% 2. a term indicating whether the queue is an existing queue that
%% should be recovered or not. When 'new' is given, no recovery is
%% taking place, otherwise a list of recovery terms is given, or
%% the atom 'non_clean_shutdown' if no recovery terms are available.
%% 3. an asynchronous callback which accepts a function of type
%% backing-queue-state to backing-queue-state. This callback
%% function can be safely invoked from any process, which makes it
%% useful for passing messages back into the backing queue,
%% especially as the backing queue does not have control of its own
%% mailbox.
-callback init(rabbit_types:amqqueue(), recovery_info(),
async_callback()) -> state().
%% Called on queue shutdown when queue isn't being deleted.
-callback terminate(any(), state()) -> state().
%% Called when the queue is terminating and needs to delete all its
%% content.
-callback delete_and_terminate(any(), state()) -> state().
%% Called to clean up after a crashed queue. In this case we don't
%% have a process and thus a state(), we are just removing on-disk data.
-callback delete_crashed(rabbit_types:amqqueue()) -> 'ok'.
%% Remove all 'fetchable' messages from the queue, i.e. all messages
%% except those that have been fetched already and are pending acks.
-callback purge(state()) -> {purged_msg_count(), state()}.
%% Remove all messages in the queue which have been fetched and are
%% pending acks.
-callback purge_acks(state()) -> state().
%% Publish a message.
-callback publish(rabbit_types:basic_message(),
rabbit_types:message_properties(), boolean(), pid(), flow(),
state()) -> state().
%% Like publish/6 but for batches of publishes.
-callback batch_publish([publish()], pid(), flow(), state()) -> state().
%% Called for messages which have already been passed straight
%% out to a client. The queue will be empty for these calls
%% (i.e. saves the round trip through the backing queue).
-callback publish_delivered(rabbit_types:basic_message(),
rabbit_types:message_properties(), pid(), flow(),
state())
-> {ack(), state()}.
%% Like publish_delivered/5 but for batches of publishes.
-callback batch_publish_delivered([delivered_publish()], pid(), flow(),
state())
-> {[ack()], state()}.
%% Called to inform the BQ about messages which have reached the
%% queue, but are not going to be further passed to BQ.
-callback discard(rabbit_types:msg_id(), pid(), flow(), state()) -> state().
%% Return ids of messages which have been confirmed since the last
%% invocation of this function (or initialisation).
%%
%% Message ids should only appear in the result of drain_confirmed
%% under the following circumstances:
%%
%% 1. The message appears in a call to publish_delivered/4 and the
%% first argument (ack_required) is false; or
%% 2. The message is fetched from the queue with fetch/2 and the first
%% argument (ack_required) is false; or
%% 3. The message is acked (ack/2 is called for the message); or
%% 4. The message is fully fsync'd to disk in such a way that the
%% recovery of the message is guaranteed in the event of a crash of
%% this rabbit node (excluding hardware failure).
%%
%% In addition to the above conditions, a message id may only appear
%% in the result of drain_confirmed if
%% #message_properties.needs_confirming = true when the msg was
%% published (through whichever means) to the backing queue.
%%
%% It is legal for the same message id to appear in the results of
%% multiple calls to drain_confirmed, which means that the backing
%% queue is not required to keep track of which messages it has
%% already confirmed. The confirm will be issued to the publisher the
%% first time the message id appears in the result of
%% drain_confirmed. All subsequent appearances of that message id will
%% be ignored.
-callback drain_confirmed(state()) -> {msg_ids(), state()}.
%% Drop messages from the head of the queue while the supplied
%% predicate on message properties returns true. Returns the first
%% message properties for which the predictate returned false, or
%% 'undefined' if the whole backing queue was traversed w/o the
%% predicate ever returning false.
-callback dropwhile(msg_pred(), state())
-> {rabbit_types:message_properties() | undefined, state()}.
%% Like dropwhile, except messages are fetched in "require
%% acknowledgement" mode and are passed, together with their ack tag,
%% to the supplied function. The function is also fed an
%% accumulator. The result of fetchwhile is as for dropwhile plus the
%% accumulator.
-callback fetchwhile(msg_pred(), msg_fun(A), A, state())
-> {rabbit_types:message_properties() | undefined,
A, state()}.
%% Produce the next message.
-callback fetch(true, state()) -> {fetch_result(ack()), state()};
(false, state()) -> {fetch_result(undefined), state()}.
%% Remove the next message.
-callback drop(true, state()) -> {drop_result(ack()), state()};
(false, state()) -> {drop_result(undefined), state()}.
%% Acktags supplied are for messages which can now be forgotten
%% about. Must return 1 msg_id per Ack, in the same order as Acks.
-callback ack([ack()], state()) -> {msg_ids(), state()}.
%% Reinsert messages into the queue which have already been delivered
%% and were pending acknowledgement.
-callback requeue([ack()], state()) -> {msg_ids(), state()}.
%% Fold over messages by ack tag. The supplied function is called with
%% each message, its ack tag, and an accumulator.
-callback ackfold(msg_fun(A), A, state(), [ack()]) -> {A, state()}.
%% Fold over all the messages in a queue and return the accumulated
%% results, leaving the queue undisturbed.
-callback fold(fun((rabbit_types:basic_message(),
rabbit_types:message_properties(),
boolean(), A) -> {('stop' | 'cont'), A}),
A, state()) -> {A, state()}.
%% How long is my queue?
-callback len(state()) -> non_neg_integer().
%% Is my queue empty?
-callback is_empty(state()) -> boolean().
%% What's the queue depth, where depth = length + number of pending acks
-callback depth(state()) -> non_neg_integer().
%% For the next three functions, the assumption is that you're
%% monitoring something like the ingress and egress rates of the
%% queue. The RAM duration is thus the length of time represented by
%% the messages held in RAM given the current rates. If you want to
%% ignore all of this stuff, then do so, and return 0 in
%% ram_duration/1.
%% The target is to have no more messages in RAM than indicated by the
%% duration and the current queue rates.
-callback set_ram_duration_target(duration(), state()) -> state().
%% Optionally recalculate the duration internally (likely to be just
%% update your internal rates), and report how many seconds the
%% messages in RAM represent given the current rates of the queue.
-callback ram_duration(state()) -> {duration(), state()}.
%% Should 'timeout' be called as soon as the queue process can manage
%% (either on an empty mailbox, or when a timer fires)?
-callback needs_timeout(state()) -> 'false' | 'timed' | 'idle'.
%% Called (eventually) after needs_timeout returns 'idle' or 'timed'.
%% Note this may be called more than once for each 'idle' or 'timed'
%% returned from needs_timeout
-callback timeout(state()) -> state().
%% Called immediately before the queue hibernates.
-callback handle_pre_hibernate(state()) -> state().
%% Called when more credit has become available for credit_flow.
-callback resume(state()) -> state().
%% Used to help prioritisation in rabbit_amqqueue_process. The rate of
%% inbound messages and outbound messages at the moment.
-callback msg_rates(state()) -> {float(), float()}.
-callback info(atom(), state()) -> any().
%% Passed a function to be invoked with the relevant backing queue's
%% state. Useful for when the backing queue or other components need
%% to pass functions into the backing queue.
-callback invoke(atom(), fun ((atom(), A) -> A), state()) -> state().
%% Called prior to a publish or publish_delivered call. Allows the BQ
%% to signal that it's already seen this message, (e.g. it was published
%% or discarded previously) and thus the message should be dropped.
-callback is_duplicate(rabbit_types:basic_message(), state())
-> {boolean(), state()}.
-callback set_queue_mode(queue_mode(), state()) -> state().
-callback zip_msgs_and_acks(delivered_publish(),
[ack()], Acc, state())
-> Acc.
info_keys() -> ?INFO_KEYS.