2014-04-28 6 views
14

Używam Boto do łączenia się z Amazon S3 w moim programie Python. Jestem w stanie otworzyć połączenie i przesłać pliki do zasobnika. Pomyślałem, że powinienem wtedy zamknąć połączenie, aby zwolnić zasoby, a co ważniejsze, aby uniknąć ryzyka związanego z bezpieczeństwem, pozostawiając otwarte połączenie. Zakładałem, że powinienem wywołać metodę close(). Ale przetestowałem to w następujący sposób: 1. Otwórz połączenie. 2. Zamknij połączenie. 3. Prześlij plik do wiadra.Jak zamknąć połączenie Boto S3?

Wyobraziłem, że krok 3 zakończy się niepowodzeniem, ale przesyłanie zadziałało! Więc co robi close()? Jeśli to naprawdę nie zamyka połączenia, co powinienem użyć zamiast close()? A może po prostu nie trzeba zamykać połączenia?

Szukałem odpowiedzi w Boto tutorial, Boto API reference i this StackOverflow post, ale bez powodzenia.

Dzięki za pomoc.

Odpowiedz

6

Twój krok 3 zadziałał, ponieważ boto ma kod, który automatycznie ponownie otworzy zamknięte połączenia i ponowi prośby o błędy. Niewiele można zyskać, ręcznie zamykając połączenia boto, ponieważ są to tylko połączenia HTTP i zostaną automatycznie zamknięte po kilku minutach bezczynności. Nie martwiłbym się, próbując je zamknąć.

2

Pod okładkami, boto używa httplib. Ta biblioteka kliencka obsługuje utrzymywanie aktywności HTTP 1.1, więc może i powinna pozostawić gniazdo otwarte, aby mogło wykonywać wiele żądań przez to samo połączenie.

connection.close() w rzeczywistości nie zamyka podstawowych gniazd. Zamiast tego usuwa odniesienie do puli bazowej połączeń httplib, co pozwala na ich uruchomienie na module do zbierania śmieci, i wtedy następuje faktyczne zamknięcie gniazda.

Oczywiście, można również pozwolić na uruchamianie śmieciarza, nie zachowując odniesienia do samego połączenia boto. Istnieją jednak zalety związane z wydajnością ponownego wykorzystania połączenia boto (zobacz np. Notatkę Keep-Alive powyżej).

Na szczęście w większości przypadków nie trzeba jawnie dzwonić pod numer connection.close(). Aby uzyskać więcej informacji na temat jednego przypadku, w którym musisz zadzwonić blisko, zobacz moją odpowiedź na the StackOverflow post, która jest połączona z pytaniem.

0

Istnieje co najmniej jeden przypadek, w którym pozostawienie otwartego połączenia może spowodować awarię. Powyższa odpowiedź doprowadziła mnie do rozwiązania. Poniżej, addUnverifiedEmail ma wkładkę DBS RDS DB. Tak więc połączenie boto3 jest nadal w zasięgu i aktywne, gdy próbuje się wstawić. To jest z mojej Lambdy (python).

boto3.client.sign_up(
       ClientId='xxxxxxxxxxxxxxxxxxxxxxxxxx', 
       Username=self._user['email'], 
       Password=self._user['password'], 
       UserAttributes=attributes 
) 
dbUserInstance.addUnverifiedEmail(self._user['email']) 

Spowodowało to (błąd 1205 przekroczony limit czasu blokady). Poniżej addUserToCognito tworzy połączenie boto3 i wypada poza zakresem przed wstawieniem.

self.addUserToCognito() 
dbUserInstance.addUnverifiedEmail(self._user['email']) 

Wkładka powiodła się po wprowadzeniu tej zmiany. Na szczęście addUnverifiedEmail było ostatnim wywołaniem funkcji w addUserToCognito, więc łatwo było je przenieść na zewnątrz. Inny, bardziej złożony kod może nie mieć tej samej zdolności. Tak więc client.close() nie zamykając połączenia i nie zamykając go może być całkiem dużą wadą.

Powiązane problemy