Question about asyncio and blocking operations

Alberto Berti alberto at metapensiero.it
Tue Jan 26 18:57:10 EST 2016


>>>>> "Frank" == Frank Millman <frank at chagford.com> writes:

    Frank> Now I have another problem. I have some classes which retrieve some
    Frank> data from the database during their __init__() method. I find that it
    Frank> is not allowed to call a coroutine from __init__(), and it is not
    Frank> allowed to turn __init__() into a coroutine.

IMHO this is semantically correct for a method tha should really
initialize that instance an await in the __init__ means having a
suspension point that makes the initialization
somewhat... unpredictable :-).

To cover the cases when you need to call a coroutine from a non
coroutine function like __init__ I have developed a small package that
helps maintaining your code almost clean, where you can be sure that
after some point in your code flow, the coroutines scheduled by the
normal function have been executed. With that you can write code like
this:

    from metapensiero.asyncio import transaction

    class MyObject():

        def __init__(self):
            tran = transaction.get()
            tran.add(get_db_object('company'), cback=self._init) # get_db_object is a coroutine

        def _init(self, fut):
            self.company = fut.result()

    async external_coro(): # this is the calling context, which is a coro
        async with transction.begin():
            o = MyObject
            # maybe other stuff

        # start using your db object
        o.company...

This way the management of the "inner" coroutine is simpler, and from
your code it's clear it suspends to wait and after that all the
"stashed" coroutines are guaranteed to be executed.

Hope it helps,

Alberto




More information about the Python-list mailing list