2011-08-10 6 views
4

システムをブロックせずに遅延AMP応答を与えるにはどうすればよいですか?

私はTwistedでAMPプロトコルを使用して、エージェントにジョブを供給するスケジューラを作成しています。エージェントはスケジューラからジョブをプルするので、スケジューラはAMPサーバであり、エージェントはクライアントとして接続します。

エージェントは、(内部スケジューラ)ジョブキューの上からジョブを取り出し、それを実行するという方法で接続します。ただし、そのキューは常に空ではないことが保証されています。したがって、スケジューラがキューからジョブを取り除くことができたときにエージェントの側に遅延した発火を単にかけるために、ねじれた遅延機構を利用しようとしています。

スケジューラ側でこれを実装することは、ややこしいことです。 AMPが動作する方法は、エージェントが送ることができる各(あらかじめ定義された)コマンドに関数を割り当て、関数が持つすべての引数を取り、それが返すすべての値の辞書を返します。これは、私が1つの関数内からすべてを行う必要があることを意味します。通常、これは問題ではありませんが、ここではねじれているように見えます:ちょっとしたために関数を一時停止させ、ねじれイベントループを一時停止せずに実際にキューにジョブを追加できるようにする必要がありますぽんと鳴らすことができます。 (これが、私が通常のsleep()が望む効果を持つとは思わない理由です。)もっと重要なことは、ねじれた機能を使用する方法を考えることができないということです。 deferToThread()、私はその結果を処理しなければならないので、私はそれをdeferredのコールバックとして代入する別の関数で処理する必要があります。そのため、AMPレスポンダ関数で何を返すのか分からないでしょう別のスレッドを起動し、そのコールバックを割り当てます。これは私がもう少し明確に何を意味するかを示しています。

def assignJob(agentID): 
    # We expect the agentID, so we can store who we've given a job to. 

    # Get a job without blocking even if the queue is originally empty. 
    job = None 
    while job is None: 
     try: 
      job = jobqueue.pop(0) 
     except IndexError: 
      # Imagine getJob simply tries to get a job every 5 seconds 
      # (using sleep() safely because it's in a separate thread) 
      # until it eventually gets one, which it returns 
      d = deferToThread(getJob) 

      # We would then need to have a separate function 
      # , e.g. jobReturn() pick up the firing deferred and do 
      # something with the result... 
      d.addCallback(jobReturn) 

    # But if we do... We don't (necessarily) have a job to return here 
    # because for all we know, the deferred from that thread hasn't even 
    # fired yet. 
    return {'job': ???} 

(。これは明らかに関数の実際の完全なコードではありません - 必要に応じて1のために、それはamp.AMPのサブクラスへの工法です)

リアクターメソッドcallInThread()も最初は便利だと思われます(遅延を返さないため)。ただし、実行可能な呼び出し可能コードの戻り値を得る方法は提供していません。それは、スレッドが終了するのを待つことを意味します。これは、このメソッドを長い間ブロックするので、別のスレッドを無意味に使用することになります。

私はジョブを持っているが、Twistedイベントループ全体ではなく、どうやってこのメソッドをブロックするのですか?また、即時レスポンスメソッドの外でAMP応答を返すのですか?

答えて

4

欠けているかもしれない1つのことは、AMPレスポンダメソッド自体も遅延型を返すことができるということです(の検索でもAMP API docsのDeferredsが返されることがあります)。 Deferredが最終的にコマンドの応答定義と一致する辞書で起動する限り、すべて正常に動作します。

また、スレッドの使用を避けたい場合は、ネイティブにDeferredsを知っているキューデータ構造のtwisted.internet.defer.DeferredQueueを参照してください。

+1

はい!はい、私はそれを逃した!あなたは信じられないほど醜いハックから私を救った、ありがとう! (私がちょっと興奮しているのであれば申し訳ありません、ちょうど30分かけて、ハックをやり遂げることに反対してしまいました) DefferedQueueをもっと詳しく見ていきます。私はいくつかのことを私の待ち行列なので、これでもできるかどうかを判断する必要がありますが、可能な代替手段のように見えます。 – bdeniker

関連する問題