Lambda Python Pool.map和urllib2.urlopen:仅重试失败的进程,仅记录错误

时间:2017-04-24 15:26:39

标签: python lambda urllib2

我有一个AWS Lambda函数,它使用{ test: /\.(gif|png|jpe?g|svg)$/i, use: [ 'file-loader', { loader: 'image-webpack-loader', options: { mozjpeg: { quality: 65, }, pngquant: { quality: '65-90', speed: 4, }, svgo: { plugins: [ { removeViewBox: false, }, { removeEmptyAttrs: false, }, ], } } } ] } 调用一组URL。问题是,如果其中一个URL返回除pool.map以外的任何内容,则Lambda函数将失败并立即重试。问题是它会立即重试整个lambda函数。我希望它只重试失败的URL,如果(经过第二次尝试)它仍然失败,请调用固定的URL来记录错误。

这是当前的代码(删除了一些详细信息),仅在所有网址都是:

时才有效
200

我尝试阅读the official documentation但似乎在解释from __future__ import print_function import urllib2 from multiprocessing.dummy import Pool as ThreadPool import hashlib import datetime import json print('Loading function') def lambda_handler(event, context): f = urllib2.urlopen("https://example.com/geturls/?action=something"); data = json.loads(f.read()); urls = []; for d in data: urls.append("https://"+d+".example.com/path/to/action"); # Make the Pool of workers pool = ThreadPool(4); # Open the urls in their own threads # and return the results results = pool.map(urllib2.urlopen, urls); #close the pool and wait for the work to finish pool.close(); return pool.join(); 函数方面缺乏一点,特别是解释了返回值。

使用urlopen文档我尝试将代码修改为以下内容:

map

我不确定以这种方式做异常是否正确,或者我是否正确地制作了python异常表示法。同样,我的目标是我希望它只重试失败的网址,如果(经过第二次尝试)它仍然失败,请调用固定的网址来记录错误。

1 个答案:

答案 0 :(得分:0)

感谢a "lower-level" look at this question I posted here,我想出了答案。

答案是为urllib2.urlopen函数创建我自己的自定义包装器,因为每个线程本身都需要 try {} catch 'd而不是整个事物。这个功能看起来像这样:

def my_urlopen(url):
    try:
        return urllib2.urlopen(url)
    except URLError:
        urllib2.urlopen("https://example.com/log_error/?url="+url)
        return None

我把它放在def lambda_handler函数声明之上,然后我可以用它替换整个try / catch:

try:
   results = pool.map(urllib2.urlopen, urls);
except URLError:
   try:                              # try once more before logging error
      urllib2.urlopen(URLError.url);
   except URLError:                  # log error
      urllib2.urlopen("https://example.com/error/?url="+URLError.url);

对此:

results = pool.map(my_urlopen, urls);

Q.E.D。