gpt4 book ai didi

python - WSGI:使每个请求真正独一无二

转载 作者:太空宇宙 更新时间:2023-11-03 19:20:04 26 4
gpt4 key购买 nike

我目前正在熟悉 Python 中 Web 应用程序的 WSGI 规范。我设置 Apache(使用 mod-wsgi)来调用一个当前仅显示线程 ID 号的小应用程序,以尝试观察每个请求的唯一性:

import thread

def application(environ, start_response)
start_response('200 Ok', [('Content-type', 'text/plain')])
output = "current thread id: %s" % thread.get_ident()
return [output]

我很快注意到,过了一会儿,相同的线程被后续请求重用。

如果我的理解是正确的,为了让我的应用程序具有“特定于上下文的”变量,我需要使用类似于以下的方案来存储它们:

lock = thread.allocate_lock()
lock.acquire()
thread_id = get_ident()
threadsafe[thread_id]['user'] = request.username
lock.release()

然后我可以以类似的方式从应用程序的不同部分访问它们。在这种情况下,我唯一的保证是该值属于该特定线程。但是,使用同一线程的请求可能仍然会互相干扰(例如,请求访问先前请求的剩余值)。我的结论是,为了以真正独特的方式处理每个请求,除了“thread_id”之外,我还需要另一个 key 来区分使用同一线程的请求。

使用唯一的 key (例如 uuid),我可以做到这一点

lock.acquire()
uuid = uuid.uuid4()
thread_id = get_ident()
threadsafe[(thread_id, uuid)]['user'] = request.username
lock.release()

但这意味着我有办法以线程安全的方式检索 uuid 值,就像我稍后可以检索 thread_id 一样。

我得出的结论正确吗?如果是这样,我如何获得额外的 key ?

编辑

我突然想到我的问题是错误的二分法。我的观点是线程可以与其自身同时运行,而事实上这是不可能的。使用同一线程的请求必须串行运行。因此,我实际上可以使用 uuid 来避免使用线程的过时值,但只有在将其存储为线程保存值本身之后。

# somewhere early in the request
threadsafe[thread_id]['current_uuid'] = uuid.uuid4()

# later
lock.acquire()
thread_id = get_ident()
uuid = threadsafe[thread_id]['current_uuid']
threadsafe[(thread_id, uuid)]['user'] = request.username
lock.release()

最佳答案

此答案基于 @user590028 答案的评论中开发的新信息。

您说过您的目标是拥有线程安全的持久数据。因为您还说您正在熟悉 WSGI 规范,所以我觉得这个链接特别相关:Application_Global_Variables

...although global data can be used, it can only be used to cache data which can be safely reused within the context of that single process. You cannot use global data as a means of holding information that must be visible to any request handler no matter which process it runs in.

您的应用程序不仅可能在多个线程下运行,而且可能在多个进程下运行。根据上面的链接,持久数据的推荐解决方案(超出当前请求的数据)是使用外部存储解决方案(文件系统、数据库、memcached...)

更新

您尝试使用锁来保存状态信息的操作似乎完全没有必要。无论如何,每个请求都应被视为唯一。如果客户端用户向您的应用程序发出 10 个请求,并且您希望在这些请求中保留数据,那么您应该使用 session key (例如 cookie),当客户端的请求是新的(不包含 session )时,您首先向客户端建立该 session key ,然后您在响应中返回它,并期望将来的请求提供此 key 。随后,有一些库旨在为您提供此功能: http://www.ollycope.com/software/pesto/session.html

wsgi 应用程序有一个入口点,在这种情况下,您的示例将其定义为名为“应用程序”的函数。它也可能是一个类或任何可调用的东西。由于范围的原因,您的变量本质上是上下文特定的。无论您对该范围执行什么操作,都与运行同一处理程序的任何其他线程完全不同。 “应用程序”函数可能更复杂,调用其他函数并传递其变量,直到最终返回其响应主体。您还可以创建一个类实例,其中包含处理请求和生成响应所需的所有功能,并使用其自己的实例变量。

如果前两个建议都不适用于您所要求的内容,我认为剩下的唯一可能性是您确实希望将数据存储在数据库、文件系统、memcached 或 redis 等中。 uuid4 将是唯一的,但只有当您在响应中传递它并让客户端返回它以保持与该数据的关联时,它的值才有意义。

关于python - WSGI:使每个请求真正独一无二,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10049872/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com