2016-09-23 16 views
2

私はTxmongoライブラリと共にTwistedを使用しています。 次の関数では、5秒後にcancelTest()を呼び出したいと思います。しかし、コードは動作しません。どうすればそれを動作させることができますか?一定時間後にコールバック関数を呼び出す方法

from twisted.internet import task 

def diverge(self, d): 
    if d == 'Wait': 
     self.flag = 1 
     # self.timeInit = time.time() 
     clock = task.Clock() 
     for ip in self.ips: 
      if self.factory.dictQueue.get(ip) is not None: 
       self.factory.dictQueue[ip].append(self) 
      else: 
       self.factory.dictQueue[ip] = deque([self]) 
       # self.factory.dictQueue[ip].append(self) 

     log.msg("-----------------the queue after wait") 
     log.msg(self.factory.dictQueue) 
###############################HERE, this does not work 
     self.dtime = task.deferLater(clock, 5, self.printData) 
############################# 
     self.dtime.addCallback(self.cancelTest) 
     self.dtime.addErrback(log.err) 
    else: 
     self.cancelTimeOut() 
     d.addCallback(self.dispatch) 
     d.addErrback(log.err) 



def sendBackIP(self): 
    self.ips.pop(0) 
    log.msg("the IPs: %s" % self.ips) 

    d = self.factory.service.checkResource(self.ips) 

    d.addCallback(self.diverge) ###invoke above function 
    log.msg("the result from checkResource: ") 
    log.msg() 

答えて

0

一般的にreactor.callLater()は、必要な機能です。関数は5秒後に呼び出す必要があるので、もし、あなたのコードは次のようになります。奇妙である

from twisted.internet import reactor 
reactor.callLater(5, cancelTest) 

一つのことは、あなたのtask.deferLater実装も動作するはずということです。しかし、あなたのコードの多くを見ることなく、私はそれはあなたがほとんどやっている奇妙な:)

参照

+0

Clock()はIReactorTimeの決定的模擬実装であるため、clock.advance(5)が呼び出されない限り時計は決して動かないでしょう。 –

0

だことを伝えるよりも、あなたがそれ以上の他のを助けることができるとは思いませんすべての権利;あなたはちょうど時計の部分を正しく取得していない。

twisted.internet.task.Clockは、IReactorTimeの確定的な実装です。これは主に、コードから確定的な出力を得るためのユニット/統合テストに使用されます。本番環境では使用しないでください。

プロダクションではどうすればよいですか? リアクター!実際、すべての生産炉の実装ではIReactorTimeインターフェイスが実装されています。

ただ、次のインポート機能の呼び出しを使用します。

from twisted.internet import reactor 
# (omissis) 
self.dtime = task.deferLater(reactor, 5, self.printData) 

だけでいくつかのsidenotes:スニペット上記のテキストに

を、あなたは5秒後にcancelTestを起動したいと言うが、中あなたが実際に呼び出すコードprintData;もちろん、printDataが単に何かを出力し、即値を生成せずに返す場合、これは、チェーンされたcallcackであるため、直ちにcancelTest関数が実行されます。 実際に100%確実にするには、printDataではなく、deferLater内でcancelTestを呼び出す必要があります。

また、これが一種の「タイムアウト」であるかどうかわかりません。このようなコールバックは、テストが5秒未満であっても、すべての状況でトリガされることに注意してください。キャンセル可能なタスクが必要な場合は、reactor.callLaterを直接使用する必要があります。あなたが使用できる延期は返されませんが、スケジュールされた通話を取り消すことができます。

+0

答えをありがとう。私はまだ質問があります。このプログラムはinternet.TCPServerと他のサービスモジュールを使用しているので、原子炉は実際に場面の後ろにあるので、あなたが言ったような原子炉を使用すれば、それは2つの原子炉ですか?それで私は何をしますか? – Henry

+0

リアクタは、実際にはPOSA2の本によく記載されているパターンです。http://eu.wiley.com/WileyCDA/WileyTitle/productCd-0471606952.html リアクタは1つだけです。 Twistedでは、Linux環境下であれば、おそらくSelectReactorやEPollReactorを使用しています。このようなモジュールを最初にインポートすると、既定の原子炉(https:// github)がまだインストールされていない場合にインスタンシエートされます。 これは、ボンネットの下で原子炉を使用するTCPServerであり、副作用ではありません。特定の実装が必要になるまで、無視しても問題ありません。 –

関連する問題