Merge pull request #149 from rabbitmq/gh-132
Ensure maximum message id value is used when saving to process state
This commit is contained in:
		
						commit
						c1872605ff
					
				|  | @ -158,7 +158,7 @@ process_request(?PUBACK, | ||||||
|       true -> |       true -> | ||||||
|         Tag = gb_trees:get(MessageId, Awaiting), |         Tag = gb_trees:get(MessageId, Awaiting), | ||||||
|         amqp_channel:cast(Channel, #'basic.ack'{ delivery_tag = Tag }), |         amqp_channel:cast(Channel, #'basic.ack'{ delivery_tag = Tag }), | ||||||
|         {ok, PState #proc_state{ awaiting_ack = gb_trees:delete( MessageId, Awaiting)}} |         {ok, PState#proc_state{ awaiting_ack = gb_trees:delete(MessageId, Awaiting) }} | ||||||
|     end; |     end; | ||||||
| 
 | 
 | ||||||
| process_request(?PUBLISH, | process_request(?PUBLISH, | ||||||
|  | @ -192,13 +192,14 @@ process_request(?PUBLISH, | ||||||
| process_request(?SUBSCRIBE, | process_request(?SUBSCRIBE, | ||||||
|                 #mqtt_frame{ |                 #mqtt_frame{ | ||||||
|                   variable = #mqtt_frame_subscribe{ |                   variable = #mqtt_frame_subscribe{ | ||||||
|                               message_id  = MessageId, |                               message_id  = SubscribeMsgId, | ||||||
|                               topic_table = Topics}, |                               topic_table = Topics}, | ||||||
|                   payload = undefined}, |                   payload = undefined}, | ||||||
|                 #proc_state{channels = {Channel, _}, |                 #proc_state{channels = {Channel, _}, | ||||||
|                             exchange = Exchange, |                             exchange = Exchange, | ||||||
|                             retainer_pid = RPid, |                             retainer_pid = RPid, | ||||||
|                             send_fun = SendFun } = PState0) -> |                             send_fun = SendFun, | ||||||
|  |                             message_id  = StateMsgId } = PState0) -> | ||||||
|     check_subscribe_or_die(Topics, fun() -> |     check_subscribe_or_die(Topics, fun() -> | ||||||
|         {QosResponse, PState1} = |         {QosResponse, PState1} = | ||||||
|             lists:foldl(fun (#mqtt_topic{name = TopicName, |             lists:foldl(fun (#mqtt_topic{name = TopicName, | ||||||
|  | @ -218,17 +219,18 @@ process_request(?SUBSCRIBE, | ||||||
|                        end, {[], PState0}, Topics), |                        end, {[], PState0}, Topics), | ||||||
|         SendFun(#mqtt_frame{fixed    = #mqtt_frame_fixed{type = ?SUBACK}, |         SendFun(#mqtt_frame{fixed    = #mqtt_frame_fixed{type = ?SUBACK}, | ||||||
|                             variable = #mqtt_frame_suback{ |                             variable = #mqtt_frame_suback{ | ||||||
|                                         message_id = MessageId, |                                         message_id = SubscribeMsgId, | ||||||
|                                         qos_table  = QosResponse}}, PState1), |                                         qos_table  = QosResponse}}, PState1), | ||||||
|         %% we may need to send up to length(Topics) messages. |         %% we may need to send up to length(Topics) messages. | ||||||
|         %% if QoS is > 0 then we need to generate a message id, |         %% if QoS is > 0 then we need to generate a message id, | ||||||
|         %% and increment the counter. |         %% and increment the counter. | ||||||
|  |         StartMsgId = safe_max_id(SubscribeMsgId, StateMsgId), | ||||||
|         N = lists:foldl(fun (Topic, Acc) -> |         N = lists:foldl(fun (Topic, Acc) -> | ||||||
|                           case maybe_send_retained_message(RPid, Topic, Acc, PState1) of |                           case maybe_send_retained_message(RPid, Topic, Acc, PState1) of | ||||||
|                             {true, X} -> Acc + X; |                             {true, X} -> Acc + X; | ||||||
|                             false     -> Acc |                             false     -> Acc | ||||||
|                           end |                           end | ||||||
|                         end, MessageId, Topics), |                         end, StartMsgId, Topics), | ||||||
|         {ok, PState1#proc_state{message_id = N}} |         {ok, PState1#proc_state{message_id = N}} | ||||||
|     end, PState0); |     end, PState0); | ||||||
| 
 | 
 | ||||||
|  | @ -274,8 +276,6 @@ process_request(?PINGREQ, #mqtt_frame{}, #proc_state{ send_fun = SendFun } = PSt | ||||||
| process_request(?DISCONNECT, #mqtt_frame{}, PState) -> | process_request(?DISCONNECT, #mqtt_frame{}, PState) -> | ||||||
|     {stop, PState}. |     {stop, PState}. | ||||||
| 
 | 
 | ||||||
| %%---------------------------------------------------------------------------- |  | ||||||
| 
 |  | ||||||
| hand_off_to_retainer(RetainerPid, Topic, #mqtt_msg{payload = <<"">>}) -> | hand_off_to_retainer(RetainerPid, Topic, #mqtt_msg{payload = <<"">>}) -> | ||||||
|   rabbit_mqtt_retainer:clear(RetainerPid, Topic), |   rabbit_mqtt_retainer:clear(RetainerPid, Topic), | ||||||
|   ok; |   ok; | ||||||
|  | @ -350,11 +350,10 @@ amqp_callback({#'basic.deliver'{ consumer_tag = ConsumerTag, | ||||||
|                   {?QOS_0, ?QOS_0} -> |                   {?QOS_0, ?QOS_0} -> | ||||||
|                       {ok, PState}; |                       {ok, PState}; | ||||||
|                   {?QOS_1, ?QOS_1} -> |                   {?QOS_1, ?QOS_1} -> | ||||||
|                       {ok, |                       Awaiting1 = gb_trees:insert(MsgId, DeliveryTag, Awaiting), | ||||||
|                        next_msg_id( |                       PState1 = PState#proc_state{ awaiting_ack = Awaiting1 }, | ||||||
|                          PState #proc_state{ |                       PState2 = next_msg_id(PState1), | ||||||
|                            awaiting_ack = |                       {ok, PState2}; | ||||||
|                              gb_trees:insert(MsgId, DeliveryTag, Awaiting)})}; |  | ||||||
|                   {?QOS_0, ?QOS_1} -> |                   {?QOS_0, ?QOS_1} -> | ||||||
|                       amqp_channel:cast( |                       amqp_channel:cast( | ||||||
|                         Channel, #'basic.ack'{ delivery_tag = DeliveryTag }), |                         Channel, #'basic.ack'{ delivery_tag = DeliveryTag }), | ||||||
|  | @ -395,10 +394,17 @@ delivery_dup({#'basic.deliver'{ redelivered = Redelivered }, | ||||||
|         {bool, Dup} -> Redelivered orelse Dup |         {bool, Dup} -> Redelivered orelse Dup | ||||||
|     end. |     end. | ||||||
| 
 | 
 | ||||||
| next_msg_id(PState = #proc_state{ message_id = 16#ffff }) -> | ensure_valid_mqtt_message_id(Id) when Id >= 16#ffff -> | ||||||
|     PState #proc_state{ message_id = 1 }; |     1; | ||||||
| next_msg_id(PState = #proc_state{ message_id = MsgId }) -> | ensure_valid_mqtt_message_id(Id) -> | ||||||
|     PState #proc_state{ message_id = MsgId + 1 }. |     Id. | ||||||
|  | 
 | ||||||
|  | safe_max_id(Id0, Id1) -> | ||||||
|  |     ensure_valid_mqtt_message_id(erlang:max(Id0, Id1)). | ||||||
|  | 
 | ||||||
|  | next_msg_id(PState = #proc_state{ message_id = MsgId0 }) -> | ||||||
|  |     MsgId1 = ensure_valid_mqtt_message_id(MsgId0 + 1), | ||||||
|  |     PState#proc_state{ message_id = MsgId1 }. | ||||||
| 
 | 
 | ||||||
| %% decide at which qos level to deliver based on subscription | %% decide at which qos level to deliver based on subscription | ||||||
| %% and the message publish qos level. non-MQTT publishes are | %% and the message publish qos level. non-MQTT publishes are | ||||||
|  | @ -438,8 +444,6 @@ session_present(Channel, ClientId)  -> | ||||||
|         _                     -> false |         _                     -> false | ||||||
|     end. |     end. | ||||||
| 
 | 
 | ||||||
| %%---------------------------------------------------------------------------- |  | ||||||
| 
 |  | ||||||
| make_will_msg(#mqtt_frame_connect{ will_flag   = false }) -> | make_will_msg(#mqtt_frame_connect{ will_flag   = false }) -> | ||||||
|     undefined; |     undefined; | ||||||
| make_will_msg(#mqtt_frame_connect{ will_retain = Retain, | make_will_msg(#mqtt_frame_connect{ will_retain = Retain, | ||||||
|  | @ -776,7 +780,6 @@ human_readable_mqtt_version(_) -> | ||||||
|     "N/A". |     "N/A". | ||||||
| 
 | 
 | ||||||
| send_client(Frame, #proc_state{ socket = Sock }) -> | send_client(Frame, #proc_state{ socket = Sock }) -> | ||||||
|     %log(info, "MQTT sending frame ~p ~n", [Frame]), |  | ||||||
|     rabbit_net:port_command(Sock, rabbit_mqtt_frame:serialise(Frame)). |     rabbit_net:port_command(Sock, rabbit_mqtt_frame:serialise(Frame)). | ||||||
| 
 | 
 | ||||||
| close_connection(PState = #proc_state{ connection = undefined }) -> | close_connection(PState = #proc_state{ connection = undefined }) -> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue