2013-05-22 21 views
6

Mój program python użyć httplib2.Http do żądania http. Kiedy muszę wygenerować żądanie, tworzę obiekt httplib2.Http, aby mój program często tworzył/niszczył obiekty httplib2.Http.Jest to błąd httplib2

Znalazłem, że mój program łatwo się zawiesił z powodu osiągnięcia maksymalnej liczby otwartych plików. Sprawdzanie/proc // fd, było zbyt wiele otwartych gniazd fds. Problem sprawił, że musiałam przekopać się na kod źródłowy httplib2.

Potem stwierdził, że w httplib2.Http._conn_request metody, nie było kodu tak:

 else: 
      content = "" 
      if method == "HEAD": 
       conn.close() 
      else: 
       content = response.read() 
      response = Response(response) 
      if method != "HEAD": 
       content = _decompressContent(response, content) 
     break 

To pokazuje, że gniazdo jest zamknięty tylko wtedy, gdy jest metoda HTTP HEAD. Może httplib2 chciał jakoś ponownie wykorzystać gniazdo. Ale klasa Http nie ma metody close(). Oznacza to, że gdy wykonuję żądanie HTTP, gniazdo nie zostanie zamknięte, dopóki mój proces nie zostanie zakończony.

Potem zmodyfikował kod:

 else: 
      content = "" 
      if method == "HEAD": 
       conn.close() 
      else: 
       content = response.read() 
      response = Response(response) 
      if method != "HEAD": 
       content = _decompressContent(response, content) 
       conn.close() # I ADD THIS CLOSE 
     break 

Po tym, mój program działa dobrze.

Ale nadal jestem ciekawy, czy to naprawdę błąd httplib2, biorąc pod uwagę, że httplib2 jest bardzo starą i powszechną biblioteką.

Odpowiedz

6

Nie, fakt, że połączenia nie są zamknięte, nie jest błędem, konieczne jest ponowne użycie połączenia dla następnego żądania.

Zapisano sposób, w jaki czeka, aż serwer zamknie połączenie lub upłynie limit czasu, nie aktywnie je zamyka (execept on errors). Jeśli połączenie zostanie zamknięte, będzie po prostu próbowało przywrócić je przy następnym użyciu.

Zamknięcie połączenia (tak jak poprawka do źródła) uniemożliwiłoby to, każde żądanie musiałoby użyć własnego połączenia.

Zniszczenie obiektu httplib2.Http powinien automatycznie zamknąć otwarte połączenia, ponieważ odnoszą się tylko w to connections słownik, więc jeśli nie prowadzą żadnych odniesień do utworzonych powinno działać na Http obiektów. Czy na pewno nie masz żadnych referencji?

Ewentualnie można przekazać Connnection: close nagłówka żądania:

http.request("http://example.org", headers={'Connection': 'close'}) 

To powinno spowodować, że serweraby zamknąć połączenie po każdym żądaniu. Możesz też spróbować ręcznie zamknąć wszystkie połączenia w dyktafonie obiektu connections.

Powiązane problemy