Skip to content

Resource subclass and its init return value #663

@pansen

Description

@pansen

Hi there,

thanks a lot for this library and its great documentation! I could manage to port important parts of my application to using this, without any bigger issues.

One thing I had to spend some time for was the following.

Consider I subsclass a Resource, which creates a asyncio.Task, which should be cancelled on shutdown. I could not get this to work, except with this workaround:

class DispatcherQueueConsumerResource(resources.Resource): async def init(self, loop: AbstractEventLoop, disp, queue, **kwargs) -> Optional[Task]: t: Task = loop.create_task(disp.queue_consumer(queue)) # If this is an async method, we store the task to have that usable in `shutdown`. # # The `shutdown` method receives this method as an awaited coroutine and *not* the task we # just created and may return. Ergo does the cancellation not work, if we don't store our own # copy here. setattr(self, '__t', t) return async def shutdown(self, t: Task) -> None: to_cancel = None t_ = getattr(self, '__t', None) if t_: # Take `self.__t` with preference to_cancel = t_ elif t: to_cancel = t else: log.error("Nothing to shutdown: %s, %s", self, t) return try: if isinstance(to_cancel, Task): to_cancel_task = to_cancel elif inspect.iscoroutine(to_cancel): to_cancel_task = asyncio.create_task(to_cancel) else: raise RuntimeError(f"Don't know what I got here: {t}") was_cancelled = to_cancel_task.cancel() if was_cancelled: wait_for_seconds = 0.1 await asyncio.wait_for(to_cancel_task, wait_for_seconds) foo = 1 except AttributeError as e: log.error('Could not call `%s.cancel`: %s', to_cancel, e)

As described in the init comment, we will receive a coroutine of DispatcherQueueConsumerResource.init as parameter in DispatcherQueueConsumerResource.shutdown, no matter what is returned from DispatcherQueueConsumerResource.init. It is hackable with this subclass solution, but not using the generator approach.

If I would be using the parameter t in shutdown, my code stalls forever when calling shutdown_resources. Therefore using the generator approach for my Resource is not working as is.

Just in case this is relevant, cause I saw this bug, I'm also using FastAPI in my application.

Please let me know if I should provide more information :)

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions