Витой неблокирующий метод - как? - PullRequest
2 голосов
/ 16 февраля 2012

Мой код выглядит так:

... # class Site(Resource)
def render_POST(self,request)
   otherclass.doAssync(request.args)
   print '1'
   return "done" #that returns the HTTP response, always the same.

...

def doAssync(self,msg):
    d = defer.Deferred()
    reactor.callLater(0,self.doStuff,d,msg)
    d.addCallback(self.sucess)

def doStuff(self,d,msg):
    # do some stuff
    time.sleep(2)  #just for example
    d.callback('ok')

def sucess(msg):
    print msg

Вывод:

1

ok

Пока что,это хорошо, но HTTP-ответ (возврат «сделано») происходит только после задержки (time.sleep (2)).Я могу сказать это, потому что браузер продолжает загружаться в течение 2 секунд.

Что я делаю не так?

1 Ответ

4 голосов
/ 16 февраля 2012

То, что вы делаете неправильно, - это блокирующий вызов (time.sleep(2)), в то время как Twisted ожидает, что вы будете выполнять только неблокирующие операции.Вещи, которые не ждут.Поскольку у вас есть time.sleep(2), Twisted больше ничего не может делать, пока эта функция находится в спящем режиме.Поэтому он также не может отправлять данные в браузер.

В случае time.sleep(2) вы бы заменили это другим вызовом reactor.callLater.Предполагая, что вы действительно хотели, чтобы вызов time.sleep(2) был какой-то другой операцией блокировки, как ее исправить, зависит от операции.Если вы можете выполнить операцию неблокирующим образом, сделайте это.Для многих таких операций (например, взаимодействие с базой данных) Twisted уже поставляется с неблокирующими альтернативами.Если то, что вы делаете, не имеет неблокирующего интерфейса и у Twisted нет альтернативы ему, возможно, вам придется запускать код в отдельном потоке (используя, например, twisted.internet.threads.deferToThread), хотя для этого требуется, чтобы ваш код былна самом деле потокобезопасен.

...