@@ -37,33 +37,67 @@ defmodule BroadwaySQS.ExAwsClient do
3737 def ack ( ack_ref , successful , failed ) do
3838 ack_options = :persistent_term . get ( ack_ref )
3939
40- messages =
41- Enum . filter ( successful , & ack? ( & 1 , ack_options , :on_success ) ) ++
42- Enum . filter ( failed , & ack? ( & 1 , ack_options , :on_failure ) )
40+ success_messages_by_ack_action =
41+ Enum . group_by ( successful , & ack_action ( & 1 , ack_options , :on_success ) )
4342
44- messages
43+ failed_messages_by_ack_action =
44+ Enum . group_by ( failed , & ack_action ( & 1 , ack_options , :on_failure ) )
45+
46+ delete_messages =
47+ Map . get ( success_messages_by_ack_action , :ack , [ ] ) ++
48+ Map . get ( failed_messages_by_ack_action , :ack , [ ] )
49+
50+ delete_messages
4551 |> Enum . chunk_every ( @ max_num_messages_allowed_by_aws )
46- |> Enum . each ( fn messages -> delete_messages ( messages , ack_options ) end )
52+ |> Enum . each ( & delete_messages_batch ( & 1 , ack_options ) )
53+
54+ change_visibility_entries =
55+ collect_nack_entries ( success_messages_by_ack_action ) ++
56+ collect_nack_entries ( failed_messages_by_ack_action )
57+
58+ change_visibility_entries
59+ |> Enum . chunk_every ( @ max_num_messages_allowed_by_aws )
60+ |> Enum . each ( & change_message_visibility_batch ( & 1 , ack_options ) )
4761 end
4862
49- defp ack? ( message , ack_options , option ) do
63+ defp collect_nack_entries ( messages_by_ack_action ) do
64+ Enum . flat_map ( messages_by_ack_action , fn
65+ { { :nack , timeout } , messages } -> Enum . map ( messages , & { & 1 , timeout } )
66+ _ -> [ ]
67+ end )
68+ end
69+
70+ defp ack_action ( message , ack_options , option ) do
5071 { _ , _ , message_ack_options } = message . acknowledger
51- ( message_ack_options [ option ] || Map . fetch! ( ack_options , option ) ) == :ack
72+ message_ack_options [ option ] || Map . fetch! ( ack_options , option )
5273 end
5374
5475 @ impl Acknowledger
5576 def configure ( _ack_ref , ack_data , options ) do
5677 { :ok , Map . merge ( ack_data , Map . new ( options ) ) }
5778 end
5879
59- defp delete_messages ( messages , ack_options ) do
80+ defp delete_messages_batch ( messages , ack_options ) do
6081 receipts = Enum . map ( messages , & extract_message_receipt / 1 )
6182
6283 ack_options . queue_url
6384 |> ExAws.SQS . delete_message_batch ( receipts )
6485 |> ExAws . request! ( ack_options . config )
6586 end
6687
88+ defp change_message_visibility_batch ( messages , ack_options ) do
89+ entries =
90+ Enum . map ( messages , fn { message , timeout } ->
91+ message
92+ |> extract_message_receipt ( )
93+ |> Map . put ( :visibility_timeout , timeout )
94+ end )
95+
96+ ack_options . queue_url
97+ |> ExAws.SQS . change_message_visibility_batch ( entries )
98+ |> ExAws . request! ( ack_options . config )
99+ end
100+
67101 defp wrap_received_messages ( { :ok , % { body: body } } , % { ack_ref: ack_ref } ) do
68102 Enum . map ( body . messages , fn message ->
69103 metadata = Map . delete ( message , :body )
0 commit comments