Как установить время ожидания сервера в python Klein?
Я использую Python Klein http://klein.readthedocs.io/en/latest/ для настройки веб-службы. Я проверил документацию, но я все еще не знаю, как установить тайм-аут службы. Может кто-нибудь, кто более знаком с инструментом показывает, как установить тайм-аут на 15 секунд? Спасибо!
1 ответ
Вы могли бы позвонить Request.loseConnection()
сбросить запрос соединения с клиентом через заданный интервал времени ожидания. Вот быстрый пример:
from twisted.internet import reactor, task, defer
from klein import Klein
app = Klein()
request_timeout = 10 # seconds
@app.route('/delayed/<int:n>')
@defer.inlineCallbacks
def timeoutRequest(request, n):
work = serverTask(n) # work that might take too long
drop = reactor.callLater(
request_timeout, # drop request connection after n seconds
dropRequest, # function to drop request connection
request, # pass request obj into dropRequest()
work) # pass worker deferred obj to dropRequest()
try:
result = yield work # work has completed, get result
drop.cancel() # cancel the task to drop the request connection
except:
result = 'Request dropped'
defer.returnValue(result)
def serverTask(n):
"""
A simulation of a task that takes n number of seconds to complete.
"""
d = task.deferLater(reactor, n, lambda: 'delayed for %d seconds' % (n))
return d
def dropRequest(request, deferred):
"""
Drop the request connection and cancel any deferreds
"""
request.loseConnection()
deferred.cancel()
app.run('localhost', 9000)
Чтобы попробовать это, перейдите к http://localhost:9000/delayed/2
затем http://localhost:9000/delayed/20
проверить сценарий, когда задача не завершена вовремя. Не забудьте отменить все задачи, отсрочки, потоки и т. Д., Связанные с этим запросом, иначе вы можете потратить много памяти.
Код Объяснение
Задача на стороне сервера: клиент переходит к /delayed/<n>
конечная точка с указанным значением задержки. Задача на стороне сервера (serverTask()
) запускается и ради простоты и для симуляции занятого задания, deferLater
был использован для возврата строки после n
секунд.
Время ожидания запроса: использование callLater
функция, после request_timeout
интервал, позвоните dropRequest
функционировать и пройти request
и все рабочие отсрочки, которые должны быть отменены (в этом случае есть только work
). Когда request_timeout
прошло, то запрос соединения будет закрыт (request.loseConnection()
) и отсрочки будут отменены (deferred.cancel
).
Результат задачи сервера Yield: в блоке try/ исключением результат будет получен, когда значение станет доступным или, если истекло время ожидания и соединение разорвано, произойдет ошибка, и Request dropped
сообщение будет возвращено.
альтернатива
Это действительно не кажется желательным сценарием, и его следует избегать, если это возможно, но я мог видеть потребность в такого рода функциональности. Также, хотя и редко, имейте в виду, что loseConnection
не всегда полностью закрывает соединение (это связано с тем, что реализация TCP не так сильно закручена). Лучшим решением было бы отменить задачу на стороне сервера, когда клиент отключается (что может быть немного легче поймать). Это можно сделать, прикрепив addErrback
в Request.notifyFinish()
, Вот пример использования только Twisted ( http://twistedmatrix.com/documents/current/web/howto/web-in-60/interrupted.html).