← Back to team overview

nova team mailing list archive

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

 

But then haven't we also converted info() from returning a value to
returning a deferred?  So then don't we have to do this to all the callers
of info()?  And then all their callers? etc


On Mon, Aug 2, 2010 at 4:59 PM, Vishvananda Ishaya <vishvananda@xxxxxxxxx>wrote:

> 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