parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Ответ

moko 07.10 19:18 / 07.10 19:21

consume failed: a socket error occurred при отключении сети — ожидаемое поведение, и auto_reconnect здесь не поможет. Он восстанавливает соединение в начале следующего вызова метода объекта, а уже идущую прослушку не продолжает: при разрыве ^consume завершается исключением.

Сделано это намеренно, потому что после разрыва нельзя просто продолжить с того же места:
- после переподключения это новый канал, и подписку и qos нужно делать заново;
- сообщения, которые уже были выданы, но не подтверждены, брокер вернёт в очередь и выдаст повторно с флагом redelivered. Колбэк увидит их второй раз;
- delivery_tag от старого соединения больше не действительны, ack по ним даст ошибку канала;
- скрипту обычно важно узнать о разрыве: записать в лог, сбросить своё состояние.

Если бы consume переподключался молча, всё это происходило бы незаметно для скрипта. Поэтому прослушку, которая должна переживать разрывы, пишут циклом:
  $oAmqp[^amqp::create[ $.auto_reconnect(5) ]]
  ^while(1){
        ^try{
                ^oAmqp.qos[$.prefetch_count(1)] ^rem{qos каждый раз: после переподключения он сбрасывается}
                ^oAmqp.consume[
                        $.queue[links]
                        $.ack(true)
                        $.callback[$processTask]
                ]       
        }{   
                $exception.handled(true)
                ^log[consume error: $exception.comment]
        }    
  }     
При разрыве consume бросит исключение, цикл его поймает, а следующий вызов подождёт 5 секунд из auto_reconnect, переподключится и подпишется заново. Если сеть ещё не вернулась, будет снова исключение и новая попытка через 5 секунд.