GAE/P存储SES连接和线程安全



我正在使用亚马逊的SES从我的Python谷歌应用程序引擎应用程序发送电子邮件。我想保存SES连接,而不是为我发送的每封电子邮件创建它。

对于一个多威胁的应用程序来说,这是一种合理的方法吗?:

SES = None
def send_email_AWS(sender, to_addresses, subject, body):
global SES
if not SES:
SES = SESConnection(aws_key, aws_secret)
[other code for sending the email]

我不太了解什么是破旧的,什么不是。

以下是一个可以帮助您的示例:http://blog.notdot.net/2011/10/Migrating-to-Python-2-7-part-1-Threadsafe

class SesConnection(object):
_SES = None
_aws_key = ....
_aws_secret = ....
_ses_lock = threading.Lock()
@classmethod
def get_ses(cls):
with cls._ses_lock:
if not cls._SES:
cls._SES = SESConnection(cls._aws_key, cls._aws_secret)  # or put the code here
return cls._SES

或者使用webapp2应用程序注册表:http://webapp-improved.appspot.com/guide/app.html#registry

从您的例子中,如果您只是将其读取为常量,则不会有任何问题。您的公共变量SES不是线程安全的。这意味着,例如,如果有许多用户向该全局写入,那么您将始终读取发生的最后一次写入,而不是每个实例。

想象线程就是人。不要想象你的全局变量是一个公共WC。线程保险箱有一个门(锁)。如果我们没有锁,其他人都会试图在另一把锁在里面的时候完成他的工作。

例如,我看到:

SES = NONE 

这意味着你的应用程序的每个实例都将重新设置SES全局变量。这不是一件好事。

global SES
if not SES:

然后第一个请求会将其再次设置为某个值。但这并不安全,因为同时一些其他请求可能会覆盖它。如果这不是问题,那也没关系。如果希望线程安全,那么您需要的是按照每个请求处理程序在本地创建它。

@voscousa的回答向您展示了一个很好的实现示例。看看

最新更新