BITERP / PinkRabbitMQ

Внешняя Native API компонента для взаимодействия с RabbitMQ из 1С
MIT License
264 stars 107 forks source link

Работа компоненты в фоновом задании #34

Closed Shanginre closed 3 years ago

Shanginre commented 3 years ago

Возник такой вопрос по работе кода, приведенного в README.md:

Пока Клиент.BasicConsumeMessage("", ОтветноеСообщение, ТегСообщения, 5000) Цикл
            Клиент.BasicAck(ТегСообщения);
            Сообщить("Успешно! Из очереди прочитано сообщение " + ОтветноеСообщение);
            ОтветноеСообщение = ""; // Обнуляем, чтобы избежать утечку памяти
            ТегСообщения = 0; // Обнуляем, чтобы избежать утечку памяти
КонецЦикла;

Правильно я понимаю, схему работы с компонентой:

  1. Запускается регламентное задание (с заданной периодичностью), которое в фоновом режиме выполняет цикл с методом BasicConsumeMessage().
  2. Если таймаут истекает и нет новых сообщений в очереди, то BasicConsumeMessage возвращает False, мы выходим из цикла и фоновое задание завершается.

ВОПРОСЫ:

  1. Если мое понимание схемы работы правильное, то получается мы читаем сообщения из очереди с периодичностью запуска регламентного задания, верно?
  2. Г. Стальной на партнерсе написал: "Постоянно весит соединение на сервере (на самом деле нет мы его рубим каждые 10 мин и перезапускаем через расписание регл. задание)". Зачем "рубить" выполнение этого цикла с методом BasicConsumeMessage? Возникают проблемы с памятью? Или в каком контексте он это имел ввиду?
  3. Какие есть причины, чтобы не крутить метод BasicConsumeMessage в цикле постоянно (конечно, нужно дорабатывать существующий метод под такую логику), передавая управление в 1С когда у нас есть новые сообщения в очереди? Это связано со спецификой функционала кролика, или проблемами в native API?
  4. (вопрос связан с 3) Здесь вы написали: "Подход с бесконечным циклом некорректный. Внутренняя либа для работы с rabbitMQ - AMQPСPP поддерживает возможность "подписаться" на очередь. Эту возможность и следуюет использовать." Как я понимаю подписка предполагает создание некого колбека, который будет вызываться по событию поступления новых сообщений в очередь. Но на сервере 1С не поддерживаются события, тогда не понятно какую подписку на очередь вы имеете ввиду?

хотим использовать вашу компоненту (а может и сам адаптер) в проекте, но пока нет уверенности, что компонента работает корректно и (самое главное) оптимально.

ripreal commented 3 years ago
  1. Да. А вообще сообщение можно читать как угодно - на клиенте, на сервере, в фоновом задании и без
  2. В адаптере два ФЗ - на отправку и на получение сообщений из очереди. ФЗ на отправку висит 10 минут и потом штатно завершается как говорит Г. Стальной. ФЗ на получение не висит 10 минут, а ждет все сообщения в цикле из очереди с определенным таймаутом на методе BasicConsumeMessage() . Этот метод блокирует дальнейшее выполнение кода до окончания таймаута или получения очередного сообщенния из очереди. После прочтения сообщения таймаут начинает идти заново до своего окончания или опять же получения нового сообщения изх очереди. Таким образом возможен теоретически бесконечный цикл, если сообщения в очередь будут поступать ранее окончания таймаута.

Никаких проблем с памятью со стороны внешней компоненты не возникает. Но принудительно держать настоящий вечный цикл на стороне 1С, да и на любом языке - это в целом плохая практика.

  1. BasicConsumeMessage() не находится в бесконечном цикле, он считывает все сообщения из очереди, а потом включает таймаут и завершается по его истечении. Можно задать очень высокий таймаут, чтобы цикл был бесконечным. Никто не мешает так делать, но в адаптере мы так не делаем.

  2. В 1С поддерживаются асинхронные операции на клиенте. Но работа с внешними событиями не реализована в компоненте PinkRAbbitMQ, потому что нет задачи, которая требовала бы получение и обработку сообщения на клиенте. В адаптере работа с компонентой выполняется только на сервере.

Рекомендую подождать релиза компоненты 1.10 - это значительно улучшенная производительность по отправке сообщений, поддержка SSL и в целом более оптимальный код и общая оптимизация

Shanginre commented 3 years ago

@ripreal спасибо за подробный и быстрый ответ. Будем ждать тогда нового релиза.

Единственный вопрос. Вы писали: "Но принудительно держать настоящий вечный цикл на стороне 1С, да и на любом языке - это в целом плохая практика."

Что, если цикл будет "вечным", но рег. задание (которое порождает фоновое задание с циклом) мы будем перезапускать раз в сутки, то какие проблемы это может вызвать? Или должно быть все нормально, если у нас утечек памяти не будет?

ripreal commented 3 years ago

Если завершать фоновое задание штатно - дожидаясь окончания выполнения, то наверное никаких проблем

gstalnoy commented 3 years ago

@Shanginre @ripreal там много чего может быть. И по разным причинам. В том числе, связанным с компонентой. И с конфигурацией. И с платформой. И с сервером. Именно поэтому в БИТ.Адаптер перезапуск раз в 10 минут. Опыт - сын ошибок трудных...