Skip to main content

A library providing a pool-like object for holding `AsyncContextManager` instances.

Project description

asyncio-contextmanager-pool

A library providing a pool-like object for holding AsyncContextManager instances.

Why?

Some objects, like MongoDB connections to a Replica Set, are expensive to create, time-wise. As a result, they are usually created once and then used across the entire application. This mitigates, or eliminates, the costs associated with creating and setting up such objects.

However, there are situations where one may need to dynamically create such objects. One such example would be a multi-tenant API that can talk to multiple instances.

One could use cachetools to hold the references, perhaps in a TTLCache, so that not "too many" instances are kept (especially when not used), but then they must also make sure that instances are cleaned up properly, sometimes with some leniency (TTL).

Features

  • Async Context Manager (async with) support to manage objects
  • Memoizes instances based on the arguments used to create them, which prevents duplicates and saves init time
  • Provides TTL support, so that objects are kept for a set period of time after not being used, which again helps preventing duplication

Usage

import asyncio
from asyncio_contextmanager_pool import Pool


class Example:
    """
    A dummy implementation of an AsyncContextManager
    that "knows" when it was used.
    """
    def __init__(self, message: str) -> None:
        self.message = message

        self.enter_called = 0
        self.exit_called = 0

    async def __aenter__(self):
        self.enter_called += 1
        return self

    async def __aexit__(self, *args, **kwargs):
        self.exit_called += 1


async with Pool(Example, ttl=5) as p:
    # Get an instance of Example
    async with p.get("hello, world") as inst_1:
        # Use it
        assert inst_1.message == "hello, world"

    # Here, under normal circumstances, `inst_1` is still alive
    assert inst_1.exit_called == 0

    # So, if I `get` it again...
    async with p.get("hello, world") as inst_2:
        # And use it...
        assert inst_2.message == "hello, world"
    
    # I will get the exact same object
    assert inst_1 is inst_2

    # Now, let's assume some time passes...
    await asyncio.sleep(10)

    # Here, inst_1 already expired, so inst_3
    # will be a new object...
    async with p.get("hello, world") as inst_3:
        assert inst_3.message == "hello, world"

    assert inst_1 is not inst_3
    assert inst_1.exit_called == 1

# And after the `async with` block, everything is cleaned:
assert inst_3.exit_called == 1

Notes

Pickle support

If a Pool instance is copied via Pickle (e.g., through multiprocessing.Process or a concurrent.futures.ProcessPoolExecutor), the instances are not copied.

This is by design, because:

  • Some objects should not be copied between processes (e.g., pymongo.MongoClient)
  • Object expiration uses asyncio's Timer functions, which are attached to the Event Loop. Event Loops cannot be shared between processes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asyncio-contextmanager-pool-0.1.1.tar.gz (5.1 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file asyncio-contextmanager-pool-0.1.1.tar.gz.

File metadata

  • Download URL: asyncio-contextmanager-pool-0.1.1.tar.gz
  • Upload date:
  • Size: 5.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.8 CPython/3.10.0 Linux/5.14.18-300.fc35.x86_64

File hashes

Hashes for asyncio-contextmanager-pool-0.1.1.tar.gz
Algorithm Hash digest
SHA256 174c896b796d1da256999bf4e3ae67660ccbe02b6ab21ac677ed4a98009d1621
MD5 218e0cf68e6b01b4b1c1d9cc141c0ee8
BLAKE2b-256 17e6059536c87d5113150052f7e09bc11428297fce258f864847a3c40d823ec9

See more details on using hashes here.

File details

Details for the file asyncio_contextmanager_pool-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for asyncio_contextmanager_pool-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1dd1498c8350f1d565c53704c8ac11b4cb9c73c92d111651e402e97dd4f9635a
MD5 e8c3747208f0932f4994f2655d1f84e1
BLAKE2b-256 853e6daf7ec9b3b617f8231e0ea312217dea82ee0493c17cb330aab5ee0a8a9b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page