Basic.consume refers to the channel in a queue to register the consumer, that after the queue has a message, it will be forwarded to the channel processing, if the queue has multiple consumers, it will be rotated to distribute the message to the message.
The first is that the Rabbit_reader receives the packet and parses the Method,channel method into the channel processing. See Http://www.cnblogs.com/haoqingchuan/p/4354692.html for specific processes
The channel process processes the Basic.consume method. Check to see if the tag already exists in the state (with channel as a domain, different consumer_tag identify different consumers, consumer within each channel) Tag must be unique). Normal if not found, if the queue name is not named, a UUID is generated as the queue name.
1Handle_method (# ' basic.consume ' {queue =Queuenamebin,2Consumer_tag =Consumertag,3No_local = _,%fixme:implement4No_ack =Noack,5Exclusive =Exclusiveconsume,6NoWait =NoWait,7arguments =Args},8_, state = #ch {Consumer_prefetch =Consumerprefetch,9consumer_mapping = consumermapping})Ten CaseDict:find (Consumertag, consumermapping) of OneError- AQueueName =Qbin_to_resource (Queuenamebin, state), - check_read_permitted (QueueName, state), -Actualconsumertag = the CaseConsumertag of -<<>>rabbit_guid:binary (Rabbit_guid:gen_secure (), -"Amq.ctag"); -Other Other + End, - CaseBasic_consume ( + queuename, Noack, Consumerprefetch, Actualconsumertag, AExclusiveconsume, Args, NoWait, State) of at{OK, State1} - {noreply, State1}; -{Error, exclusive_consume_unavailable} - Rabbit_misc:protocol_error ( -access_refused, "~s in exclusive use", - [Rabbit_misc:rs (QueueName)]) in End; -{OK, _} to %%attempted reuse of consumer tag. + Rabbit_misc:protocol_error ( -not_allowed, "Attempt to reuse consumer tag ' ~s '", [Consumertag]) the End;
1 Basic_consume (QueueName, Noack, Consumerprefetch, Actualconsumertag,2 Exclusiveconsume, Args, NoWait,3State = #ch {conn_pid =Connpid,4Limiter =Limiter,5consumer_mapping = consumermapping})6 CaseRabbit_amqqueue:with_exclusive_access_or_die (7 queuename, Connpid,8 Fun(Q)9 {Rabbit_amqqueue:basic_consume (Ten Q, Noack, self (), One rabbit_limiter:pid (limiter), A rabbit_limiter:is_active (limiter), - Consumerprefetch, Actualconsumertag, - Exclusiveconsume, Args, theOk_msg (NoWait, # ' BASIC.CONSUME_OK '{ -Consumer_tag =Actualconsumertag})), - Q} - End) of +{OK, Q = #amqqueue {pid = qpid, name = QName}} -CM1 =Dict:store ( + Actualconsumertag, A {Q, {noack, Consumerprefetch, Exclusiveconsume, Args}}, at consumermapping), -State1 =Monitor_delivering_queue ( - Noack, Qpid, QName, -State#ch{consumer_mapping =CM1}), -{OK, CaseNoWait of - true-Consumer_monitor (Actualconsumertag, State1); in false-State1 - End}; to{{error, exclusive_consume_unavailable} = E, _q} + E - End.
Rabbit_amqqueue.erl
1 basic_consume (#amqqueue {pid = qpid, name = QName}, Noack, Chpid, Limiterpid,2 Limiteractive, Consumerprefetchcount, Consumertag,3 exclusiveconsume, Args, okmsg)-4 OK = check_consume_arguments (QName, Args),5 delegate:call (qpid, {Basic_ Consume, Noack, Chpid, Limiterpid, limiteractive,6 consumerprefetchcount, Consumertag, Exclusiveconsume,7 Args, okmsg}).
Rabbit_amqqueue_process
1 Handle_call ({basic_consume, Noack, Chpid, Limiterpid, Limiteractive,2 Prefetchcount, Consumertag, Exclusiveconsume, Args, okmsg},3_from, state = #q {consumers =consumers,4Exclusive_consumer = Holder})5 CaseCheck_exclusive_access (Holder, Exclusiveconsume, State) of6In_usereply ({error, exclusive_consume_unavailable}, state);7OK-Consumers1 =Rabbit_queue_consumers:add (8 chpid, Consumertag, Noack,9 limiterpid, Limiteractive,Ten Prefetchcount, Args, Is_empty (state), One consumers), AExclusiveconsumer = - ifExclusiveconsume{chpid, consumertag}; - true-Holder the End, -State1 = State#q{consumers =Consumers1, -Has_had_consumers =true, -Exclusive_consumer =Exclusiveconsumer}, +OK =maybe_send_reply (Chpid, okmsg), - emit_consumer_created (Chpid, Consumertag, Exclusiveconsume, + notNoack, QName (State1), A Prefetchcount, Args, none), at notify_decorators (State1), - reply (OK, run_message_queue (State1)) - End;
Rabbit_queue_consumers.erl
Update the process dictionary and add new consumers to the queue.
1 Add (Chpid, Ctag, Noack, Limiterpid, Limiteractive, Prefetch, Args, IsEmpty,2State = #state {consumers =consumers,3Use = Cuinfo})4C = #cr {Consumer_count =Count,5Limiter = limiter} =Ch_record (Chpid, limiterpid),6Limiter1 = CaseLimiteractive of7 true-rabbit_limiter:activate (limiter);8 false-Limiter9 End,TenC1 = C#cr{consumer_count = count + 1, limiter =Limiter1}, One Update_ch_record ( A CaseParse_credit_args (Prefetch, args) of -{0, auto}C1; -{_credit, auto} whenNoackC1; the{Credit, Mode}Credit_and_drain ( - C1, Ctag, Credit, Mode, IsEmpty) - End), -Consumer = #consumer {tag =Ctag, +ack_required = notNoack, -Prefetch =Prefetch, +args =Args}, AState#state{consumers =Add_consumer ({chpid, consumer}, consumers), atUse = Update_use (Cuinfo, Active)}.
The percent of consumer is added to the consumers list , that is, the message is removed from this list when the message is distributed later.
1 in (x, 0, { queue, [_] = in, [], 1})--2 {queue, [x], in, 2}; 3 when Is_list (in), Is_list (out),4 {queue, [x| In], out, Len + 1};
The Basic.consume of Rabbitmq method