mio elaborazione modello Post utilizza il segnale post_save
:segnali asincroni con asyncio
from django.core.signals import request_finished
from django.dispatch import receiver
from models import MyModel
from pipeline import this_takes_forever
@receiver(post_save, sender=MyModel)
def my_callback(sender, **kwargs):
this_takes_forever(sender)
Il this_takes_forever
di routine fa IO quindi voglio rinviare per evitare il blocco della richiesta troppo.
Ho pensato che fosse un ottimo caso per il nuovo modulo asyncio. Ma ho difficoltà a prendere in considerazione l'intero processo.
Credo dovrei essere in grado di adattare il ricevitore di segnale in questo modo:
@receiver(post_save, sender=MyModel)
def my_callback(sender, **kwargs):
loop = asyncio.get_event_loop()
loop.run_until_complete(this_takes_forever(sender))
loop.close()
fornito this_takes_forever
è inoltre atto ad essere un coroutine.
@coroutine
def this_takes_forever(instance):
# do something with instance
return instance
Questo suona troppo magico per funzionare. Ed in effetti ferma con una AssertionError
:
AssertionError at /new/
There is no current event loop in thread 'Thread-1'.
Non vedo dove devo iniziare il ciclo in questo contesto. Qualcuno ha provato qualcosa del genere?
Ok con il primo punto. Forse questo è solo un cattivo esempio, proverò a fare il refactoring per maggiore chiarezza. Ad ogni modo non sto usando django in nessuna modalità multithread, semplicemente eseguendo il 'runserver' predefinito che è un thread. Guardando più a fondo sembra che avrei bisogno di collegare alcuni server non bloccanti come [aiohttp] (https://github.com/KeepSafe/aiohttp) – tutuca
Dalla mia comprensione 'runserver' crea in realtà un nuovo thread per eseguire l'applicazione Django al suo interno da default - è così che funziona la funzione "autoreload'. –
su aiohttp - per favore nota che la libreria è troppo bassa ora paragonando Django o, ad esempio, tornado.web. Sto lavorando su un'interfaccia più user friendly ma il lavoro è in una fase molto precoce. –