Skip to content

Instantly share code, notes, and snippets.

@njsmith
Created February 22, 2019 00:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save njsmith/196984fe7209974077b19428ee5773bf to your computer and use it in GitHub Desktop.
Save njsmith/196984fe7209974077b19428ee5773bf to your computer and use it in GitHub Desktop.
# https://gitter.im/python-trio/general?at=5c6f46089155d45d905346b3
import trio
from functools import partial
class RenewableResource(trio.abc.AsyncResource):
def __init__(self, factory, *args):
self._factory = partial(factory, *args)
self._resource = None
@asynccontextmanager
async def use(self):
if self._resource is None:
self._resource = await self._factory()
try:
yield self._resource
except:
await self.aclose()
raise
async def aclose(self):
if self._resource is not None:
resource = self._resource
self._resource = None
await resource.aclose()
# This with block controls the lifetime of abstract "renewable resource", and
# makes sure that the final concrete resource eventually gets closed
async with RenewableResource(partial(open_websocket, ...)) as resource:
# Each time we 'async with use' it, it re-uses the last one if possible,
# otherwise recreates it
async with resource.use() as ws:
# Use the websocket here
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment