Работа над JabRSS

Одним из первых jabber-проектов в собранном архиве, который пробовал запускать у себя, стал JabRSS – бот для чтения новостных лент.

Предыстория: на начало войны хотелось получать новости в jabber'e более-менее реалтайм, но оригинальный инстанс JabRSS делал апдейты не чаще, чем раз в 45 минут, что я первым делом и исправил, после чего и решил держать свой инстанс на своем сервере.

Бот вполне успешно запустился на python2 и python3.7, но отказался запускаться на python3.9, сославшись на устаревший атрибут getchildren() в xml.etree.ElementTree.Element. Бот в итоге был запущен на сервере под python2 с пакетом библиотек под него; я подергал на эту тему H31, чтобы тот как-то помог и на том все затихло. Я увлекся работой над RSS-транспортом – в итоге на сейчас JabRSS не особо и нужен, транспорт стал более продвинутым и удобным в использовании.

Однако сейчас все же решил поставить уже какую-то точку насчет JabRSS – если там не сильно сложно его доработать – а опыт работы с Python у меня уже немного есть – то почему бы и нет?

Всего было несколько моментов в TODO:

  • Работа под python3.7+
  • Ругань на сертификат для HTTPS-сайтов
  • Реконнекты
  • Оформить свои изменения касательно периода обновления лент.

getchildren() используется в 3 местах в коде: в xmpplify.py в функциях get_child() и _get_elem(), а также в jabrssng.py в session_start(). Из рекомендаций в документации – использовать list(elem) или итерацию. В одном случае итерация и так уже была, в остальных – добавил list(). Честно говоря, так и не понял толком, надо ли что-то вообще дорабатывать – элемент в любом случае вроде как один (или я не так смотрел), так что итерация особо не нужна. Так или иначе, JabRSS запустился на Python3.9, вроде ничего не отвалилось.

Ругань на сертификаты была со стороны urllib3. Напрямую эта библиотека нигде не вызывается в коде – как выяснилось, это зависимость зависимости, поэтому добавлять проверку сертификатов (а надо ли вообще в данном случае?) было неудобно, как и добавлять стандартный вариант подавления этой ошибки. Нашел другой путь – делать export PYTHONWARNINGS="ignore:Unverified HTTPS request" перед запуском бота – так в итоге и поступил, прописав это в etc/jabrss.sh.

С реконнектами идей нет – бот написан на собственной библиотеке автора JabRSS, так что для начала придется вникнуть в проект, по объему в разы превышающий то, над чем я до этого работал. Но из того, что я понял – реконнекты идут из-за таймаута подключения к серверу. Современные клиенты такое обрабатывают нормально, а xmpplify видя, что соединение оборвалось, инициализирует его полностью с нуля. Подозреваю, что в оригинальном инстансе все происходит так же само, но реконнектов нет из-за большой пользовательской базы – 30 активных пользователей и 1000+ зарегистрированных лент создают постоянный поток данных и соединение никогда не прерывается. Так что да, проблема есть, но решать ее можно разными путями – можно вникать и править код – или просто пользоваться ботом :).

Ну и по последнему пункту – сбросил все свои изменения и поправил только MIN_INTERVAL в parserss.py. Протестировал – да, вроде все работает как надо, так что можно ограничиться только этой правкой.

Когда все заработало на обеих версиях python’а, сравнил потребление памяти:

rain@walkbook:~$ python --version
Python 2.7.18
rain@walkbook:~$ python3 --version
Python 3.9.2

Python2:

29804 КБ (14300 shared) при старте и 31444 КБ (15048 shared) при первом получении ленты.

Python3:

35960 КБ (14432 shared) при старте и 37400 КБ (14924 shared) при первом получении ленты.

Версии библиотек на основе списка того, что добавлялось для работы на Python2 – для Python2 версии брались из репозитория Debian предыдущих версий, так что, возможно, можно найти версию чуть свежее:

certifi – 2020.6.20-1 (both 2/3)
chardet – 3.0.4 (py2) / 4.0.0 (py3)
idna – 2.6 (py2) / 2.10 (py3)
lxml – 4.3.2 (py2) / 4.6.3 (py3)
requests – 2.25.1 (both 2/3)
urllib3 – 1.26.3 (py2) / 1.26.5 (py3)

В целом, сильно много переменных и сложно сходу сказать, что именно привело к росту памяти, но одно ясно – рост есть.

Напоследок написал systemd-сервис-файл для запуска бота, как сервиса. Проблем доставило то, что бот предназначен только для запуска в терминале: если боту не передавать параметры подключения, то он спрашивает их в консоли. Тут же, несмотря на наличие всех параметров, при запуске через systemd он довольно невнятно вываливался и в цикле переподключался. Проявлялось как

Started Jabber RSS Bot

JabRSS shutting down...

connected to.....

прочие сообщения об успешном подключении...

******

starting RSS/RDF updater
updater shutting down...

Т.е., сразу после старта RSS-апдейтера тот завершался. На деле надо было смотреть не туда, а на “JabRSS shutting down…” сразу в момент запуска. Если оно есть – ставится флаг и дальше уже ничего не работает (в том числе вываливается и тот апдейтер). В общем, как решение на сейчас – указать StandardInput=tty и TTYPath=/dev/tty10 (какой-нибудь номер повыше из тех, что есть и тех, что вряд ли будут заняты). А в идеале – сделать какую-то проверку или глянуть в сторону псевдотерминалов.

Добавить комментарий