﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
35583	asgiref.sync.sync_to_async cannot be affected by close_old_connections	Alexandr Onufrienko		"Rel. to https://code.djangoproject.com/ticket/34914#comment:3
partially rel. to this implementation https://github.com/django/channels/blob/main/channels/db.py

1. Let's assume, that we have django command, that creates a ""server"" that listening for a message from queue, or periodically do some job.
2. Second point - our service have async function and requires DB calls (dummy example in ''_test'' function)
3. let's assume. that we have Postgres DB running in docker compose - and to reproduce this bug, we should call **docker compose restart db**

Similar to Django itself and, for example, to Django channels https://github.com/django/channels/blob/main/channels/db.py we want to be able to close closed connection (simplest way to reproduce - DB was restarted).

**Expected behavior:** we are assuming, that we do same steps as we can see in Django project examples and we should see **success** message in logs.
**Actual**: we will see ''failure: the connection is closed''

**What we can see in code itself:** 
1. sync_to_async class will use its own isolated ThreadPoolExecutor
2. django connections will be created withing this ThreadPoolExecutor and will be unavailable for us (this is my assumption)

**Found workaround**
Calling this code will implicitly have access to hidden DB pool and will close closed connections

{{{
syncio.run(sync_to_async(close_old_connections)())
}}}


Notes:
1. I'm not really sure - is it a feature request or a bug (taking into account, how hard to find theoretical reason of it)
2. I didn't dive into details of **async_to_sync** function/class

Code snippet for Django command
{{{
import asyncio
import time

from asgiref.sync import sync_to_async
from django.db import close_old_connections
from django.core.management.base import BaseCommand

# This can be any model
from django.contrib.auth.models import User


class Command(BaseCommand):
    def handle(self, *args, **options):
        while True:
            process_message()
            time.sleep(3)


def process_message():
    print(""close_old_connections"")
    close_old_connections()

    print(""run test"")
    try:
        test()
        print(""success"")
    except Exception as e:
        print(""failure:"", str(e))
    print(""done test"")


def test():
    asyncio.run(_test())


async def _test():
    """"""
    Synthetic case - most likely, we will use ``sync_to_async`` as decorator for part of functions
    and will use it directly for other calls ``sync_to_async``.
    """"""
    await User.objects.afirst()
    await sync_to_async(
        User.objects.first
    )()
    await sync_to_async(
        User.objects.first,
        thread_sensitive=False,
    )()
}}}

"	Uncategorized	new	Uncategorized		Normal				Unreviewed	0	0	0	0	0	0
