web-dev-qa-db-fra.com

Comment fermer la connexion Boto S3?

J'utilise Boto pour me connecter à Amazon S3 dans mon programme Python. Je suis en mesure d'ouvrir une connexion et de télécharger des fichiers dans un compartiment. Je me suis dit que je devrais alors fermer la connexion pour libérer des ressources et, plus important encore, pour éviter tout risque de sécurité en laissant une connexion ouverte traîner. J'ai supposé que je devrais appeler la méthode close (). Mais j'ai testé ceci comme suit: 1. Connexion ouverte. 2. Fermer la connexion. 3. Téléchargez le fichier dans le compartiment.

J'ai pensé que l'étape 3 échouerait, mais le téléchargement a fonctionné! Alors que fait close ()? Si cela ne ferme pas vraiment la connexion, que dois-je utiliser à la place de close ()? Ou est-il simplement inutile de fermer la connexion?

J'ai cherché la réponse dans le tutoriel Boto , la référence API Boto , et cet article StackOverflow , mais pas de chance jusqu'à présent.

Merci de votre aide.

20
Steve Saporta

Votre étape 3 a fonctionné parce que boto a un code qui rouvrira automatiquement les connexions fermées et réessayera les demandes d’erreurs. Il est inutile de fermer manuellement les connexions réseau, car il ne s’agit que de connexions HTTP et se fermeront automatiquement après quelques minutes d’inactivité. Je ne m'inquiéterais pas d'essayer de les fermer.

8
garnaat

Sous les couvertures, boto utilise httplib. Cette bibliothèque client prend en charge HTTP Keep-Alive HTTP 1.1. Elle peut donc et doit garder le socket ouvert afin qu'il puisse effectuer plusieurs requêtes sur la même connexion.

connection.close() ne ferme pas réellement les sockets sous-jacents. Au lieu de cela, il supprime la référence au pool sous-jacent de connexions httplib, ce qui permet au collecteur de mémoire de s'exécuter sur ces connexions, et c'est à ce moment-là que la fermeture du socket se produit.

De toute évidence, vous pouvez également laisser le ramasse-miettes s'exécuter en ne gardant pas une référence à la connexion boto elle-même. Cependant, la réutilisation de la connexion bidirectionnelle présente des avantages en termes de performances (voir par exemple la note Keep-Alive ci-dessus).

Heureusement, dans la plupart des cas, vous n'avez pas à appeler explicitement connection.close(). Pour plus de détails sur un cas où vous devez appeler à proximité, voir ma réponse à l'article StackOverflow qui est lié à la question.

2
jtoberon

Il existe au moins un cas où le fait de laisser cette connexion ouverte peut entraîner une défaillance. La réponse ci-dessus m'a amené à la solution. En dessous, addUnverifiedEmail effectue une insertion dans la base de données AWS RDS. Ainsi, la connexion à boto3 est toujours dans la portée et active lorsque vous essayez de faire l'insertion. Ceci est de mon Lambda (python).

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

Cela s'est traduit par (erreur 1205 Délai d'attente de verrouillage dépassé). En dessous, addUserToCognito crée la connexion boto3 et celle-ci sort de la portée avant l'insertion.

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

L'insertion a réussi après avoir effectué ce changement. Heureusement pour moi, addUnverifiedEmail était le dernier appel de fonction dans addUserToCognito, il était donc facile de le déplacer à l'extérieur. D'autres codes, plus complexes, peuvent ne pas avoir la même capacité. Ainsi, client.close () ne pas fermer la connexion et la garder fermée pourrait être un très gros défaut.

0
CPlusPlus Lover