2011-08-19 61 views
6

我正在使用twisted的Perspective Broker在客戶端和服務器之間進行通話。客戶端從服務器請求遠程方法'remote_ssh'。這會導致PB服務器使用Paramiko的SSH庫啓動SSH連接並從遠程設備檢索配置。扭曲的角度經紀人服務器端延遲

這一切都正常,但是當我有幾個遠程設備執行此操作時,我看到以下行爲 - Perspective Broker客戶端將發送所有請求到PB服務器。然後,PB服務器將逐個執行這些請求(這很好),但只有在它們全部完成之後它纔會返回任何結果。

下面是相關PB服務器端代碼:

class RMethods(pb.Root): 

    def remote_ssh(self, aDict): 

     self.login('SSH', aDict)  # Login to remote device 
     response = self.aSSH.retrieve() # Retrieve the config 
     self.aSSH.close() 

     return response 


if __name__ == "__main__": 
    reactor.listenTCP(1885, pb.PBServerFactory(RMethods())) 
    reactor.run() 

通過觀察各種系統級信息(tcpdump和netstat的),I見下面(假設所述遠程方法的5個調用):

從PB客戶

呼叫remote_ssh到PB服務器五個遠程設備發生在大約同一時間

self.login device 1 
    self.aSSH.retrieve() device 1 
    self.aSSH.close() device 1 

    self.login device 2 
    self.aSSH.retrieve() device 2 
    self.aSSH.close() device 2 

    ... 

    self.login device 5 
    self.aSSH.retrieve() device 5 
    self.aSSH.close() device 5 

    return results for all 5 devices 

我不理解爲什麼它會等待返回將R結果(即爲什麼它會等到device5完成之後才返回device1的結果)。

回答

5

發生這種情況是因爲在反應堆有機會運行之前無法發送響應。如果所有五個請求幾乎同時到達,那麼反應堆可能會醒來一次,同時注意到它們全部五個。它將全部五個派送到PB服務器。 remote_ssh方法將服務其中一個,阻止整個時間。完成後,答覆將(幾乎肯定)排隊。然後remote_ssh方法將服務下一個,並且該響應將排隊。等到所有請求都被處理完爲止。然後,反應堆將完成派遣最初的5個事件組並繼續下一步。當它繼續時,它會發現準備發送的數據並開始發送它。

換句話說,阻塞阻止反應堆運行,包括阻止反應堆發送準備發送的輸出。

您可以嘗試使用Twisted Conch作爲SSH客戶端,它可以讓您在不阻塞的情況下執行SSH工作,或者您可以嘗試在線程中使用現有的SSH代碼(假設它可以成爲線程安全的)或多個進程。

+0

我會評論你可以包括一個關於如何使用海螺的例子,當我想起你已經寫道:http://as.ynchrono.us/2011/03/twisted-conch-in-60-seconds.html – stderr

+0

即使有線程,我也沒有看到我能做到這一點(我一直在嘗試)。我遇到的根本問題是,我必須阻止等待SSH結果返回,但是一旦我阻止了主要的Perspective Broker remote_method,它就會使用remote_method阻止所有其他SSH連接的執行。 –

+0

爲什麼你必須阻止等待SSH結果回來?要麼通過在單獨的線程或進程中完成工作來避免阻塞,要麼通過使用非阻塞的Conch客戶端API來避免阻塞。 –