Skip to content

sync_to_async is incompatible with asyncio.run_coroutine_threadsafe #527

@aliqandil

Description

@aliqandil

While doing some work on a Django project, I ran into an issue that I can't add a task to be run in an already running loop from a model_save signal using the method meant for this very action: asyncio.run_coroutine_threadsafe

I might be wrong in some of my assumptions, but I think using run_coroutine_threadsafe should not require the thread_sensitive argument to be given as false. (which is specially a hard problem in Django since I don't control things like await model_instance.asave())

A bit more context, here is the part of the code that runs on django signals:

def model_changed( self, signal_name, sender, signal, instance, **kwargs ):
  asyncio.run_coroutine_threadsafe(
    self.start_task_now( task, reason = f"Change ({signal_name}) on {instance}" ),
    self.loop
  )

which then, running something like this in the start_task_now function gives an error:

await sync_to_async( lambda: None )()
>>> RuntimeError: Single thread executor already being used, would deadlock

My current workaround:

def start( self, is_robust = False ):
  ...
  self.loop = asyncio.new_event_loop()
  asyncio.set_event_loop( self.loop )
  
  #Run tasks from other threads, explicitly safe
  self.task_reason_jobs_queue = asyncio.Queue()
  self.create_task( self.consume_task_reason_jobs_queue() )
  ...

async def consume_task_reason_jobs_queue( self ):
  while True:
    task, reason = await self.task_reason_jobs_queue.get()
    await self.start_task_now( task, reason )
    self.task_reason_jobs_queue.task_done()

I could be wrong thinking the run_coroutine_threadsafe should work in the first place my work around might just be the correct solution, but I guessed I might as well create an issue and let those that know better decide.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions