跳转到主要内容

Python的通用代理和池类

项目描述

代理模式池

Python的通用代理和池类。

Status Tests Coverage Issues Python Version Badges License

此模块提供了两个类

  • Proxy实现了代理模式,即代理上的所有方法调用都转发到内部包装的对象。这允许解决Python模块的经典鸡生蛋导入和初始化可能存在的循环依赖问题

    # File "database.py"
    db = Proxy()
    
    def init_app(config):
        db.set_obj(initialization from config)
    
    # File "app.py"
    import database
    from database import db  # db is a proxy to nothing
    
    # delayed initialization
    database.init_app(config)
    
    # db is now a proxy to the initialized object
    
  • Pool实现了一个线程安全的对象池,可用于存储创建成本高昂的对象,例如数据库连接。上面的代理对象根据其参数自动创建池。

    使用完毕后,请调用db._ret_obj()将对象返回到池中。

文档

Proxy类管理对一个或多个对象的访问,可能使用Pool,具体取决于这些对象的预期范围。

Proxy构造函数期望以下参数

  • obj 一个在所有线程之间共享的单个对象。
  • fun 一个函数,每次需要时调用对象创建,用于THREADVERSATILE范围。
  • scope 对象范围,由Proxy.Scope定义
    • SHARED 一个共享对象(进程级别)
    • THREAD 每个线程一个对象(threading实现)
    • WERKZEUG 每个greenlet一个对象(werkzeug实现)
    • EVENTLET 每个greenlet一个对象(eventlet实现)
    • GEVENT 每个greenlet一个对象(gevent实现)
    • VERSATILE 等同于 WERKZEUG,默认是 SHAREDTHREAD,取决于是否为对象传递了函数对象。
  • set_name 设置代理内容的函数名称,默认是 set。此参数允许避免与代理方法冲突。它用作前缀,以拥有 set_objset_fun 函数,这些函数允许重置内部的 objfun
  • log_level 设置日志级别,默认 None 表示不设置。
  • max_size 池的大小,默认 None 表示没有池。
  • max_size 和其他所有参数都转发到 Pool

max_size 不是 None 时,创建一个 Pool 来存储创建的对象以便重用。当不再需要对象时,通过显式调用 _ret_obj 来返回对象是用户的责任。这对于不断创建新线程的代码很有用,例如 werkzeug。对于数据库连接,在 commit 之后进行操作是一个很好的时间点。

代理有一个 _has_obj 方法来测试对象是否可用,而无需从池中提取任何内容:这在某些错误处理模式中测试是否需要返回对象时很有用。

Pool 类以线程安全的方式管理对象池。其构造函数期望以下参数

  • fun 创建新对象的方式;函数传递创建编号。
  • max_size 池的最大大小,0 表示无限。
  • min_size 池的最小大小。
  • timeout 等待某物的最大时间。
  • max_use 使用多少次后丢弃对象。
  • max_avail_delay 何时丢弃未使用的对象。
  • max_using_delay 何时警告长时间保留对象。
  • max_using_delay_kill 何时杀死长时间保留的对象。
  • health_freq 在每个守护进程回合中运行健康检查。
  • hk_delay 强制清理延迟。
  • log_level 设置日志级别,默认 None 表示不设置。
  • opener 在创建对象时调用的函数,默认 None 表示不调用。
  • getter 在获取对象时调用的函数,默认 None 表示不调用。
  • retter 在返回对象时调用的函数,默认 None 表示不调用。
  • closer 在丢弃对象时调用的函数,默认 None 表示不调用。
  • stats 生成用于统计的 JSON 兼容结构的函数。
  • health 检查可用对象健康的函数。
  • tracer 对象调试辅助工具,默认 None 表示更少的调试。

根据需要通过调用 fun 来按需创建对象。

代理示例

以下是一个具有蓝图和共享资源的 flask 应用的示例。

首先,一个共享模块持有对一个尚不知道的对象的代理

# file "Shared.py"
from ProxyPatternPool import Proxy
stuff = Proxy()
def init_app(s):
    stuff.set_obj(s)

此共享对象被具有蓝图的模块使用

# file "SubStuff.py"
from Flask import Blueprint
from Shared import stuff
sub = Blueprint()

@sub.get("/stuff")
def get_stuff():
    return str(stuff), 200

然后,应用程序本身可以按任何顺序加载和初始化这两个模块,而不会存在某些未初始化的导入风险

# file "App.py"
from flask import Flask
app = Flask("stuff")

from SubStuff import sub
app.register_blueprint(sub, url_prefix="/sub")

import Shared
Shared.init_app("hello world!")

注意

此模块是修辞性的:由于 GIL,Python 在并行语言方面相当糟糕,因此创建将主要无法并行运行的线程的目的毫无意义,因此这些线程共享的智能池的目的甚至更加无意义!

共享对象 必须 返回到池中,以避免耗尽资源。这可能需要来自基础设施的一些积极合作,这可能或可能不可靠。考虑监控您的资源以检测意外状态,例如数据库连接保持 事务空闲 状态等。

另请参阅

许可证

此代码属于公有领域

所有软件都有bug,这是软件,所以……小心,你可能会因此失去头发或朋友。如果你喜欢它,请随时给作者寄张明信片。

版本

源代码、文档问题托管在GitHub上。从PyPI安装软件包。查看版本详情

项目详情


下载文件

下载适用于您平台的文件。如果您不确定该选择哪个,请了解有关安装包的更多信息。

源代码分发

proxypatternpool-11.1.tar.gz (15.7 kB 查看哈希值)

上传时间 源代码

构建分发

ProxyPatternPool-11.1-py3-none-any.whl (13.0 kB 查看哈希值)

上传时间 Python 3

由以下支持