2016-09-20 7 views
0

私はpython Klein http://klein.readthedocs.io/en/latest/を使ってWebサービスを設定しています。私はドキュメントをチェックしたが、私はまだサービスのタイムアウトを設定する方法を知らない。ツールに慣れている人なら、タイムアウトを15秒に設定する方法を教えてください。ありがとう!python Kleinでサーバのタイムアウトを設定するには?

+0

何をタイムアウトしますか?セッション、リクエスト、....? –

+0

私は信じてタイムアウトを要求する?サーバーがコールを受信し、一定の時間枠(10秒)で応答できない場合、サーバーはクライアントにタイムアウトを返します。 – JLTChiu

+0

次回に '' klien''という質問があるときにタグに '' twisted''を追加できますか?この方法はツイストdevsもあなたの質問を見つけることができます。 –

答えて

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/2http://localhost:9000/delayed/20に行き、これを試してみるために。このリクエストに関連するすべてのタスク、延期、スレッドなどをキャンセルすることを忘れないでください。そうしないと、メモリが大量に消費される可能性があります。

コード説明

サーバー側のタスク:クライアントが指定した遅延値を持つ/delayed/<n>エンドポイントになります。サーバー側のタスク(serverTask())が開始され、簡略化のためにビジーなタスクをシミュレートするためにdeferLaterを使用してn秒後の文字列を戻しました。

要求タイムアウトcallLater機能を使用して、request_timeoutインターバルの後、dropRequest関数を呼び出してrequestと(この場合のみworkがあります)をキャンセルする必要があるすべての作業のDeferredを渡します。 request_timeoutが通過すると、要求接続は終了し(request.loseConnection())、遅延はキャンセルされます(deferred.cancel)。

収量サーバタスク結果:試行の値が利用可能であるときに/ブロックを除いて、結果が得られたであろう、または、タイムアウトが経過すると、接続が切断された場合、エラーが発生するとRequest droppedメッセージがされると戻ってきた。

代替

これは本当に望ましいシナリオのようには思えないし、可能であれば避けるべきであるが、私はこの種の機能の必要性を見ることができました。まれに、loseConnectionは必ずしも接続を完全に閉じるとは限りません(これは、TCPの実装がそれほどあまりひねられていないためです)。より良い解決策は、クライアントが切断されたときにサーバー側のタスクをキャンセルすることです(これは少しは簡単です)。これは、addErrbackRequest.notifyFinish()に添付することによって行うことができます。ここでは、Twisted(http://twistedmatrix.com/documents/current/web/howto/web-in-60/interrupted.html)を使用した例を示します。

関連する問題