Deferredオブジェクトを使用するWebサービスコードで、使用しないコードと同じ動作を生成するのに苦労しています。私の目的は、任意のメソッド(Twistedから切り離されている)の処理をTwistedスレッドプールに委任するデコレーターを作成して、そのメソッドのセマンティクスを変更せずに、リアクターがブロックされないようにすることです。
以下のクラスechoのインスタンスがWebサービスとして公開されると、次のコードが表示されます。
from twisted.web import server, resource
from twisted.internet import defer, threads
from cgi import escape
from itertools import count
class echo(resource.Resource):
isLeaf = True
def errback(self, failure): return failure
def callback1(self, request, value):
#raise ValueError # E1
lines = ['<html><body>\n',
'<p>Page view #%s in this session</p>\n' % (value,),
'</body></html>\n']
return ''.join(lines)
def callback2(self, request, encoding):
def execute(message):
#raise ValueError # E2
request.write(message.encode(encoding))
#raise ValueError # E3
request.finish()
#raise ValueError # E4
return server.NOT_DONE_YET
return execute
def render_GET(self, request):
content_type, encoding = 'text/html', 'UTF-8'
request.setHeader('Content-Type', '%s; charset=%s' %
tuple(map(str, (content_type, encoding))))
s = request.getSession()
if not hasattr(s, 'counter'):
s.counter = count(1)
d = threads.deferToThread(self.callback1, request, s.counter.next())
d.addCallback(self.callback2(request, encoding))
d.addErrback(self.errback)
#raise ValueError # E5
return server.NOT_DONE_YET
すべてのraiseステートメントがコメントアウトされるとブラウザにHTMLドキュメントが表示され、「E5」というラベルの付いたraiseステートメントが含まれると適切にフォーマットされたスタックトレースが表示されます(Twistedが私に代わって行います)。それが私が欲しいものです。同様に、Deferredオブジェクトをまったく使用せず、callback1とcallback2のすべての動作をrender_GET()内に配置すると、render_GET内のどこかで例外が発生すると、目的のスタックトレースが生成されます。
Twisted内でリソースリークを引き起こさず、ブラウザにすぐに応答し、raiseステートメント「E1」から「E3」のいずれかが含まれている場合にもブラウザスタックトレースを表示するコードを記述しようとしています。延期されたコード-もちろん、スタックトレース自体が異なることは理解しています。(「E4」の場合はあまり気にしません。)このサイトのTwistedドキュメントやその他の質問を読んだ後、これを実現する方法がわかりません。エラーバックを追加するとこれが容易になると思いましたが、明らかにそうではありません。遅延オブジェクトとtwisted.webスタックについて、私が理解していないことがあるはずです。
ここで説明するロギングへの影響は、PythonLoggingObserverを使用してTwistedロギングを標準のロギングモジュールにブリッジすることによって影響を受ける可能性があります。
「E1」が含まれている場合、ブラウザはリアクタがシャットダウンされるまで待機します。シャットダウンすると、スタックトレースを含むValueError例外がログに記録され、ブラウザは空のドキュメントを受け取ります。
「E2」が含まれている場合、スタックトレースを含むValueError例外はすぐにログに記録されますが、ブラウザはリアクタがシャットダウンするまで待機し、その時点で空のドキュメントを受け取ります。
「E3」が含まれている場合、スタックトレースを含むValueError例外がすぐにログに記録され、ブラウザはリアクタがシャットダウンするまで待機し、その時点で目的のドキュメントを受信します。
発生ステートメント「E4」が含まれている場合、目的のドキュメントはすぐにブラウザに返され、スタックトレースを含むValueError例外がすぐにログに記録されます。(この場合、リソースリークの可能性はありますか?)