MagicStack / MagicStack/asyncpg

Continuous memory increase in Sanic web server after calling `loop.start_tls(...)` in `connect_utils._create_ssl_connection`

Ouverte
#1,004 2 commentaires 0 réactions 1 personne assignée Voir sur GitHub

@fantix y travaille déjà.

Depuis le 17/2/2023.

Langage dominant
Python
Étoiles
8.1k
Forks
468
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

  • asyncpg version: 0.2.7
  • PostgreSQL version: PostgreSQL 13.3 (Debian 13.3-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
  • Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
    the issue with a local PostgreSQL install?
    : I use PostgreSQL installed in docker image kartoza/postgis:pr-333-13-3.1
  • Python version: 3.8.10
  • Platform: 20.04.1-Ubuntu x86_64
  • Do you use pgbouncer?: Not sure, I use it indirectly. (behind sqlalchemy)
  • Did you install asyncpg with pip?: Yes
  • If you built asyncpg locally, which version of Cython did you use?: /
  • Can the issue be reproduced under both asyncio and
    uvloop?
    : I see the code below is based on uvloop.

Background: I built a simple web server using sqlalchemy and sanic, then created a request handler function that can query my local PostgreSQL server running in docker. However, I saw continuous memory increase while benching my handler function.

After running tracemalloc for help, I got the result below:

Top 10 lines
#1: /home/tusimple/Workspace/projects/map-workdata-manager/venv/lib/python3.8/site-packages/asyncpg/connect_utils.py:700: 5670.1 KiB
    new_tr = await loop.start_tls(

The code for creating the async_engine is:

from sqlalchemy.ext.asyncio import create_async_engine
engine = create_async_engine("postgresql+asyncpg://{}:{}@{}/{}".format(...))

At first, I tried adding ?ssl=disable after the previous connect string in order to prevent connect_utils._create_ssl_connection calls, and it works.
Then, I tried to make some stupid changes to the source code of asyncpg, because I think this SSL transport is not closed after creating new transport. (I'm not sure is that correct)

# line 697 
    if hasattr(loop, 'start_tls'):
        if do_ssl_upgrade:
            try:
                new_tr = await loop.start_tls(
                    tr, pr, ssl_context, server_hostname=host)        # <--- here
            except (Exception, asyncio.CancelledError):
                tr.close()
                raise
        else:
            new_tr = tr
# line 706

Finally, I modified the code starts from line 702 to:

            except (Exception, asyncio.CancelledError):
                raise
            finally:
                tr.close()

After this modification, my web server keeps working fine, but I don't know whether this is a proper modification.

If you have any questions or ideas, please let me know, thank you so much!

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.