1

Django の管理インターフェースを介してTwisted サーバーによって管理されるさまざまなクライアント接続を制御できる Twisted/Django マッシュアップを構築しようとしています。つまり、Django の admin にログインして、現在使用されているプロトコル、各接続に固有の詳細を確認できるようにしたい (たとえば、サーバーが IRC 経由で freenode に接続されている場合、現在接続されているすべてのチャネルを一覧表示する必要があります)。データベース レコードを変更または作成して、新しいクライアントを切断または接続できるようにします。

これを行う最良の方法は何ですか?DjangoTwistedの組み合わせ に関する投稿はたくさんありますが、私が概説したことを実行するための先行技術は見つかりませんでした。私が見た Twisted の例はすべて、ハードコーディングされた接続パラメーターを使用しているため、データベース内のレコードによって通知されたときに、reactor.connectTCP(...) または loseConnection(...) を動的に実行する方法を想像するのが難しくなっています。

私の戦略は、すべてのコマンドについて N 秒ごとに Django/マネージド データベースのみをポーリングするカスタム ClientFactory を作成し、必要に応じて接続を変更/作成/削除し、完了時にデータベースの新しいステータスを反映することです。

これは実現可能だと思いますか?より良いアプローチはありますか?同様の機能を実装する既存のプロジェクトを知っている人はいますか?

4

2 に答える 2

1

私は、djangoとtwistedを組み合わせるさらに別の方法に取り組んできました。気軽に試してみてください:https ://github.com/kowalski/featdjango 。

それが機能する方法は、他のものとは少し異なります。ツイストアプリケーションとhttpサイトを起動します。djangoに対して行われたリクエストは、特別なスレッドプール内で処理されます。特別なのは、これらのスレッドがDeferredを待機できることです。これにより、同期djangoアプリケーションコードと非同期ツイストコードを簡単に組み合わせることができます。

私がこのような構造を思いついた理由は、私のアプリケーションがdjangoビュー内から多くのhttpリクエストを実行する必要があるためです。それらを1つずつ実行する代わりに、ツイストして実行される「メインアプリケーションスレッド」に一度にすべてを委任して、それらを待つことができます。あなたの問題との類似点は、私には非同期コンポーネントもあります。これはシングルトンであり、djangoビューからアクセスします。

したがって、これは、たとえば、ツイストコンポーネントを開始し、後でビューから参照を取得する方法です。

import threading

from django.conf import settings

_initiate_lock = threading.Lock()

def get_component():
    global _initiate_lock
    if not hasattr(settings, 'YOUR_CLIENT')
        _initiate_lock.acquire()
        try:
            # other thread might have did our job while we
            # were waiting for the lock
            if not hasattr(settings, 'YOUR_CLIENT'):
                client = YourComponent(**whatever)
                threading.current_thread().wait_for_deferred(
                    client.initiate)
                settings.YOUR_CLIENT = client
        finally:
            _initiate_lock.release()
    return settings.YOUR_CLIENT

上記のコードは、クライアントを開始し、その上でinitiateメソッドを呼び出します。このメソッドは非同期であり、Deferredを返します。私はそこで必要なすべてのセットアップを行います。djangoスレッドは、次の行に処理する前に、それが終了するのを待ちます。

リクエストハンドラからのみアクセスするため、これが私のやり方です。起動時にコンポーネントを開始して、ListenTCP|SSLを呼び出すことをお勧めします。djangoリクエストハンドラーは、クライアントのいくつかのパブリックメソッドにアクセスするだけで接続に関するデータを取得できます。これらのメソッドはDeferredを返すこともあります。その場合は、.wait_for_defer()を使用して呼び出す必要があります。

于 2012-12-21T16:05:06.547 に答える
1

データベースのポーリングは不十分ですが、残念ながら、データベースには変更を監視するための優れたツールがほとんどありません (データベースに移植可能なツールはありません)。したがって、あなたのアプローチは大丈夫かもしれません。

ただし、アプリが Django にあり、他の (Django 以外の) クライアントからのデータベースへのランダムな変更をサポートしておらず、WSGI コンテナーが Twisted である場合は、 を実行するだけでこれを非常に簡単に行うことができますcallFromThread(connectTCP, ...)

于 2012-11-24T01:20:10.177 に答える