2010-08-21 2 views
2

My Gae 애플리케이션은 제 3 자 사이트에서 JSON 데이터를 검색합니다. 다운로드 할 항목을 나타내는 ID가 주어지면이 사이트의 항목 데이터는 여러 페이지로 구성되어 있으므로 내 코드는 마지막 페이지의 데이터가 검색 될 때까지 페이지 이후 페이지의 데이터 청크를 다운로드해야합니다.
내 간단한 코드는 다음과 같습니다Google App Engine : TaskQueue 또는 Async Urlfetch를 사용하여 다운로드를 병렬 처리하는 방법?

class FetchData(webapp.RequestHandler): 
    def get(self): 
    ... 
    data_list = [] 
    page = 1 
    while True: 
     fetched_data= urlfetch.fetch('http://www.foo.com/getdata?id=xxx&result=JSON&page=%s' % page) 
     data_chunk = fetched_data["data"] 
     data_list = data_list + data_chunk 
     if len(data_list) == int(fetched_data["total_pages"]): 
     break 
     else: 
     page = page +1 
    ... 
    doRender('dataview.htm',{'data_list':data_list}) 

data_list 결과는 첫 번째 항목은 페이지 번호 1의 데이터가 정렬 된 목록입니다 마지막 항목이 최신 페이지의 데이터가; 이 data_list은 검색된 후보기로 렌더링됩니다.

이 접근 방식은 99 %의 시간 동안 작동하지만 때로는 30 초 Google App Engine에 의해 제한이 있기 때문에 많은 페이지가있는 항목에서 나는 두려워한 DeadlineExceededError을 얻습니다. 사용하는 경우 알고 싶습니다 TaskQueue | Deferred | AsyncUrlfetch N urlfetch 호출에서이 알고리즘을 병렬 처리하는 방법을 향상시킬 수 있습니다.

+0

이 솔루션은 아래 당신이 –

+0

이를 위해 밖으로 작동하는지 알려줘과 같이 간단하다 http://code.google.com/appengine/docs/python/urlfetch/asynchronousrequests.html

운이 좋았 니? –

답변

1

사용이 :이 함께 해결 한

def handle_result(rpc): 
    result = rpc.get_result() 
    # ... Do something with result... 

# Use a helper function to define the scope of the callback. 
def create_callback(rpc): 
    return lambda: handle_result(rpc) 

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

# ... 

# Finish all RPCs, and let callbacks process the results. 
for rpc in rpcs: 
    rpc.wait() 
+0

괜찮습니다. 위의 코드로 while 섹션을 바꾸고 필요한 경우 변경하십시오. 전역이 필요하지 않습니다. –

+1

비록 자세하게 설명하지는 않았지만 귀하의 대답은 비동기식 솔루션에 집중하는 데 도움이되었습니다. – systempuntoout

0

:

chunks_dict = {} 

def handle_result(rpc, page): 
    result = rpc.get_result() 
    chunks_dict[page] = result["data"] 

def create_callback(rpc, page): 
    return lambda: handle_result(rpc, page) 

rpcs = [] 
while True: 
    rpc = urlfetch.create_rpc(deadline = 10) 
    rpc.callback = create_callback(rpc, page) 
    urlfetch.make_fetch_call(rpc, 'http://www.foo.com/getdata?id=xxx&result=JSON&page=%s' % page) 
    rpcs.append(rpc) 
    if page > total_pages: 
     break 
    else: 
     page = page +1 
for rpc in rpcs: 
    rpc.wait() 

page_keys = chunks_dict.keys() 
page_keys.sort() 
for key in page_keys: 
    data_list= data_list + chunks_dict[key]