Python、Twisted、Django、Reactor.run()の原因
-
13-10-2019 - |
質問
Django Webアプリケーションがあります。また、Djangoを使用して同じマシンでTwisted Runningを使用して書かれたスペルサーバーもあります(で実行されています localhost:8090
)。アイデアは、ユーザーが何らかのアクションを実行するとき、リクエストがDjangoに届き、このTwisted Server&Serverに接続すると、Djangoにデータが送信されます。最後に、DjangoはこのデータをいくつかのHTMLテンプレートに配置し、ユーザーに提供します。
これが私が問題を抱えているところです。私のdjangoアプリでは、リクエストが入ったときに、シンプルなツイストクライアントを作成して、ローカルに実行されたツイストサーバーに接続します。
...
factory = Spell_Factory(query)
reactor.connectTCP(AS_SERVER_HOST, AS_SERVER_PORT, factory)
reactor.run(installSignalHandlers=0)
print factory.results
...
reactor.run()
問題を引き起こしています。イベントループなので。次回この同じコードがDjangoによって実行されるとき、私はサーバーに接続することができません。これをどのように処理しますか?
解決
上記の2つの答えは正しいです。ただし、すでにスペルを実装していることを考慮してください サーバ それから 1つとして実行します. 。別のプロセスと同じマシンで実行することから始めることができます -で localhost:PORT
. 。今のところ、あなたはすでに非常にシンプルなバイナリプロトコルインターフェイスを持っているようです - あなたは標準のLIBを使用して同様にシンプルなPythonクライアントを実装できます socket
ブロッキングモードのインターフェイス。
ただし、遊ぶことをお勧めします twisted.web
シンプルなWebインターフェイスを公開します。 JSONを使用して、データをシリアル化して脱皮化することができます。これは、Djangoによって十分にサポートされています。これが非常に簡単な例です:
import json
from twisted.web import server, resource
from twisted.python import log
class Root(resource.Resource):
def getChild(self, path, request):
# represents / on your web interface
return self
class WebInterface(resource.Resource):
isLeaf = True
def render_GET(self, request):
log.msg('GOT a GET request.')
# read request.args if you need to process query args
# ... call some internal service and get output ...
return json.dumps(output)
class SpellingSite(server.Site):
def __init__(self, *args, **kwargs):
self.root = Root()
server.Site.__init__(self, self.root, **kwargs)
self.root.putChild('spell', WebInterface())
それを実行するには、次のスケルトンを使用できます .tac
ファイル:
from twisted.application import service, internet
site = SpellingSite()
application = service.Application('WebSpell')
# attach the service to its parent application
service_collection = service.IServiceCollection(application)
internet.TCPServer(PORT, site).setServiceParent(service_collection)
サービスを別のファーストクラスのサービスとして実行すると、必要があることがわかった場合、ある日、別のマシンで実行できます。Webインターフェイスを公開すると、逆プロキシロードバランサーの後ろにも水平方向にスケーリングできます。
他のヒント
reactor.run()
プログラム全体で一度だけ呼び出す必要があります。 「私が持っているこのリクエストを開始する」と考えないでください。「すべてのねじれを開始する」と考えてください。
バックグラウンドスレッドで反応器を実行することは、これを回避する1つの方法です。その後、Djangoアプリケーションを使用できます blockingCallFromThread
djangoアプリケーションでは、ブロッキングAPIと同じようにねじれたAPIを使用します。ただし、WSGIコンテナからの少し協力が必要になります。この背景ねじれたスレッドが適切な時期に開始および停止することを確認する必要があるため(それぞれ通訳が初期化されて破壊されたとき)。
また、TwistedをWSGIコンテナとして使用することもできます。その後、特別なものを開始したり停止する必要はありません。 blockingCallFromThread
すぐに動作します。コマンドラインヘルプを参照してください twistd web --wsgi
.
Twisted Serverまたはエラー/タイムアウトが発生した結果を得た後、リアクターを停止する必要があります。そのため、ツイストサーバーを照会する必要がある各djangoリクエストで、リアクターを実行してから停止する必要があります。しかし、Twisted Libraryによってサポートされていません。リアクターは再起動できません。可能な解決策:
Twisted Reactorには個別のスレッドを使用しますが、Djangoアプリをサーバーで展開する必要があります。サーバーは、長期にわたるスレッドをサポートしています(現在はこれらのいずれもありませんが、簡単に書くことができます:-))。
クライアントプロトコルを実装するためにTwistedを使用しないでください。単純なstdlibを使用してください
socket
モジュール。