How to set the server timeout in python Klein?
<p>I am using python Klein <a href="http://klein.readthedocs.io/en/latest/" rel="nofollow">http://klein.readthedocs.io/en/latest/</a> for setting up a web service. I had checked the documentation but I still don't know how to set the timeout of the service. Can anyone who is more familiar with tool shows how to set the timeout to 15 seconds? Thanks!</p>

<p>You could call <code>Request.loseConnection()</code> to drop the request connection to the client after an set timeout interval. Here is a quick example:</p>

<pre><code>from twisted.internet import reactor, task, defer
from klein import Klein

app = Klein()
request_timeout = 10 # seconds

@app.route('/delayed/&lt;int:n&gt;')
@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)
</code></pre>

<p>To try this out, go to <code>http://localhost:9000/delayed/2</code> then <code>http://localhost:9000/delayed/20</code> to test a scenario when the task doesn't complete in time. Don't forget to cancel all tasks, deferreds, threads, etc related to this request or you could potentially waste lots of memory.</p>

<h1>Code Explanation</h1>

<p><strong>Server Side Task</strong>:  Client goes to <code>/delayed/&lt;n&gt;</code> endpoint with a specified delay value. A server side task (<code>serverTask()</code>) starts and for the sake of simplicity and to simulate a busy task, <code>deferLater</code> was used to return a string after <code>n</code> seconds.</p>

<p><strong>Request Timeout</strong>:  Using <code>callLater</code> function, after the <code>request_timeout</code> interval, call the <code>dropRequest</code> function and pass <code>request</code> and all work deferreds that need to be canceled (in this case there's only <code>work</code>). When the <code>request_timeout</code> has passed then the request connection will be closed (<code>request.loseConnection()</code>) and deferreds will be cancelled (<code>deferred.cancel</code>).</p>

<p><strong>Yield Server Task Result</strong>:  In a try/except block, the result will be yielded when the value is available or, if the timeout has passed and connection is dropped, an error will occur and the <code>Request dropped</code> message will be returned.</p>

<h1>Alternative</h1>

<p>This really doesn't seem like a desirable scenario and should be avoided if possible, but I could see a need for this kind of functionality. Also, though rare, keep in mind that <code>loseConnection</code> doesn't always fully close a connection (this is due to TCP implementation not so much Twisted). A better solution would be to cancel a server side task when the client disconnects (which may be a bit easier to catch). This can be done by attaching an <code>addErrback</code> to <code>Request.notifyFinish()</code>. Here is an example using just Twisted (<a href="http://twistedmatrix.com/documents/current/web/howto/web-in-60/interrupted.html" rel="nofollow">http://twistedmatrix.com/documents/current/web/howto/web-in-60/interrupted.html</a>).</p>

python web-services klein-mvc