2015-01-29 5 views
10

Sto cercando di utilizzare il lavoratore in gaiohttp Gunicorn con un app Django sto sviluppando con il seguente comando:Come posso cedere ad un'altra richiesta quando usi gunicorn con asyncio?

gunicorn -k gaiohttp -b localhost:8080 myproject.wsgi 

Il mio obiettivo finale è quello di essere in grado di elaborare le richieste contemporaneamente - cioè hanno lavoratore 1 gunicorn elaborare più richieste contemporaneamente. Vi sono operazioni con I/O che rendono le richieste lente.

so un ciclo di eventi è già in esecuzione quando sto elaborazione di una richiesta:

class MyView(View): 

    def get(self, request): 
     loop = asyncio.get_event_loop() 
     loop.is_running() # True 
     ... 

Domande:

  1. Come posso eseguire un'operazione come yield from asyncio.sleep(10) nel mio codice della vista?

    class MyView(View): 
    
        def get(self, request): 
         # Raises AssertionError: yield from wasn't used with future 
         yield from asyncio.sleep(10) 
    
  2. posso aggiungere attività per il ciclo degli eventi, tuttavia essi non bloccano durante l'elaborazione della richiesta

    @asyncio.coroutine 
    def simulate_work(): 
        yield from asyncio.sleep(10) 
    
    class MyView(View): 
    
        def get(self, request): 
         # This runs simulate_work(), however, it doesn't block 
         # the response is returned before simulate_work() is finished 
         loop = asyncio.get_event_loop() 
         task = loop.create_task(simulate_work()) 
    
  3. cerco di utilizzare future, ma il ciclo degli eventi è già in esecuzione

    @asyncio.coroutine 
    def simulate_work(future): 
        yield from asyncio.sleep(10) 
        future.set_result('Done!') 
    
    class MyView(View): 
    
        def get(self, request): 
         future = asyncio.Future() 
         asyncio.async(simulate_work(future)) 
         loop = asyncio.get_event_loop() 
         # Raises RuntimeError: Event loop is running. 
         loop.run_until_complete(future) 
         print(future.result()) 
    

Chiaramente c'è qualcosa che non sto capendo circa asyncio o gaiohttp.

Come posso avere il blocco asyncio.sleep(10) per le richieste correnti, ma non bloccare Gunicorn dall'elaborazione di altre richieste?

+0

Altri utenti di gunicorn hanno menzionato la stessa cosa di Andrew - vedi http://lists.gunicorn.org/user/74434.html - Purtroppo, mi sono arreso e ho iniziato a utilizzare il framework Tornado. –

risposta

6

Spiacente, non è possibile chiamare le coroutine dalla propria applicazione wsgi - WSGI è protocollo sincrono, nonché framework costruiti sopra di esso (Django, Flask, Pyramid).

Ho implementato il lavoratore gaiohttp ma è un cittadino di seconda classe nel mondo asyncio. Se hai veramente bisogno del server HTTP asincrono, prova aiohttp.web.