#34914: Postgres connection is not restarted after it's dropped by the server, even if we use CONN_HEALTH_CHECKS=True -------------------------------------+------------------------------------- Reporter: Vitor Menegat | Owner: nobody Type: Bug | Status: new Component: Database layer | Version: 4.2 (models, ORM) | Severity: Normal | Resolution: Keywords: | Triage Stage: | Unreviewed Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+-------------------------------------
Comment (by Simon Charette): I think this is closely related to #32589 and #14845. Django being mainly a web framework most of its connection management is based around HTTP request lifecycle handling. For example, Django automatically checks whether database connections should be closed [https://github.com/django/django/blob/89d2ae257bfdbe6f32c4671d97bf572623992ace/django/db/__init__.py#L53-L61 when starting and finishing HTTP requests]. The way management commands were designed though didn't account for lifecycle events for the framework to hook into and manage connections appropriately. In other words, `BaseCommand.handle` is a blackbox to the framework and it cannot safely determine that a unit of work is completed and that is is safe to close a connection. In the case of long-running / demonized commands that are meant to run for longer than `CONN_MAX_AGE` (or the TTL of the underlying server connection) it is the responsibility of the user to call `close_old_connections`. This is something that is unfortunately not documented but given how common this use case and the lack of progress on #14845 in the past years I think we should consider a documentation admonition that focuses solely on the long-runner command use case if that means documenting this pattern more broadly. If you feel so inclined to get this documented it appears to be a good opportunity to resolve a 10 years old issue ;) TL;DR the following should address your issue but it's unfortunately not documented {{{#!python import logging import time from django.core.management import BaseCommand from django.db import close_old_connections, connection logger = logging.getLogger(__name__) class Command(BaseCommand): def handle(self, *args, **kwargs): while True: close_old_connections() # <- this ensures DATABASES["default"]["CONN_*"] settings are honoured. time.sleep(1) try: logger.info(f"health_check_enabled: {connection.health_check_enabled}") logger.info(f"health_check_done: {connection.health_check_done}") logger.info(f"errors_occurred: {connection.errors_occurred}") with connection.cursor() as cursor: cursor.execute("SELECT 1") logger.info("query executed") except Exception as e: logger.exception(e) }}} -- Ticket URL: <https://code.djangoproject.com/ticket/34914#comment:3> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/0107018b4a8343fe-6d5998cb-7a85-4223-b8ec-aec6908502cd-000000%40eu-central-1.amazonses.com.