2014-01-15 1 views
1

내 목표 움직이지 않는 이유 :ThreadPool이가 TimeoutError 후 다음

  • 는 요청을 사용하여 확인하는 웹 사이트 목록을 통해 이동을. 이것은 apply_job에서 이루어집니다.

내 문제 : job_pool.next가 호출되면, 몇 웹 사이트에 오류가있는 대신 오류를주는, 그들은 단지 거기 서서, 심지어 TimeoutError를 제공하지 않습니다

  • . 그래서 next 함수에서 10 초의 타임 아웃을 사용하고 있습니다. 이 시간 초과는 잘 작동하지만 TimeoutError 예외가 발생하면 next은 다음 웹 사이트가 양호하더라도 다음 시간 동안 계속 예외를 발생시킵니다. 그것은 다음 항목으로 이동하지 않고 동일한 루프를 반복하는 것 같습니다.
  • imapimap_unordered으로 시도했지만 그 차이는 없습니다. 여기

내 코드 :

def run_check(websites): 
     """ Run check on the given websites """ 
     import multiprocessing 
     from multiprocessing.pool import ThreadPool 

     pool = ThreadPool(processes=JOB_POOL_SIZE) 

     try: 
      job_pool = pool.imap_unordered(apply_job, websites) 

      try: 
       while True: 
        try: 
         res = job_pool.next(10) 
        except multiprocessing.TimeoutError: 
         logging.error("Timeout Error") 
         res = 'No Res' 

        csv_callback(res) 

      except StopIteration: 
       pass 

      pool.terminate() 
     except Exception, e: 
      logging.error("Run_check Error: %s"%e) 
      raise 

나는 웹 사이트를 확인하는 res = requests.get(url, timeout=10)를 사용합니다. 이 시간 초과는이 문제에 대해 작동하지 않습니다.

테스트하려면 다음과 같이 문제를 만드는 웹 사이트 (매번이 아닌 매우 자주) : http://www.kddecorators.netfirms.com, http://www.railcar.netfirms.com.

이 웹 사이트와 다른 점을 알 수는 없지만 사용하지 못하더라도 실시간으로 간주되지 않으므로 잠시 동안 바이트를 계속 보내고 있습니다.

누구나 아이디어가 있다면 크게 환영 할 것입니다. 지금은 며칠 동안 저것에 매달 렸습니다. 심지어 futureasync을 시도했지만 필요한 예외를 발생시키지 않았습니다.

고마워요!

답변

0

내 문제의 해결책을 찾았습니다. eventlet과 그 Timeout 기능을 사용했습니다.

def apply_job(account_info): 
    """ Job for the Thread """ 
    try: 
     account_id = account_info['id'] 
     account_website = account_info['website'] 
     url = account_website 
     result = "ERROR: GreenPool Timeout" 
     with Timeout(TIMEOUT*2, False): 
      url, result = tpool.execute(website.try_url, account_website) 

     return (account_id, account_website, url, result) 

    except Exception, e: 
     logging.error("Apply_job Error: %s"%e) 

def start_db(res): 
    update_db(res) 
    csv_file.csv_callback(res) 

def spawn_callback(result): 
    res = result.wait() 
    tpool.execute(start_db, res) 

def run_check(websites): 
    """ Run check on the given websites """ 
    print str(len(websites)) + " items found\n" 

    pool = eventlet.GreenPool(100) 
    for i, account_website in enumerate(websites): 
     res = pool.spawn(apply_job, account_website) 
     res.link(spawn_callback) 

    pool.waitall() 

이 솔루션은 명령 url, result = tpool.execute(website.try_url, account_website)에서 함수 website.try_url의 전체 실행을 통해 잘 때문에 번 아웃 작동합니다.

0

시간 제한을 next으로 전달하면 직관력이 올바르지 않습니다. 대기를 중단하지만 특정 작업은 계속 실행됩니다. 다음에 기다리면 같은 일을 기다리게됩니다. 실제 작업 시간을 초과하려면 을 봐야합니다. 다른 스레드를 종료 할 수있는 확실한 방법은 없습니다. 따라서 합리적인 시간 내에 작업을 종료 할 수없는 경우 프로세스 기반 풀로 전환하고 프로세스를 강제 종료하십시오 (예 : signal.alarm 사용).

관련 문제