38
38
-import (rabbit_data_coercion , [to_binary /1 ]).
39
39
40
40
-define (INFO (Text , Args ), rabbit_log_shovel :info (Text , Args )).
41
- -define (LINK_CREDIT_TIMEOUT , 5000 ).
41
+ -define (LINK_CREDIT_TIMEOUT , 20_000 ).
42
42
43
43
-type state () :: rabbit_shovel_behaviour :state ().
44
44
-type uri () :: rabbit_shovel_behaviour :uri ().
@@ -173,7 +173,8 @@ dest_endpoint(#{shovel_type := dynamic,
173
173
dest := #{target_address := Addr }}) ->
174
174
[{dest_address , Addr }].
175
175
176
- -spec handle_source (Msg :: any (), state ()) -> not_handled | state ().
176
+ -spec handle_source (Msg :: any (), state ()) ->
177
+ not_handled | state () | {stop , any ()}.
177
178
handle_source ({amqp10_msg , _LinkRef , Msg }, State ) ->
178
179
Tag = amqp10_msg :delivery_id (Msg ),
179
180
Payload = amqp10_msg :body_bin (Msg ),
@@ -312,7 +313,8 @@ status(_) ->
312
313
ignore .
313
314
314
315
-spec forward (Tag :: tag (), Props :: #{atom () => any ()},
315
- Payload :: binary (), state ()) -> state ().
316
+ Payload :: binary (), state ()) ->
317
+ state () | {stop , any ()}.
316
318
forward (_Tag , _Props , _Payload ,
317
319
#{source := #{remaining_unacked := 0 }} = State ) ->
318
320
State ;
@@ -331,17 +333,33 @@ forward(Tag, Props, Payload,
331
333
Msg = add_timestamp_header (
332
334
State , set_message_properties (
333
335
Props , add_forward_headers (State , Msg0 ))),
334
- ok = amqp10_client :send_msg (Link , Msg ),
335
- rabbit_shovel_behaviour :decr_remaining_unacked (
336
- case AckMode of
337
- no_ack ->
338
- rabbit_shovel_behaviour :decr_remaining (1 , State );
339
- on_confirm ->
340
- State #{dest => Dst #{unacked => Unacked #{OutTag => Tag }}};
341
- on_publish ->
342
- State1 = rabbit_shovel_behaviour :ack (Tag , false , State ),
343
- rabbit_shovel_behaviour :decr_remaining (1 , State1 )
344
- end ).
336
+ case send_msg (Link , Msg ) of
337
+ ok ->
338
+ rabbit_shovel_behaviour :decr_remaining_unacked (
339
+ case AckMode of
340
+ no_ack ->
341
+ rabbit_shovel_behaviour :decr_remaining (1 , State );
342
+ on_confirm ->
343
+ State #{dest => Dst #{unacked => Unacked #{OutTag => Tag }}};
344
+ on_publish ->
345
+ State1 = rabbit_shovel_behaviour :ack (Tag , false , State ),
346
+ rabbit_shovel_behaviour :decr_remaining (1 , State1 )
347
+ end );
348
+ Stop ->
349
+ Stop
350
+ end .
351
+
352
+ send_msg (Link , Msg ) ->
353
+ case amqp10_client :send_msg (Link , Msg ) of
354
+ ok ->
355
+ ok ;
356
+ {error , insufficient_credit } ->
357
+ receive {amqp10_event , {link , Link , credited }} ->
358
+ ok = amqp10_client :send_msg (Link , Msg )
359
+ after ? LINK_CREDIT_TIMEOUT ->
360
+ {stop , credited_timeout }
361
+ end
362
+ end .
345
363
346
364
new_message (Tag , Payload , #{ack_mode := AckMode ,
347
365
dest := #{properties := Props ,
0 commit comments