Как установить время ожидания сервера в 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).

Другие вопросы по тегам