Google ドキュメントの特定のフォルダーにドキュメントをアップロードする Google App Engine アプリケーションを実装しました。1 か月前に、Google ドキュメントで特定のフォルダーをクエリするときに、応答時間の問題 (GdataClient.GetDocList、fetch-url 呼び出し、Gdata クライアントで期限を超えた) が発生し始めました。これにより、多くのタスクがタスク キューにキューアップされました。
これを見たとき、キューをしばらく一時停止しました-約24時間。キューを再起動すると、10 個のファイル/タスクを除いて、ほぼすべての場所が再びアップロードされました。
GetDocList 呼び出しを実装したとき、再試行/スリープ機能を実装して、.GetNextLink().href ループ中に発生する断続的な "DeadLineExceeded" を回避しました。これが良い「クラウド」設計ではないことはわかっています。しかし、生産に十分な安定性を得るために、これを行うことを余儀なくされました。スリープするたびに待機時間を延長し、5回だけ再試行します。前回、再試行する前に約 25 秒待機しました。
私が考えているのは、キュー内のすべてのタスクが何度も再試行されたということです (タスクを serial-mode で実行するように制限しましたが、一度に 1 つずつ、1 分間に最大 5 回)、App Engine アプリがブラックリストに登録されました。 Google ドキュメント API。
これは起こりえますか?
同じ App Engine インスタンスから Google Docs Api を再度クエリできるようにするには、どうすればよいですか?
App Engine アプリを新しいアプリケーション ID に移行する必要はありますか?
開発環境からこれを試すと、コードが機能し、フォルダー構造を照会して、制限時間内に結果を返します。
照会しているフォルダー構造はかなり大きいため、.GetNextLink().href を介して取得する必要があります。私の開発環境では、フォルダー構造に含まれるフォルダーははるかに少なくなっています。
とにかく、これは実稼働の AppEngine インスタンスで約 1 年間非常にうまく機能しています。しかし、3月4日から5日にかけて作業を停止しました。
照会されたユーザー・アカウントは、現在、使用可能な 205824 MB の 7000 MB (3%) を使用しています。
dev-env のコードを使用しても、Google Apps ドメイン / アプリ ID / Google アカウントがまったく異なる場合、エラーを再現できません。
max-results を (100 または 50 または 20 ではなく) 1 に変更すると、断続的に成功します。しかし、最大結果が 1 であるため、1000 回もクエリを実行する必要があります。連続して最大 3 回しか成功しないため、指数バックオフが終了するまで、結果セット全体を取得することはできません。結果セット (クエリを実行するフォルダーは、300 から 400 のフォルダーで構成されます (これは、pdf ファイルを含む少なくとも 2 から 6 のサブフォルダーで構成されます)
max-result 2 で試してみましたが、フェッチは毎回失敗します。max-result 1 に戻すと、1 つまたは 2 つのフェッチが連続して成功しますが、これでは十分ではありません。ファイルを保存する正しいフォルダーを見つけるには、フォルダー構造全体が必要なので。
ローカル環境から、つまり完全に異なる IP アドレスからこれを試しましたが、それでも失敗します。これは、アプリ エンジン アプリが Google ドキュメントへのアクセスをブロックされていないことを意味します。max-result が 2 から 1 に変更されたことも、それを証明しています。
結論: Google Docs API からの戻り時間が遅いのは、ループしているコレクション内の膨大な量のファイルとコレクションが原因であるに違いありません。このコレクションには約 3500 MB が含まれていることに注意してください。これは問題ですか?
ログ: DocListUrl からエントリを取得する = https://docs.google.com/feeds/default/private/full/folder:XXXXXXX/contents?max-results=1 .
RetryGetDocList を再試行し、1 秒待ちます。
RetryGetDocList を再試行し、1 秒待ちます。
RetryGetDocList を再試行し、4 秒間待ちます。
RetryGetDocList を再試行し、9 秒間待ちます。
RetryGetDocList を再試行し、16 秒待ちます。
RetryGetDocList を再試行し、25 秒間待ちます。
ApplicationError: 5
トレースバック (最新の呼び出しは最後): ファイル "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py"、703 行目、呼び出し中
handler.post(*groups) ファイル "/base/data/home/apps/XXXX/prod-43.358023265943651014/DocsHandler.py"、418 行目、投稿成功 = uploader.Upload(blob_reader、fileToUpload.uploadSize、fileToUpload.MainFolder、 fileToUpload.ruleTypeReadableId、fileToUpload.rootFolderId、fileToUpload.salesforceLink、fileToUpload.rootFolder、fileToUpload.type_folder_name、fileToUpload.file_name、currentUser、client、logObj) ファイル "/base/data/home/apps/XXXX/prod-43.358023265943651014/DocsClasses.py "、アップロード コレクションの 404 行目 = GetAllEntries('https://docs.google.com/feeds/default/private/full/%s/contents?max-results=1' % (ruleTypeFolderResourceId), client) File" /base/data/home/apps/XXXX/prod-43.358023265943651014/DocsClasses.py"、351 行目、GetAllEntries チャンク = RetryGetDocList(client.GetDocList , chunk.GetNextLink().href) ファイル "/base/data/home/apps/XXX/prod-43.358023265943651014/DocsClasses.py"、202 行目、RetryGetDocList で functionCall(uri) ファイルを返す "/base/data/home/apps/XXX /prod-43.358023265943651014/gdata/docs/client.py"、142 行目、get_doclist auth_token=auth_token、**kwargs 内) ファイル "/base/data/home/apps/XXXX/prod-43.358023265943651014/gdata/client.py" 、635 行目、get_feed **kwargs 内) ファイル "/base/data/home/apps/XXXXX/prod-43.358023265943651014/gdata/client.py"、265 行目、リクエスト uri=uri、auth_token=auth_token、http_request=http_request , **kwargs) ファイル "/base/data/home/apps/XXXX/prod-43.358023265943651014/atom/client.py"、117 行目、リクエストで self.http_client.request(http_request) ファイル "/base/data/ホーム/アプリ/XXXXX/prod-43.358023265943651014/atom/http_core.py」、420 行目、リクエスト http_request.headers、http_request._body_parts) ファイル「/base/data/home/apps/XXXXX/prod-43.358023265943651014/atom/http_core.py」、497 行目_http_request return connection.getresponse() ファイル "/base/python_runtime/python_dist/lib/python2.5/httplib.py" の 206 行目、getresponse 内の delay=self.timeout) ファイル "/base/python_runtime/python_lib/versions/1 /google/appengine/api/urlfetch.py"、263 行目、フェッチで rpc.get_result() ファイルを返す "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py"、592 行目、 get_result で self.__get_result_hook(self) を返す358023265943651014/atom/http_core.py」、497 行目、_http_request return connection.getresponse() ファイル「/base/python_runtime/python_dist/lib/python2.5/httplib.py」、206 行目、getresponse デッドライン = self.timeout ) ファイル "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py"、263 行目、フェッチで rpc.get_result() ファイル "/base/python_runtime/python_lib/versions/1/google /appengine/api/apiproxy_stub_map.py"、592 行目、get_result で self.__get_result_hook(self) を返す358023265943651014/atom/http_core.py」、497 行目、_http_request return connection.getresponse() ファイル「/base/python_runtime/python_dist/lib/python2.5/httplib.py」、206 行目、getresponse デッドライン = self.timeout ) ファイル "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py"、263 行目、フェッチで rpc.get_result() ファイル "/base/python_runtime/python_lib/versions/1/google /appengine/api/apiproxy_stub_map.py"、592 行目、get_result で self.__get_result_hook(self) を返す/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py"、263 行目、フェッチで rpc.get_result() ファイルを返す "/base/python_runtime/python_lib/versions/1/google/appengine/ api/apiproxy_stub_map.py"、592 行目、get_result で self.__get_result_hook(self) を返す/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py"、263 行目、フェッチで rpc.get_result() ファイルを返す "/base/python_runtime/python_lib/versions/1/google/appengine/ api/apiproxy_stub_map.py"、592 行目、get_result で self.__get_result_hook(self) を返す
ファイル "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py"、371 行目、_get_fetch_result で DeadlineExceededError(str(err)) DeadlineExceededError: ApplicationError: 5 を発生させます。
よろしく/イェンス