我正在编写一个 lambda 函数,每次用户将图像上传到 S3 时都会触发该函数。该函数的主要目的是压缩图像,也可能在此过程中对其进行重命名。实现这一点,函数是取新上传的图片,压缩,上传新压缩的图片,删除原文件:
@app.on_s3_event(bucket=settings.BUCKET_NAME, events=['s3:ObjectCreated:*'])
def compress(event):
# download the resource
s3.Bucket(settings.BUCKET_NAME).download_file(key, local_file_path)
# compress the image
...
# rename the file, if necessary (change extension, etc.)
...
# upload the new image
s3.Object(settings.BUCKET_NAME, output_path).put(Body=open(compressed_path, 'rb'))
# remove original image
s3.Object(settings.BUCKET_NAME, event.key).delete()
因此,如果我上传一个名为sample.png
S3 的图像,它会被压缩并重命名为sample.jpg
; 并且sample.png
之后会被删除。
然而,问题在于该解决方案将导致无限递归。原因是压缩图像的上传会再次调用lambda函数,从而导致再次下载,从而压缩已经压缩的图像,从而再次上传。无穷无尽。
我的一个朋友提出了两种可能的解决方案:通过将压缩图像的名称存储在单独的 S3 存储桶文件中的某个位置来缓存它们,并防止缓存的文件名被多次上传;并修改压缩图像的 exif/metada,以便 lambda 可以判断哪些文件已被压缩,指示该函数不应继续执行,这将防止再次发生压缩。
第一个想法很容易出现多个文件同时上传到服务器时可能出现的问题,至少从理论上讲。第二个想法可能需要第三方库,例如piexif,但这是我目前正在考虑的。
你有更好的方法来解决这个问题吗?还是我什至一开始就在做压缩的事情(除了递归上传和下载)?我的意思是,也许我可以压缩 S3 图像而无需执行下载-压缩-上传-删除例程。