1

4 ~ 5 回の URL フェッチを実行し、データを結合してから応答に出力する必要がある Google AppEngine(in ) アプリケーションがあります。Python

同期ワークフローを使用して問題なくこれを行うことができますが、フェッチしている URL は相互に関連または依存していないため、これを非同期で実行するのが最も理想的 (かつ最速) です。

ドキュメントhereを読んで読み直しましたが、各 URL の内容を読み取る方法がわかりません。また、Web で小さな例を検索しました (これは、私が本当に必要としているものです)。私はこのSO の質問を見てきましたが、ここでも、これらの個々の非同期 URL フェッチの内容を読み取ることについては何も言及していません。

AppEngine で 4 つまたは 5 つの非同期 URL フェッチを実行する方法の簡単な例はありますか? そして、応答に出力する前に結果を結合しますか?

これが私がこれまでに持っているものです:

rpcs = []
for album in result_object['data']:
  total_facebook_photo_count = total_facebook_photo_count + album['count']
  facebook_albumid_array.append(album['id'])

  #Get the photos in the photo album
  facebook_photos_url = 'https://graph.facebook.com/%s/photos?access_token=%s&limit=1000' % (album['id'], access_token)

  rpc = urlfetch.create_rpc()
  urlfetch.make_fetch_call(rpc, facebook_photos_url)
  rpcs.append(rpc)

for rpc in rpcs:
  result = rpc.get_result()
  self.response.out.write(result.content)

ただし、まだ次の行のように見えます: result = rpc.get_result() は、最初のリクエストが終了するのを強制的に待機させ、次に 2 番目、3 番目と続きます。受け取った結果を単純に変数に入れる方法はありますか?

ありがとう!

4

2 に答える 2

2

では、text = result.contentコンテンツ (本文) を取得する場所です。

URL フェッチを並行して行うには、それらを設定し、リストに追加して、後で結果を確認することができます。前述の例を拡張すると、次のようになります。

from google.appengine.api import urlfetch

futures = []
for url in urls:
    rpc = urlfetch.create_rpc()
    urlfetch.make_fetch_call(rpc, url)
    futures.append(rpc)

contents = []
for rpc in futures:
    try:
        result = rpc.get_result()
        if result.status_code == 200:
            contents.append(result.content)
            # ...
    except urlfetch.DownloadError:
        # Request timed out or failed.
        # ...

concatenated_result = '\n'.join(contents)

この例では、ステータス コード 200 を返したすべてのリクエストのボディを組み立て、それらの間を改行で連結します。

または、ndbを使用すると、GAE での非同期処理に対する私の個人的な好みは次のようになります。

@ndb.tasklet
def get_urls(urls):
  ctx = ndb.get_context()
  result = yield map(ctx.urlfetch, urls)
  contents = [r.content for r in result if r.status_code==200]
  raise ndb.Return('\n'.join(contents))
于 2013-02-18T20:25:53.403 に答える
1

私はこのコードを使用します(ndbタスクレットについて学ぶ前に実装されています):

    while rpcs:
      rpc = UserRPC.wait_any(rpcs)
      result = rpc.get_result()
      # process result here
      rpcs.remove(rpc)
于 2013-02-21T17:11:09.263 に答える