2012-01-02 6 views
5

Ho utilizzato open_uri per trascinare un percorso ftp come origine dati per un po 'di tempo, ma all'improvviso ho scoperto che sto diventando quasi continuo "530 Scusa, il numero massimo di client consentiti (95) è già collegato."Fa 'open_uri' Ruby chiude correttamente le prese dopo la lettura o in caso di errore?

Non sono sicuro se il mio codice è difettoso o se è qualcun altro che sta accedendo al server e sfortunatamente non c'è modo per me di sembrare davvero sicuro di chi è in errore.

In sostanza io sto leggendo FTP URI con:

def self.read_uri(uri) 
    begin 
     uri = open(uri).read 
     uri == "Error" ? nil : uri 
    rescue OpenURI::HTTPError 
     nil 
    end 
    end 

Sto indovinando che ho bisogno di aggiungere un po 'che gestisce il codice qui errore aggiuntivo ... io voglio essere sicuro che prendo tutte le precauzioni per chiudere tutte le connessioni in modo che le mie connessioni non siano il problema in questione, tuttavia ho pensato che open_uri + read avrebbe preso questa precauzione contro usando i metodi Net :: FTP.

La linea di fondo è che devo essere sicuro al 100% che queste connessioni siano chiuse e non ho in qualche modo un mucchio di connessioni aperte in giro.

Qualcuno può consigliare di utilizzare correttamente read_uri per accedere a ftp con la garanzia che sta chiudendo la connessione? O dovrei spostare la logica su Net :: FTP che potrebbe dare più controllo sulla situazione se open_uri non è abbastanza robusto?

Se invece devo usare i metodi Net :: FTP, c'è un metodo di lettura che dovrei avere familiarità con vs tirarlo giù in una posizione tmp e quindi leggerlo (come preferirei mantenere se possibile in un buffer vs fs)?

+1

io non sono a conoscenza 'read_uri' e sto avendo un tempo sorprendentemente difficile trovare risultati di ricerca. Ti dispiace condividere uno snippet di codice che richiede e/o lo usa? –

+0

LOL, mi dispiace. Ho scritto questo codice alcuni mesi fa e ho dimenticato di aver definito read_uri come segue (rendendomi conto di aver aggiunto più gestione degli errori: http://j.mp/tNHpmr – ylluminate

+0

Supponendo che tu non abbia Windows probabilmente vedrai cosa sta succedendo da te con l'esecuzione di "netstat" nel prompt dei comandi – sunkencity

risposta

6

ho il sospetto che non si sta chiudendo le maniglie. OpenURI's docs iniziare con questo commento:

It is possible to open http/https/ftp URL as usual like opening a file: 

open("http://www.ruby-lang.org/") {|f| 
    f.each_line {|line| p line} 
} 

ho guardato la fonte e il metodo open_uri fa chiudere il flusso se si passa un blocco, quindi, modificando l'esempio precedente per adattare il codice:

uri = '' 
open("http://www.ruby-lang.org/") {|f| 
    uri = f.read 
} 

Dovresti avvicinarti a ciò che vuoi.


Ecco un modo per gestire le eccezioni:

# The list of URLs to pass in to check if one times out or is refused. 
urls = %w[ 
    http://www.ruby-lang.org/ 
    http://www2.ruby-lang.org/ 
] 

# the method 
def self.read_uri(urls) 

    content = '' 

    open(urls.shift) { |f| content = f.read } 
    content == "Error" ? nil : content 

    rescue OpenURI::HTTPError 
    retry if (urls.any?) 
    nil 
end 
+0

Ok, sì, credo che tu abbia ragione qui. Ho trovato la stessa cosa dopo aver frugato in giro. Grazie! Darò uno scatto e vedrò se le cose si calmano ora. – ylluminate

+0

Beh, bello sapere che non sono io adesso. Tuttavia sto ancora ricevendo gli errori di troppe connessioni. In questo caso, ho bisogno di cambiare marcia su un server di backup. Come aggiungeresti un gestore di eccezioni a questo, quindi se viene generato un errore, prova ad entrare in un altro URI? – ylluminate

+0

In questo caso, anche il TCP riserva una connessione per un periodo di tempo dopo che è stato chiuso, ma non ricordo per quanto tempo è in questo momento. Potresti richiedere troppi file all'interno di quella finestra, esaurendo il numero disponibile. –

4

provare a utilizzare un blocco:

data = open(uri){|f| f.read} 
+0

Sì, grazie. Il blocco sembra aver aiutato.Vorrei poter dividere le risposte in quanto non riesco a vedere chi ha pubblicato per primo esattamente, ma poiché l'altra risposta ha avuto qualche dettaglio in più, ho intenzione di andare avanti e assegnarlo come risposta. Ma grazie! – ylluminate

Problemi correlati