PythonプログラムでBotoを使用してAmazon S3に接続しています。接続を開いてファイルをバケットにアップロードできます。接続を閉じてリソースを解放する必要があると考えましたさらに重要なことは、開いている接続がぶら下がることによるセキュリティリスクを回避することです。close()メソッドを呼び出す必要があると想定していましたが、次のようにテストしました:1.接続を開く2.接続を閉じる3.ファイルをアップロードするバケツに。
ステップ3は失敗すると思いましたが、アップロードは成功しました!ではclose()は何をするのでしょうか?それが実際に接続を閉じない場合は、close()の代わりに何を使用すればよいですか?または、接続を閉じる必要はありませんか?
Botoチュートリアル 、 Boto APIリファレンス 、および このStackOverflowの投稿 で答えを探しましたが、今のところうまくいきません。
ご協力いただきありがとうございます。
Botoには、閉じられた接続を自動的に再度開き、エラー時にリクエストを再試行するコードがあるため、ステップ3が機能しました。 boto接続は単なるHTTP接続であり、アイドル時間の数分後に自動的に閉じるため、手動でboto接続を閉じることによるメリットはほとんどありません。私はそれらを閉じようとすることを心配しません。
内部では、botoはhttplibを使用します。このクライアントライブラリはHTTP 1.1キープアライブをサポートしているため、ソケットを開いたままにして、同じ接続で複数の要求を実行できるようにする必要があります。
connection.close()
は、基礎となるソケットを実際には閉じません。代わりに、httplib接続の基になるプールへの参照を削除します。これにより、ガベージコレクターをそれらで実行できるようになります。このとき、実際のソケットが閉じます。
もちろん、boto接続自体への参照を保持しないことで、ガベージコレクターを実行させることもできます。ただし、boto接続の再利用にはパフォーマンス上のメリットがあります(たとえば、上記のキープアライブのメモを参照してください)。
幸い、ほとんどの場合、connection.close()
を明示的に呼び出す必要はありません。 closeを呼び出す必要がある1つのケースの詳細については、質問にリンクされている StackOverflowの投稿 に対する私の回答を参照してください。
この接続を開いたままにしておくと障害が発生する可能性があるインスタンスが少なくとも1つあります。上記の答えが私を解決に導きました。以下では、addUnverifiedEmailがAWS RDS DB挿入を実行します。そのため、挿入を試行するときにboto3接続はまだスコープ内にあり、アクティブです。これは私のLambda(python)からのものです。
boto3.client.sign_up(
ClientId='xxxxxxxxxxxxxxxxxxxxxxxxxx',
Username=self._user['email'],
Password=self._user['password'],
UserAttributes=attributes
)
dbUserInstance.addUnverifiedEmail(self._user['email'])
その結果、(エラー1205ロック待機タイムアウトを超えました)。以下では、addUserToCognitoがboto3接続を作成し、それが挿入前にスコープから外れます。
self.addUserToCognito()
dbUserInstance.addUnverifiedEmail(self._user['email'])
この変更を行った後、挿入は成功しました。幸い、私にとってaddUnverifiedEmailはaddUserToCognito内の最後の関数呼び出しだったので、外部に移動するのは簡単でした。その他の、より複雑なコードは、同じ機能を備えていない場合があります。そのため、client.close()が実際に接続を閉じずに閉じたままにすることは、かなり大きな欠陥になる可能性があります。