updating documentation for the consumer mechanism
This commit is contained in:
		
							parent
							
								
									077275abf5
								
							
						
					
					
						commit
						964543d122
					
				|  | @ -14,6 +14,7 @@ | |||
| %% Copyright (c) 2007-2011 VMware, Inc.  All rights reserved. | ||||
| %% | ||||
| 
 | ||||
| %% @private | ||||
| -module(amqp_auth_mechanisms). | ||||
| 
 | ||||
| -include("amqp_client.hrl"). | ||||
|  |  | |||
|  | @ -184,7 +184,13 @@ register_confirm_handler(Channel, ConfirmHandler) -> | |||
| register_flow_handler(Channel, FlowHandler) -> | ||||
|     gen_server:cast(Channel, {register_flow_handler, FlowHandler} ). | ||||
| 
 | ||||
| %% TODO doc | ||||
| %% @spec (Channel, Message) -> ok | ||||
| %% where | ||||
| %%      Channel = pid() | ||||
| %%      Message = any() | ||||
| %% @doc This causes the channel to invoke Consumer:handle_message/2, | ||||
| %% where Consumer is the amqp_gen_consumer implementation registered with | ||||
| %% the channel. | ||||
| send_to_consumer(Channel, Message) -> | ||||
|     gen_server:cast(Channel, {send_to_consumer, Message}). | ||||
| 
 | ||||
|  |  | |||
|  | @ -105,29 +105,43 @@ start(Type, AmqpParams) -> | |||
| %% Commands | ||||
| %%--------------------------------------------------------------------------- | ||||
| 
 | ||||
| %% @doc Invokes open_channel(ConnectionPid, none).  | ||||
| %% Opens a channel without having to specify a channel number. | ||||
| %% @doc Invokes open_channel(ConnectionPid, none, ?DEFAULT_CONSUMER). | ||||
| %% Opens a channel without having to specify a channel number. This uses the | ||||
| %% default consumer implementation. | ||||
| open_channel(ConnectionPid) -> | ||||
|     open_channel(ConnectionPid, none, ?DEFAULT_CONSUMER). | ||||
| 
 | ||||
| open_channel(ConnectionPid, {_ConsumerModule, _ConsumerArgs} = Consumer) -> | ||||
| %% @doc Invokes open_channel(ConnectionPid, none, Consumer). | ||||
| %% Opens a channel without having to specify a channel number. | ||||
| open_channel(ConnectionPid, {_, _} = Consumer) -> | ||||
|     open_channel(ConnectionPid, none, Consumer); | ||||
| 
 | ||||
| %% @spec (ConnectionPid, ChannelNumber) -> {ok, ChannelPid} | {error, Error} | ||||
| %% @doc Invokes open_channel(ConnectionPid, ChannelNumber, ?DEFAULT_CONSUMER). | ||||
| %% Opens a channel, using the default consumer implementation. | ||||
| open_channel(ConnectionPid, ChannelNumber) | ||||
|         when is_number(ChannelNumber) orelse ChannelNumber =:= none -> | ||||
|     open_channel(ConnectionPid, ChannelNumber, ?DEFAULT_CONSUMER). | ||||
| 
 | ||||
| %% @spec (ConnectionPid, ChannelNumber, Consumer) -> Result | ||||
| %% where | ||||
| %%      ChannelNumber = pos_integer() | 'none' | ||||
| %%      ConnectionPid = pid() | ||||
| %%      ChannelNumber = pos_integer() | 'none' | ||||
| %%      Consumer = {ConsumerModule, ConsumerArgs} | ||||
| %%      ConsumerModule = atom() | ||||
| %%      ConsumerArgs = [any()] | ||||
| %%      Result = {ok, ChannelPid} | {error, Error} | ||||
| %%      ChannelPid = pid() | ||||
| %% @doc Opens an AMQP channel.<br/> | ||||
| %% Opens a channel, using a proposed channel number and a specific consumer | ||||
| %% implementation.<br/> | ||||
| %% ConsumerModule must implement the amqp_gen_consumer behaviour. ConsumerArgs | ||||
| %% is passed as parameter to ConsumerModule:init/1.<br/> | ||||
| %% This function assumes that an AMQP connection (networked or direct) | ||||
| %% has already been successfully established.<br/> | ||||
| %% ChannelNumber must be less than or equal to the negotiated max_channel value, | ||||
| %% or less than or equal to ?MAX_CHANNEL_NUMBER if the negotiated max_channel | ||||
| %% value is 0.<br/> | ||||
| %% In the direct connection, max_channel is always 0. | ||||
| open_channel(ConnectionPid, ChannelNumber) -> | ||||
|     open_channel(ConnectionPid, ChannelNumber, ?DEFAULT_CONSUMER). | ||||
| 
 | ||||
| open_channel(ConnectionPid, ChannelNumber, | ||||
|              {_ConsumerModule, _ConsumerArgs} = Consumer) -> | ||||
|     amqp_gen_connection:open_channel(ConnectionPid, ChannelNumber, Consumer). | ||||
|  |  | |||
|  | @ -14,7 +14,19 @@ | |||
| %% Copyright (c) 2007-2011 VMware, Inc.  All rights reserved. | ||||
| %% | ||||
| 
 | ||||
| %% @doc TODO | ||||
| %% @doc This module is an implementation of the amqp_gen_consumer behaviour and | ||||
| %% can be used as part of the Consumer parameter when opening AMQP | ||||
| %% channels.<br/> | ||||
| %% The Consumer parameter for this implementation is | ||||
| %% {{@module}, [ConsumerPid]@}, where ConsumerPid is a process that | ||||
| %% will receive queue subscription-related messages.<br/> | ||||
| %% This consumer implementation causes the channel to send to the ConsumerPid | ||||
| %% all basic.consume_ok, basic.cancel_ok, basic.cancel and basic.deliver | ||||
| %% messages received from the server.<br/> | ||||
| %% In addition, if the channel exits abnormally, an exit signal with the | ||||
| %% channel's exit reason is sent to ConsumerPid.<br/> | ||||
| %% <br/> | ||||
| %% This module has no public functions. | ||||
| -module(amqp_direct_consumer). | ||||
| 
 | ||||
| -behaviour(amqp_gen_consumer). | ||||
|  |  | |||
|  | @ -14,7 +14,10 @@ | |||
| %% Copyright (c) 2007-2011 VMware, Inc.  All rights reserved. | ||||
| %% | ||||
| 
 | ||||
| %% @doc TODO | ||||
| %% @doc A behaviour module for implementing consumers for amqp_channel. To | ||||
| %% specify a consumer implementation for a channel, use | ||||
| %% amqp_connection:open_channel/{2,3}.<br/> | ||||
| %% All callbacks are called withing the channel process. | ||||
| -module(amqp_gen_consumer). | ||||
| 
 | ||||
| -export([behaviour_info/1]). | ||||
|  | @ -23,40 +26,69 @@ | |||
| %% Behaviour | ||||
| %%--------------------------------------------------------------------------- | ||||
| 
 | ||||
| %% TODO: doc | ||||
| 
 | ||||
| %% all callbacks run in the channel process | ||||
| 
 | ||||
| %% init: called when channel is started. | ||||
| %% handle_consume_ok: called on each basic.consume_ok | ||||
| %% handle_cancel_ok: called on each basic.cancel_ok (sent by the server) | ||||
| %% handle_cancel: called on each basic.cancel (sent by the server) | ||||
| %% handle_deliver: called on each basic.deliver | ||||
| %% handle_message: called on amqp_channel:send_to_consumer/2 | ||||
| %% terminate: called after channel has shut down | ||||
| 
 | ||||
| %% @private | ||||
| behaviour_info(callbacks) -> | ||||
|     [ | ||||
|      %% init(Args) -> {ok, InitialState} | ||||
|      %% @spec Module:init(Args) -> {ok, InitialState} | ||||
|      %% where | ||||
|      %%      Args = [any()] | ||||
|      %%      InitialState = any() | ||||
|      %% @doc This function is called by the channel, when it starts up. | ||||
|      {init, 1}, | ||||
| 
 | ||||
|      %% handle_consume(#'basic.consume_ok'{}, State) -> {ok, NewState} | ||||
|      %% @type consume_ok() = #'basic.consume_ok'{}. | ||||
|      %% The AMQP method returned in response to basic.consume. | ||||
|      %% @spec Module:handle_consume(consume_ok(), State) -> {ok, NewState} | ||||
|      %% where | ||||
|      %%      State = NewState = any() | ||||
|      %% @doc This function is called by the channel every time a | ||||
|      %% basic.consume_ok is received from the server. | ||||
|      {handle_consume_ok, 2}, | ||||
| 
 | ||||
|      %% handle_cancel_ok(#'basic.cancel_ok'{}, State) -> {ok, NewState} | ||||
|      %% @type cancel_ok() = #'basic.cancel_ok'{}. | ||||
|      %% The AMQP method returned as reply to basicl.cancel. | ||||
|      %% @spec Module:handle_cancel_ok(cancel_ok(), State) -> {ok, NewState} | ||||
|      %% where | ||||
|      %%      State = NewState = any() | ||||
|      %% @doc This function is called by the channel every time a basic.cancel_ok | ||||
|      %% is received from the server. | ||||
|      {handle_cancel_ok, 2}, | ||||
| 
 | ||||
|      %% handle_cancel(#'basic.cancel'{}, State) -> {ok, NewState} | ||||
|      %% @type cancel() = #'basic.cancel'{}. | ||||
|      %% The AMQP method used to cancel a subscription. | ||||
|      %% @spec Module:handle_cancel(cancel(), State) -> {ok, NewState} | ||||
|      %% where | ||||
|      %%      State = NewState = any() | ||||
|      %% @doc This function is called by the channel every time a basic.cancel | ||||
|      %% is received from the server. | ||||
|      {handle_cancel, 2}, | ||||
| 
 | ||||
|      %% handle_deliver(#'basic.deliver', #amqp_msg{}, State} -> {ok, NewState} | ||||
|      %% @type deliver() = #'basic.deliver'{}. | ||||
|      %% The AMQP method sent when a message is delivered from a subscribed | ||||
|      %% queue. | ||||
|      %% @spec Module:handle_deliver(deliver(), #amqp_msg{}, State} -> | ||||
|      %%           {ok, NewState} | ||||
|      %% where | ||||
|      %%      State = NewState = any() | ||||
|      %% @doc This function is called by the channel every time a basic.deliver | ||||
|      %% is received from the server. | ||||
|      {handle_deliver, 3}, | ||||
| 
 | ||||
|      %% handle_message(Message, State) -> {ok, NewState} | ||||
|      %% @spec Module:handle_message(Message, State) -> {ok, NewState} | ||||
|      %% where | ||||
|      %%      State = NewState = any() | ||||
|      %% @doc This function is called by the channel when calling | ||||
|      %% amqp_channel:send_to_consumer/2. | ||||
|      {handle_message, 2}, | ||||
| 
 | ||||
|      %% terminate(Reason, State) -> _ | ||||
|      %% @spec Module:terminate(Reason, State) -> _ | ||||
|      %% where | ||||
|      %%      State = any() | ||||
|      %%      Reason = any() | ||||
|      %% @doc This function is called by the channel after it has shut down and | ||||
|      %% just before its process exits. | ||||
|      {terminate, 2} | ||||
|     ]; | ||||
| behaviour_info(_Other) -> | ||||
|  |  | |||
|  | @ -14,7 +14,27 @@ | |||
| %% Copyright (c) 2007-2011 VMware, Inc.  All rights reserved. | ||||
| %% | ||||
| 
 | ||||
| %% @doc TODO | ||||
| %% @doc This module is an implementation of the amqp_gen_consumer behaviour and | ||||
| %% can be used as part of the Consumer parameter when opening AMQP | ||||
| %% channels.<br/> | ||||
| %% The Consumer parameter for this implementation is {{@module}, []@}<br/> | ||||
| %% This consumer implementation keeps track of consumer tags and sends | ||||
| %% the subscription-relevant messages to the registered consumers, according | ||||
| %% to an internal tag dictionary.<br/> | ||||
| %% Use {@module}:subscribe/3 to subscribe a consumer to a queue and | ||||
| %% {@module}:cancel/2 to cancel a subscription.<br/> | ||||
| %% The channel will send to the relevant registered consumers the | ||||
| %% basic.consume_ok, basic.cancel_ok, basic.cancel and basic.deliver messages | ||||
| %% received from the server.<br/> | ||||
| %% If a consumer is not registered for a given consumer tag, the message | ||||
| %% is sent to the default consumer registered with | ||||
| %% {@module}:register_default_consumer. If there is no default consumer | ||||
| %% registered in this case, an exception occurs and the channel is abrubptly | ||||
| %% terminated.<br/> | ||||
| %% amqp_channel:call(ChannelPid, #'basic.consume'{}) can also be used to | ||||
| %% subscribe to a queue, but one must register a default consumer for messages | ||||
| %% to be delivered to, beforehand. Failing to do so generates the | ||||
| %% above-mentioned exception. | ||||
| -module(amqp_selective_consumer). | ||||
| 
 | ||||
| -include("amqp_client.hrl"). | ||||
|  | @ -33,7 +53,28 @@ | |||
| %% Interface | ||||
| %%--------------------------------------------------------------------------- | ||||
| 
 | ||||
| %% TODO doc | ||||
| %% @type consume() = #'basic.consume'{}. | ||||
| %% The AMQP method that is used to  subscribe a consumer to a queue. | ||||
| %% @type consume_ok() = #'basic.consume_ok'{}. | ||||
| %% The AMQP method returned in response to basic.consume. | ||||
| %% @spec (ChannelPid, consume(), ConsumerPid) -> Result | ||||
| %% where | ||||
| %%      ChannelPid = pid() | ||||
| %%      ConsumerPid = pid() | ||||
| %%      Result = consume_ok() | ok | {error, command_invalid} | ||||
| %% @doc Creates a subscription to a queue. This subscribes a consumer pid to | ||||
| %% the queue defined in the #'basic.consume'{} method record. Note that | ||||
| %% both the process invoking this method and the supplied consumer process | ||||
| %% receive an acknowledgement of the subscription. The calling process will | ||||
| %% receive the acknowledgement as the return value of this function, whereas | ||||
| %% the consumer process will receive the notification as a message, | ||||
| %% asynchronously.<br/> | ||||
| %% This function returns {error, command_invalid} if consumer_tag is not | ||||
| %% specified and nowait is true.<br/> | ||||
| %% Attempting to subscribe with a consumer_tag that is already in use will | ||||
| %% cause an exception and the channel will terminate. If nowait is set to true | ||||
| %% in this case, the function will return ok, but the channel will terminate | ||||
| %% with an error. | ||||
| subscribe(ChannelPid, #'basic.consume'{nowait = false} = BasicConsume, | ||||
|           ConsumerPid) -> | ||||
|     ConsumeOk = #'basic.consume_ok'{consumer_tag = RetTag} = | ||||
|  | @ -49,12 +90,44 @@ subscribe(ChannelPid, #'basic.consume'{nowait = true, | |||
|     ok = call_consumer(ChannelPid, {subscribe_nowait, Tag, ConsumerPid}), | ||||
|     amqp_channel:call(ChannelPid, BasicConsume). | ||||
| 
 | ||||
| %% TODO doc | ||||
| %% (provided for completeness) | ||||
| %% @type cancel() = #'basic.cancel'{}. | ||||
| %% The AMQP method used to cancel a subscription. | ||||
| 
 | ||||
| %% @spec (ChannelPid, Cancel) -> amqp_method() | ok | ||||
| %% where | ||||
| %%      ChannelPid = pid() | ||||
| %%      Cancel = cancel() | ||||
| %% @doc This function is the same as calling | ||||
| %% amqp_channel:call(ChannelPid, Cancel) and is only provided for completeness. | ||||
| cancel(ChannelPid, #'basic.cancel'{} = Cancel) -> | ||||
|     amqp_channel:call(ChannelPid, Cancel). | ||||
| 
 | ||||
| %% TODO doc | ||||
| %% @spec (ChannelPid, ConsumerPid) -> ok | ||||
| %% where | ||||
| %%      ChannelPid = pid() | ||||
| %%      ConsumerPid = pid() | ||||
| %% @doc This function registers a default consumer with the channel. A default | ||||
| %% consumer is used in two situations:<br/> | ||||
| %% <br/> | ||||
| %% 1) A subscription was made via | ||||
| %% amqp_channel:call(ChannelPid, #'basic.consume'{}) (rather than | ||||
| %% {@module}:subscribe/3) and hence there is no consumer pid registered with the | ||||
| %% consumer tag.<br/> | ||||
| %% <br/> | ||||
| %% 2) The following sequence of events occurs:<br/> | ||||
| %% <br/> | ||||
| %% - subscribe is used with basic.consume with explicit acks<br/> | ||||
| %% - some deliveries take place but are not acked<br/> | ||||
| %% - a basic.cancel is issued<br/> | ||||
| %% - a basic.recover{requeue = false} is issued<br/> | ||||
| %% <br/> | ||||
| %% Since requeue is specified to be false in the basic.recover, the spec | ||||
| %% states that the message must be redelivered to "the original recipient" | ||||
| %% - i.e. the same channel / consumer-tag. But the consumer is no longer | ||||
| %% active. <br/> | ||||
| %% <br/> | ||||
| %% In these two cases, the relevant deliveries will be sent to the default | ||||
| %% consumer. | ||||
| register_default_consumer(ChannelPid, ConsumerPid) -> | ||||
|     call_consumer(ChannelPid, {register_default_consumer, ConsumerPid}). | ||||
| 
 | ||||
|  | @ -76,6 +149,7 @@ handle_consume_ok(#'basic.consume_ok'{consumer_tag = Tag} = ConsumeOk, | |||
| handle_cancel_ok(#'basic.cancel_ok'{consumer_tag = Tag} = CancelOk, State) -> | ||||
|     deliver_or_queue(Tag, CancelOk, State). | ||||
| 
 | ||||
| %% @private | ||||
| handle_cancel(#'basic.cancel'{consumer_tag = Tag} = Cancel, State) -> | ||||
|     deliver_or_queue(Tag, Cancel, State). | ||||
| 
 | ||||
|  |  | |||
|  | @ -103,7 +103,7 @@ pub_and_close_test_() -> | |||
|         end}. | ||||
| 
 | ||||
| channel_tune_negotiation_test() -> | ||||
|     amqp_connection:close(new_connection(#amqp_params{ channel_max = 10 })). | ||||
|     amqp_connection:close(new_connection(#amqp_params{channel_max = 10})). | ||||
| 
 | ||||
| confirm_test() -> | ||||
|     test_util:confirm_test(new_connection()). | ||||
|  | @ -177,4 +177,3 @@ test_coverage() -> | |||
|     rabbit_misc:enable_cover(), | ||||
|     test(), | ||||
|     rabbit_misc:report_cover(). | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue