Используйте deferreds, если вы выполняете вычисления асинхронно.
Другой способ, если это долгий расчет в отдельном потоке, который начинается, скажем, с помощью deferrToThread (), используйте реактор.callFromThread ()
(Я предполагаю, что мы не делаем тяжелые вычисления в основном цикле - это очень, очень неправильно :))
маленький пример:
def some_long_foo(data_array, protocol):
def send_msg(msg, protocol):
# It actually looks petter in classes without pushing protocol here and
# there
protocol.transport.write(msg)
for n, chunk in enumerate(data_array):
do_something_cool(chunk)
if n and (n % 10 == 0):
from twisted.internet import reactor
# here send_msg will be safely executed in main reactor loop
reactor.callFromThread(send_msg, '10 more chunks processed',
protocol)
# Somwhere in lineReceived we start long calculation
def cb(result):
self.transport.write('got result: {}'.format(result))
d = threads.deferToThread(some_long_foo, data_array, self)
d.addCallback(cb)
Таким образом, теперь мы будем уведомлять клиента об обработке каждых 10 фрагментов данных, а затем, наконец, отправлять ему результат.
код может быть немного неправильным, это просто, например,
документы
UPD:
просто для уточнения:
пропустил часть sendLine. Обычно это не имеет значения, называйте это insted of transport.write ()