Allocate an event per context
parent
26cb7aa660
commit
4527d4a677
|
@ -31,13 +31,11 @@ from typing import (
|
||||||
)
|
)
|
||||||
from contextlib import (
|
from contextlib import (
|
||||||
asynccontextmanager,
|
asynccontextmanager,
|
||||||
AsyncExitStack,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
import trio
|
import trio
|
||||||
from trio_typing import TaskStatus
|
from trio_typing import TaskStatus
|
||||||
import tractor
|
import tractor
|
||||||
from tractor._portal import maybe_open_nursery
|
|
||||||
|
|
||||||
from .brokers import get_brokermod
|
from .brokers import get_brokermod
|
||||||
from .log import get_logger
|
from .log import get_logger
|
||||||
|
@ -86,8 +84,11 @@ class cache:
|
||||||
'''
|
'''
|
||||||
lock = trio.Lock()
|
lock = trio.Lock()
|
||||||
users: int = 0
|
users: int = 0
|
||||||
values: dict[tuple[str, str], tuple[AsyncExitStack, Any]] = {}
|
values: dict[Any, Any] = {}
|
||||||
nurseries: dict[int, Optional[trio.Nursery]] = {}
|
resources: dict[
|
||||||
|
int,
|
||||||
|
Optional[tuple[trio.Nursery, trio.Event]]
|
||||||
|
] = {}
|
||||||
no_more_users: Optional[trio.Event] = None
|
no_more_users: Optional[trio.Event] = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -100,15 +101,15 @@ class cache:
|
||||||
) -> None:
|
) -> None:
|
||||||
async with mng as value:
|
async with mng as value:
|
||||||
|
|
||||||
cls.no_more_users = trio.Event()
|
_, no_more_users = cls.resources[id(mng)]
|
||||||
cls.values[key] = value
|
cls.values[key] = value
|
||||||
task_status.started(value)
|
task_status.started(value)
|
||||||
try:
|
try:
|
||||||
await cls.no_more_users.wait()
|
await no_more_users.wait()
|
||||||
finally:
|
finally:
|
||||||
value = cls.values.pop(key)
|
value = cls.values.pop(key)
|
||||||
# discard nursery ref so it won't be re-used (an error)
|
# discard nursery ref so it won't be re-used (an error)
|
||||||
cls.nurseries.pop(id(mng))
|
cls.resources.pop(id(mng))
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
|
@ -128,13 +129,12 @@ async def maybe_open_ctx(
|
||||||
|
|
||||||
ctx_key = id(mngr)
|
ctx_key = id(mngr)
|
||||||
|
|
||||||
|
|
||||||
value = None
|
value = None
|
||||||
try:
|
try:
|
||||||
# lock feed acquisition around task racing / ``trio``'s
|
# lock feed acquisition around task racing / ``trio``'s
|
||||||
# scheduler protocol
|
# scheduler protocol
|
||||||
value = cache.values[key]
|
value = cache.values[key]
|
||||||
log.info(f'Reusing cached feed for {key}')
|
log.info(f'Reusing cached resource for {key}')
|
||||||
cache.users += 1
|
cache.users += 1
|
||||||
cache.lock.release()
|
cache.lock.release()
|
||||||
yield True, value
|
yield True, value
|
||||||
|
@ -146,14 +146,15 @@ async def maybe_open_ctx(
|
||||||
# checking the cache until complete otherwise the scheduler
|
# checking the cache until complete otherwise the scheduler
|
||||||
# may switch and by accident we create more then one feed.
|
# may switch and by accident we create more then one feed.
|
||||||
|
|
||||||
# TODO: vaoid pulling from ``tractor`` internals and
|
# TODO: avoid pulling from ``tractor`` internals and
|
||||||
# instead offer a "root nursery" in
|
# instead offer a "root nursery" in piker actors?
|
||||||
service_n = tractor.current_actor()._service_n
|
service_n = tractor.current_actor()._service_n
|
||||||
|
|
||||||
# TODO: does this need to be a tractor "root nursery"?
|
# TODO: does this need to be a tractor "root nursery"?
|
||||||
ln = cache.nurseries.get(ctx_key)
|
ln = cache.resources.get(ctx_key)
|
||||||
assert not ln
|
assert not ln
|
||||||
ln = cache.nurseries[ctx_key] = service_n
|
|
||||||
|
ln, _ = cache.resources[ctx_key] = (service_n, trio.Event())
|
||||||
|
|
||||||
value = await ln.start(cache.run_ctx, mngr, key)
|
value = await ln.start(cache.run_ctx, mngr, key)
|
||||||
cache.users += 1
|
cache.users += 1
|
||||||
|
@ -170,10 +171,11 @@ async def maybe_open_ctx(
|
||||||
if value is not None:
|
if value is not None:
|
||||||
# if no more consumers, teardown the client
|
# if no more consumers, teardown the client
|
||||||
if cache.users <= 0:
|
if cache.users <= 0:
|
||||||
log.warning(f'De-allocating feed for {key}')
|
log.warning(f'De-allocating resource for {key}')
|
||||||
|
|
||||||
# terminate mngr nursery
|
# terminate mngr nursery
|
||||||
cache.no_more_users.set()
|
_, no_more_users = cache.resources[ctx_key]
|
||||||
|
no_more_users.set()
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
|
|
Loading…
Reference in New Issue