6666 monitor_ref ,
6767 unacked_messages ,
6868 is_limit_active ,
69+ txn ,
6970 unsent_message_count }).
7071
7172-define (INFO_KEYS ,
@@ -133,6 +134,7 @@ ch_record(ChPid) ->
133134 monitor_ref = MonitorRef ,
134135 unacked_messages = dict :new (),
135136 is_limit_active = false ,
137+ txn = none ,
136138 unsent_message_count = 0 },
137139 put (Key , C ),
138140 C ;
@@ -156,6 +158,11 @@ ch_record_state_transition(OldCR, NewCR) ->
156158 true -> ok
157159 end .
158160
161+ record_current_channel_tx (ChPid , Txn ) ->
162+ % % as a side effect this also starts monitoring the channel (if
163+ % % that wasn't happening already)
164+ store_ch_record ((ch_record (ChPid ))# cr {txn = Txn }).
165+
159166deliver_immediately (Message , Delivered ,
160167 State = # q {q = # amqqueue {name = QName },
161168 round_robin = RoundRobin ,
@@ -198,7 +205,7 @@ deliver_immediately(Message, Delivered,
198205 {not_offered , State }
199206 end .
200207
201- attempt_delivery (none , Message , State ) ->
208+ attempt_delivery (none , _ChPid , Message , State ) ->
202209 case deliver_immediately (Message , false , State ) of
203210 {offered , false , State1 } ->
204211 {true , State1 };
@@ -209,13 +216,13 @@ attempt_delivery(none, Message, State) ->
209216 {not_offered , State1 } ->
210217 {false , State1 }
211218 end ;
212- attempt_delivery (Txn , Message , State ) ->
219+ attempt_delivery (Txn , ChPid , Message , State ) ->
213220 persist_message (Txn , qname (State ), Message ),
214- record_pending_message (Txn , Message ),
221+ record_pending_message (Txn , ChPid , Message ),
215222 {true , State }.
216223
217- deliver_or_enqueue (Txn , Message , State ) ->
218- case attempt_delivery (Txn , Message , State ) of
224+ deliver_or_enqueue (Txn , ChPid , Message , State ) ->
225+ case attempt_delivery (Txn , ChPid , Message , State ) of
219226 {true , NewState } ->
220227 {true , NewState };
221228 {false , NewState } ->
@@ -295,10 +302,16 @@ handle_ch_down(DownPid, State = #q{exclusive_consumer = Holder,
295302 round_robin = ActiveConsumers }) ->
296303 case lookup_ch (DownPid ) of
297304 not_found -> noreply (State );
298- # cr {monitor_ref = MonitorRef , ch_pid = ChPid , unacked_messages = UAM } ->
305+ # cr {monitor_ref = MonitorRef , ch_pid = ChPid , txn = Txn ,
306+ unacked_messages = UAM } ->
299307 NewActive = block_consumers (ChPid , ActiveConsumers ),
300308 erlang :demonitor (MonitorRef ),
301309 erase ({ch , ChPid }),
310+ case Txn of
311+ none -> ok ;
312+ _ -> ok = rollback_work (Txn , qname (State )),
313+ erase_tx (Txn )
314+ end ,
302315 case check_auto_delete (
303316 deliver_or_enqueue_n (
304317 [{Message , true } ||
@@ -456,13 +469,17 @@ is_tx_persistent(Txn) ->
456469 # tx {is_persistent = Res } = lookup_tx (Txn ),
457470 Res .
458471
459- record_pending_message (Txn , Message ) ->
472+ record_pending_message (Txn , ChPid , Message ) ->
460473 Tx = # tx {pending_messages = Pending } = lookup_tx (Txn ),
461- store_tx (Txn , Tx # tx {pending_messages = [{Message , false } | Pending ]}).
474+ record_current_channel_tx (ChPid , Txn ),
475+ store_tx (Txn , Tx # tx {pending_messages = [{Message , false } | Pending ],
476+ ch_pid = ChPid }).
462477
463478record_pending_acks (Txn , ChPid , MsgIds ) ->
464479 Tx = # tx {pending_acks = Pending } = lookup_tx (Txn ),
465- store_tx (Txn , Tx # tx {pending_acks = [MsgIds | Pending ], ch_pid = ChPid }).
480+ record_current_channel_tx (ChPid , Txn ),
481+ store_tx (Txn , Tx # tx {pending_acks = [MsgIds | Pending ],
482+ ch_pid = ChPid }).
466483
467484process_pending (Txn , State ) ->
468485 # tx {ch_pid = ChPid ,
@@ -541,7 +558,7 @@ handle_call({info, Items}, _From, State) ->
541558 catch Error -> reply ({error , Error }, State )
542559 end ;
543560
544- handle_call ({deliver_immediately , Txn , Message }, _From , State ) ->
561+ handle_call ({deliver_immediately , Txn , Message , ChPid }, _From , State ) ->
545562 % % Synchronous, "immediate" delivery mode
546563 % %
547564 % % FIXME: Is this correct semantics?
@@ -555,12 +572,12 @@ handle_call({deliver_immediately, Txn, Message}, _From, State) ->
555572 % % just all ready-to-consume queues get the message, with unready
556573 % % queues discarding the message?
557574 % %
558- {Delivered , NewState } = attempt_delivery (Txn , Message , State ),
575+ {Delivered , NewState } = attempt_delivery (Txn , ChPid , Message , State ),
559576 reply (Delivered , NewState );
560577
561- handle_call ({deliver , Txn , Message }, _From , State ) ->
578+ handle_call ({deliver , Txn , Message , ChPid }, _From , State ) ->
562579 % % Synchronous, "mandatory" delivery mode
563- {Delivered , NewState } = deliver_or_enqueue (Txn , Message , State ),
580+ {Delivered , NewState } = deliver_or_enqueue (Txn , ChPid , Message , State ),
564581 reply (Delivered , NewState );
565582
566583handle_call ({commit , Txn }, From , State ) ->
@@ -711,9 +728,9 @@ handle_call({claim_queue, ReaderPid}, _From, State = #q{owner = Owner,
711728 reply (locked , State )
712729 end .
713730
714- handle_cast ({deliver , Txn , Message }, State ) ->
731+ handle_cast ({deliver , Txn , Message , ChPid }, State ) ->
715732 % % Asynchronous, non-"mandatory", non-"immediate" deliver mode.
716- {_Delivered , NewState } = deliver_or_enqueue (Txn , Message , State ),
733+ {_Delivered , NewState } = deliver_or_enqueue (Txn , ChPid , Message , State ),
717734 noreply (NewState );
718735
719736handle_cast ({ack , Txn , MsgIds , ChPid }, State ) ->
0 commit comments