Свисанный не блокирующий метод - как?
-
26-10-2019 - |
Вопрос
Мой код выглядит так:
... # 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 (return 'dode'), происходит только после задержки (Time.sleep (2)). Я могу сказать это, потому что браузер поддерживает «загрузку» в течение 2 секунд.
Что я делаю не так?
Решение
Что вы делаете неправильно, так это блокирующий звонок (time.sleep(2)
), в то время как Twisted ожидает, что вы будете выполнять только не блокирующие операции. Вещи, которые не ждут. Потому что у тебя есть это time.sleep(2)
Там Twisted не может сделать ничего еще, пока эта функция спит. Так что он также не может отправить данные в браузер.
В случае time.sleep(2)
, вы бы заменили это другим reactor.callLater
вызов. Предполагая, что вы на самом деле предназначались для time.sleep(2)
Позвоните в какую -то другую операцию блокировки, как это исправить, зависит от операции. Если вы можете выполнить операцию не блокировка, сделайте это. Для многих таких операций (таких как взаимодействие с базой данных), скрученные, уже поставляются с неблокирующими альтернативами. Если то, что вы делаете, не имеет не блокирующего интерфейса, а Twisted не имеет альтернативы, вам, возможно, придется запустить код в отдельном потоке (например, использование, например twisted.internet.threads.deferToThread
), хотя это требует, чтобы ваш код на самом деле безопасен.