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

时间:2012-12-15 20:20:32

标签: python google-app-engine amazon-web-services thread-safety

我正在使用亚马逊的SES从我的Python Google App Engine应用程序发送电子邮件。我想保存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]

我对什么是线程安全和什么不是什么没有很好的理解。

2 个答案:

答案 0 :(得分:3)

以下示例可以帮助您: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 app注册表:http://webapp-improved.appspot.com/guide/app.html#registry

答案 1 :(得分:1)

从您的示例中您没有任何问题如果您只是正在阅读,就像它是一个常量一样。 您的公共变量SES不是线程安全的。这意味着,例如,如果有许多用户写入该全局,那么您将始终读取发生的最后一次写入而不是每个实例。

线程是人的图像。不要以为您的全局变量是公共WC。线程安全有门(锁)。如果我们没有锁定,那么每个人都会尝试做他的工作而另一个人在里面。

对于你的例子,我看到:

SES = NONE 

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

global SES
    if not SES:

然后第一个请求会再次设置它。但它不安全,因为同时其他一些请求可能会覆盖它。如果那不是问题,那就好了。 你需要的是每个请求处理程序在本地创建它,如果这是为了线程安全。

@voscausa的回答显示了一个很好的实现示例。看看