存储和访问请求响应宽对象

问题描述:

我需要存储创建的/打开的LDAP连接,因此多个模型,视图等可以重复使用单个连接,而不是每次创建一个新连接。这个连接在请求期间首先需要时打开,在发送响应时关闭(完成生成页面)。连接不应该在不同的请求/响应之间共享。存储和访问请求响应宽对象

这样做的方法是什么?在哪里存储连接以及如何确保它最终关闭?

更多信息。作为附加信息来源,我使用LDAP连接。 LDAP数据包含我无法在数据库中存储的详细信息(冗余/一致性原因),例如MS Exchange邮件组。我可能需要多点LDAP数据,不同的对象/实例应该在响应生成过程中访问它。

存储连接资源以便可以在组件中共享的一种方法是使用thread local storage

例如,在myldap.py

import threading 
_local = theading.local() 

def get_ldap_connection(): 
    if not hasattr(_local, 'ldap_connection') or _local.ldap_connection is None: 
     _local.ldap_connection = create_ldap_connection() 

    return _local.ldap_connection 

def close_ldap_connection(): 
    if hasattr(_local, 'ldap_connection') and _local.ldap_connection is not None: 
     close_ldap_connection(_local.ldap_connection) 
     _local.ldap_connection = None 

所以第一次myldap.get_ldap_connection从特定线程就会打开连接调用。随后来自同一个线程的调用将重新使用该连接。

为确保连接在完成工作后关闭,您可以实施Django middleware component。除此之外,这将允许您指定一个被调用的钩子after the view has returned it's response object

中间件可以然后调用myldap.close_ldap_connection()这样的:

import myldap 

Class CloseLdapMiddleware(object): 
    def process_response(self, response): 
     myldap.close_ldap_connection() 
     return response 

最后,你将需要添加您的中间件在settings.pyMIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES = [ 
    ... 
    'path.to.CloseLdapMiddleWare', 
    ... 
] 
+0

好主意,我也没有想过用中间件: )然而,本地线程的使用不符合我们软件的概念,因此在接受之前我会再等一会儿。 – Art

+0

我知道使用线程本地(或其变体)的唯一选择是将信息存储在请求对象上。然而,这种方法的不足之处在于,您必须将请求对象传递给可能需要ldap连接的每个函数 - 根据您的确切需求和体系结构,这可能非常繁重。 –