<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>разработка &amp;mdash; Блог Евгения Морозова</title>
    <link>https://emorozov.net/tag:разработка</link>
    <description></description>
    <pubDate>Mon, 22 Jun 2026 23:26:45 +0300</pubDate>
    <item>
      <title>Исправление ошибки в meliae</title>
      <link>https://emorozov.net/ispravlenie-oshibki-v-meliae</link>
      <description>&lt;![CDATA[Для поиска утечек памяти в приложениях на Python существует масса различных модулей, в том числе, уже встроенный в Python 3 модуль tracemalloc. Недостаток всех этих инструментов в том, что утечку надо воспроизвести в локальном окружении, а потом уже, используя pdb или ipdb, ковыряться в куче (heap), в поисках утекших объектов. Однако если у нас есть огромный проект, посещаемый миллионами пользователей, то воспроизвести утечку может оказаться невозможно, так как к ней приводит какое-то сочетание взаимодействия пользователей с проектом, которое не воспроизвести наугад.&#xA;&#xA;К счастью, нашёл проект meliae, позволяющий сделать дамп кучи в произвольный момент, с тем, чтобы проанализировать ее в оффлайне, уже не на боевом сервере.&#xA;&#xA;Однако, в проекте оказался досадный баг: целые числа Python он пытается сериализовать как тип C long. Но в Python целое число может быть произвольной разрядности, а в C long имеет разрядность 32 или 64 бит. Где-то в нашем проекте (или одной из его зависимостей) используются большие числа, поэтому создать дамп не удавалось, потому что этот процесс очень быстро обрывался с ошибкой OverflowError.&#xA;&#xA;Делать нечего, все другие варианты поиска утечки я уже попробовал без малейшего успеха. Скомпилировал Python из исходников с отладочной информацией, скомпилировал meliae, и стал вспоминать полузабытые навыки программирования на C и использования отладчика gdb. Довольно быстро нашел место возникновения ошибки, проблема была только в том, что времени на поиски у меня немного, а изучение того, как сдампить из модуля на C полноценное представление целого числа Python, потребовало бы длительного изучения устройства интерпретатора Python.&#xA;&#xA;В итоге воспользовался быстро найденной функцией PyLong_AsLongLongAndOverflow, которая возвращает -1, в случае, если число Python не помещается в long long. Сомневаюсь, что в нашем приложении утекают long, поэтому точное их значение меня не интересует.&#xA;&#xA;Свои правки положил здесь: https://github.com/emorozov/meliae&#xA;&#xA;Если удастся найти утечку памяти, постараюсь написать об этом тоже.&#xA;&#xA;#python #разработка]]&gt;</description>
      <content:encoded><![CDATA[<p>Для поиска утечек памяти в приложениях на Python существует масса различных модулей, в том числе, уже встроенный в Python 3 модуль <a href="https://docs.python.org/3/library/tracemalloc.html" rel="nofollow">tracemalloc</a>. Недостаток всех этих инструментов в том, что утечку надо воспроизвести в локальном окружении, а потом уже, используя pdb или ipdb, ковыряться в куче (heap), в поисках утекших объектов. Однако если у нас есть огромный проект, посещаемый миллионами пользователей, то воспроизвести утечку может оказаться невозможно, так как к ней приводит какое-то сочетание взаимодействия пользователей с проектом, которое не воспроизвести наугад.</p>

<p>К счастью, нашёл проект <a href="https://launchpad.net/meliae" rel="nofollow">meliae</a>, позволяющий сделать дамп кучи в произвольный момент, с тем, чтобы проанализировать ее в оффлайне, уже не на боевом сервере.</p>

<p>Однако, в проекте оказался досадный баг: целые числа Python он пытается сериализовать как тип C long. Но в Python целое число может быть произвольной разрядности, а в C long имеет разрядность 32 или 64 бит. Где-то в нашем проекте (или одной из его зависимостей) используются большие числа, поэтому создать дамп не удавалось, потому что этот процесс очень быстро обрывался с ошибкой <code>OverflowError</code>.</p>

<p>Делать нечего, все другие варианты поиска утечки я уже попробовал без малейшего успеха. Скомпилировал Python из исходников с отладочной информацией, скомпилировал meliae, и стал вспоминать полузабытые навыки программирования на C и использования отладчика gdb. Довольно быстро нашел место возникновения ошибки, проблема была только в том, что времени на поиски у меня немного, а изучение того, как сдампить из модуля на C полноценное представление целого числа Python, потребовало бы длительного изучения устройства интерпретатора Python.</p>

<p>В итоге воспользовался быстро найденной функцией <code>PyLong_AsLongLongAndOverflow</code>, которая возвращает -1, в случае, если число Python не помещается в <code>long long</code>. Сомневаюсь, что в нашем приложении утекают long, поэтому точное их значение меня не интересует.</p>

<p>Свои правки положил здесь: <a href="https://github.com/emorozov/meliae" rel="nofollow">https://github.com/emorozov/meliae</a></p>

<p>Если удастся найти утечку памяти, постараюсь написать об этом тоже.</p>

<p>#python #разработка</p>
]]></content:encoded>
      <guid>https://emorozov.net/ispravlenie-oshibki-v-meliae</guid>
      <pubDate>Sun, 17 May 2020 11:13:05 +0000</pubDate>
    </item>
    <item>
      <title>Вывод списка сигналов для всех моделей в проекте на Django</title>
      <link>https://emorozov.net/vyvod-spiska-signalov-dlia-vsekh-modelei-v-proekte-na-django</link>
      <description>&lt;![CDATA[В больших и старых проектах на Django бывает непросто найти ошибки из-за большого количества сигналов. Сигналы затрудняют анализ кода, так как обработчик может быть создан в любом модуле проекта, например, не в том, где определена модель, и вызывается неявно.&#xA;&#xA;Для облегчения поиска обработчиков нашел когда-то команду для Django, выводящую список всех обработчиков в проекте. Но она выводила только список обработчиков, без указания к какой модели они относятся. Чуть позже нашлась усовершенствованная версия, а затем я тоже приложил руки в процессе создания pull request для проекта django-extensions. Пришлось попотеть, так как django-extensions должен работать на большом количестве различных версий Python и Django (включая, например, PyPy). Но все препятствия удалось преодолеть, надеюсь, что мой код окажется в django-extensions, а пока оставляю ссылку на сам код команды, чтобы можно было пользоваться, пока рассматривается pull request:&#xA;list_signals.py&#xA;&#xA;#python #разработка]]&gt;</description>
      <content:encoded><![CDATA[<p>В больших и старых проектах на Django бывает непросто найти ошибки из-за большого количества сигналов. Сигналы затрудняют анализ кода, так как обработчик может быть создан в любом модуле проекта, например, не в том, где определена модель, и вызывается неявно.</p>

<p>Для облегчения поиска обработчиков нашел когда-то команду для Django, выводящую список всех обработчиков в проекте. Но она выводила только список обработчиков, без указания к какой модели они относятся. Чуть позже нашлась усовершенствованная версия, а затем я тоже приложил руки в процессе создания pull request для проекта <a href="https://github.com/django-extensions/django-extensions" rel="nofollow">django-extensions</a>. Пришлось попотеть, так как django-extensions должен работать на большом количестве различных версий Python и Django (включая, например, PyPy). Но все препятствия удалось преодолеть, надеюсь, что мой код окажется в django-extensions, а пока оставляю ссылку на сам код команды, чтобы можно было пользоваться, пока рассматривается pull request:
<a href="https://gist.github.com/emorozov/15bfca496a765d927dab627a6016ca58" rel="nofollow">list_signals.py</a></p>

<p>#python #разработка</p>
]]></content:encoded>
      <guid>https://emorozov.net/vyvod-spiska-signalov-dlia-vsekh-modelei-v-proekte-na-django</guid>
      <pubDate>Sun, 10 May 2020 07:57:28 +0000</pubDate>
    </item>
  </channel>
</rss>