← Back to team overview

nova team mailing list archive

Re: How best to implement a synchronous interface method with an asynchronous implementation?

 

I'm thinking something like this should work

    @defer.inlineCallbacks
    def info(self):
        result = yield defer.maybeDeferred(self._conn.get_info, self.name)
        result['node_name'] = FLAGS.node_name
        defer.returnValue(result)

Then in your conn get_info can return a deferred?

Vish

On Mon, Aug 2, 2010 at 4:36 PM, Justin Santa Barbara <justin@xxxxxxxxxxxx>wrote:

> Thanks... my understanding is that maybeDeferred makes everything async,
> which means that I then have to make all the calling methods async, etc
> until the async 'virus' has infected every method :-)  Ideally, I'd like to
> contain the change so that the calling methods can remain synchronous and I
> don't have to rewrite the callers simply because the implementation of the
> interface changed.  This is sort of option B.
>
> Alternatively, I bite the bullet and convert this method and all its
> callers (and their callers, recursively) to be async.  Just for this one
> method, I think that means changing:
>
> fake::get_info, xenapi::get_info, libvirt::get_info to be async (so callers
> aren't forced to use maybeDeferred)
> And then the callers and their callers:
> monitoring.Instance::fetch_cpu_stats => monitoring.Instance::update =>
> monitoring.InstanceMonitor.updateInstances_ =>
> monitoring.InstanceMonitor.updateInstances
> service.Instance::info => service.Instance::update_state
> => ComputeService::adopt_instances (reboot and spawn are already async),
> VirtualBoxConnection::destroy (reboot and spawn are already async here also)
>
> And then because VirtualBoxConnection::destroy has now gone sync->async,
> then I would need to follow that chain.
>
> So I guess >20 functions will need conversion of sync -> async just for
> this one change.  Obviously, before I try submitting that patch, I want to
> know that this is the right thing to do!
>
> Justin
>
>
>
> On Mon, Aug 2, 2010 at 4:09 PM, Vishvananda Ishaya <vishvananda@xxxxxxxxx>wrote:
>
>>   show details 4:08 PM (0 minutes ago)
>>  I believe Twisted's maybeDefferred is for this purpose.  If you use that
>> for the calls into virt, each provider can used deferreds or not vor the
>> various methods.  We use it from api.py to call the endpoint methods
>>
>> Vish
>>
>> On Mon, Aug 2, 2010 at 1:19 PM, Justin Santa Barbara <justin@xxxxxxxxxxxx
>> > wrote:
>>
>>> I'm hacking on adding VirtualBox support (to allow native Mac
>>> development, more than as a serious production target).  This means adding
>>> another virt provider (I'm trying without libvirt for now, because libvirt
>>> VirtualBox support seems a little flaky, and I'm not sure about libvirt on
>>> the mac)  However one of the methods (get_info) is synchronous on the
>>> interface, but the VirtualBox implementation is asynchronous (it gets its
>>> results from spawning a process).  How do I handle this?
>>>
>>> A) Do I change the interface so that the method returns a deferred even
>>> in the providers that are synchronous?  If so, we should just have all
>>> interfaces return a deferred on all methods, so that the interface doesn't
>>> expose the implementation.  However, this would make everything messy...
>>>
>>> B) Should I type-check the result of the call and synchronously wait on
>>> it if it is deferred?  (And can anyone point me at some code that can do a
>>> sync-wait?)
>>>
>>> As an aside, and to borrow from the Wizard of Oz, "Twisted, I've a
>>> feeling we're not in Python any more".  Every method is preceded by
>>> @defer.inlineCallbacks, return x becomes returnValue(x), and there are
>>> yields scattered throughout the code based on whether the called method
>>> returns a deferred or not.  Perhaps we can clarify the Twisted vs Eventlet
>>> discussion: would Eventlet solve this particular problem?
>>>
>>> Justin
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Mailing list: https://launchpad.net/~nova
>>> Post to     : nova@xxxxxxxxxxxxxxxxxxx
>>> Unsubscribe : https://launchpad.net/~nova
>>> More help   : https://help.launchpad.net/ListHelp
>>>
>>>
>>
>

Follow ups

References