2011-02-08 8 views
7

Sto tentando di implementare get_current_user in RequestHandler for Tornado, ma ho bisogno che la chiamata si blocchi mentre si attende la chiamata asincrona al mio database. Decorare la chiamata con @ tornado.web.asynchronous non funzionerà perché in entrambi i casi il metodo get_current_user ritorna prima che la query asincrona venga completata e venga eseguita la richiamata della query.Tornado Asynchronous Handler

Ad esempio:

class MyHandler(BaseHandler): 
    @tornado.web.asynchronous 
    @tornado.web.authenticated 
    def get(self): 
    self.write('example') 
    self.finish() 

class BaseHandler(tornado.web.RequestHandler): 
    def get_current_user(self): 
    def query_cb(self, doc): 
     return doc or None 

    database.get(username='test', password='t3st', callback=query_cb) 

@ chiamate tornado.web.authenticated get_current_user, ma riceve sempre "Nessuno", perché il BaseHandler non ha il tempo di rispondere. C'è un modo, usando il tornado, per bloccare temporaneamente una chiamata come quella sopra?

risposta

4

Esegue un'operazione di blocco dei database anziché il blocco non descritto in precedenza (Esiste un blocco mysql lib fornito con il tornado).

Dalla pagina del wiki di Tornado sulle discussioni e la concorrenza: "Esegui in modo sincrono e blocca IOLoop. Questo è più appropriato per cose come memcache e query di database che sono sotto il tuo controllo e dovrebbero essere sempre veloci. , rendilo veloce aggiungendo gli indici appropriati al database, ecc. "

https://github.com/facebook/tornado/wiki/Threading-and-concurrency

+0

In sostanza sto chiedendo se c'è un modo per bloccare a livello di tornado perché la mia API di database per couchdb è asincrona e non ha chiamate non bloccanti. Preferisco questo per il resto del sito ad eccezione di questa singola operazione. Questo è il motivo per cui lo sto chiedendo. – Jarrod

+1

Una soluzione: http://pastie.org/private/v6fwon5rryacjavna2o0w – Schildmeijer

+0

2 °: http://code.google.com/p/couchdb-python/ – Schildmeijer

0

Che dire di avere get_current_user restituire un Future da segnalare quando viene restituita la risposta asincrona dal database?

class BaseHandler(tornado.web.RequestHandler): 
    def get_current_user(self): 
     future = Future() 
     def query_cb(user): 
      future.set_result(user or None) 
     database.get(username='test', password='t3st', callback=query_cb) 
     return future 


class MainHandler(BaseHandler): 
    @gen.coroutine 
    def get(self): 
     user = yield self.get_current_user() 
     self.write('user: ' + user) 
     # ... actual request processing