无显式锁的,可选暴增的高吞吐量池
项目描述
asyncio-connection-pool
这是一个通用的、高吞吐量、可选暴增的asyncio池。
一些酷炫的功能
- 无锁[^1]; 不需要获取
asyncio.Lock
或asyncio.Condition
就可以获得连接。 - 在无需让出事件循环的情况下检索可用连接。
- 当指定了
burst_limit
时,max_size
起到一个“软”限制的作用;池可以超过这个限制来处理增加的负载,之后会缩小回来。 - 池的内容可以是任何东西;只需实现一个
ConnectionStrategy
。
[^1]: 从理论上讲,在asyncio任务执行期间,存在一个隐式的“锁”。除非当前任务让出(因为它是协作式多任务),否则其他任务不能执行,因此在那个时间段内的任何操作都是原子的。
为什么?
我们之前使用不同的池来处理Redis连接,并注意到在重负载下,我们会花费很多时间等待锁,即使池中还有可用的连接。
我们还认为,如果不需要一直保持很多连接打开,但在需要时仍然能够创建更多连接,那会很好。
API
asyncio_connection_pool.ConnectionPool
这是池的实现。它是一个通用的连接类型,所有实现特定的逻辑都包含在一个 ConnectionStrategy
中。
创建连接池的步骤如下
from asyncio_connection_pool import ConnectionPool
pool = ConnectionPool(strategy=my_strategy, max_size=15)
构造函数可以可选地传入一个整数作为 burst_limit
。这允许连接池在临时情况下打开比 max_size
更多的连接。
@asynccontextmanager async def get_connection(self) -> AsyncIterator[Conn]
此方法是获取连接池中连接的唯一方式。它通常如下使用
pool = ConnectionPool(...)
async with pool.get_connection() as conn:
# Use the connection
pass
当进入 async with
块时,会检索一个连接。如果需要打开连接或连接池已满且没有可用连接,调用者将交出事件循环。
当退出块时,连接将返回到连接池。
asyncio_connection_pool.ConnectionStrategy
这是一个抽象类,它定义了作为 strategy
传入的对象的接口。一个子类 必须 实现以下方法
async def create_connection(self) -> Awaitable[Conn]
当请求连接且所有连接都在使用时,此方法被调用以创建到资源的新的连接。只要连接池未满,就会发生这种情况。
此方法的调用结果将提供给连接池的消费者,并在大多数情况下将存储在池中以供以后重用。
如果此方法抛出异常,它将冒泡到调用 ConnectionPool.get_connection()
的框架。
def connection_is_closed(self, conn: Conn) -> bool
此方法用于检查连接是否不能再使用。当连接池检索连接以提供给客户端时,此方法被调用以确保其有效性。
如果连接无效,则返回值应为 True
。
如果此方法抛出异常,则假定连接无效。传入的连接将被丢弃并检索新的连接。除非异常不是 BaseException
,如 asyncio.CancelledError
,否则会抑制异常。避免在这种情况下泄露连接是 ConnectionStrategy
实现的责任。
async def close_connection(self, conn: Conn)
当连接池超出 max_size
(即正在膨胀)且返回不再需要的连接(即没有更多消费者等待连接)时,此方法被调用以关闭连接。
如果此方法抛出异常,则假定连接已关闭,异常将冒泡到 ConnectionPool.get_connection().__aexit__
的调用者(通常是 async with
块)。
与第三方库的集成
此软件包包括对 ddtrace
/datadog
和 aioredis
(<2.0.0) 的支持。
asyncio_connection_pool.contrib.datadog.ConnectionPool
此类继承了包根目录中的 ConnectionPool
,并添加了大量跟踪、仪表和事件。构造函数除了基类的参数外,还支持
- 必需的
service_name
参数:所有指标的前缀 - 可选的
extra_tags
参数:提供给所有指标的其他标签(格式为"key:value"
的字符串)
asyncio_connection_pool.contrib.aioredis.RedisConnectionStrategy
此类实现了 ConnectionStrategy
抽象方法,使用 aioredis.Redis
对象作为连接。构造函数接受任意参数并将它们转发给 aioredis.create_redis
。
没有锁,这如何保证安全?
我鼓励您阅读源代码以了解情况(它注释得相当好)。如果您发现任何逻辑错误,请随时提交问题。
项目详情
下载文件
下载您平台对应的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
构建分发
asyncio_connection_pool-1.0.0.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | bb0bef7602d09b8db46ee571bab2606d8e62d1a67d6edfcaf5af63792dd29d5d |
|
MD5 | ddb041117dc8b67c0928ccb5467ea578 |
|
BLAKE2b-256 | 134e3fccd51feadbfd1412d53b54cbded18d1bdd1a31c9ab27b678a9bfcabc1b |
asyncio_connection_pool-1.0.0-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2a238cf9de6d022ed76536599f4477bf8d84209e4a90063ca3b5a35ea52271a9 |
|
MD5 | e31fb90c5cea346e13743815e8933c0d |
|
BLAKE2b-256 | a8a40aab1e2f726b0218376c986232022212065e33e482658ad643ff4276fecd |