qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC/RFA PATCH] qapi: detect extra members inside struc


From: Anthony Liguori
Subject: Re: [Qemu-devel] [RFC/RFA PATCH] qapi: detect extra members inside structs
Date: Mon, 19 Mar 2012 19:49:46 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2

On 03/19/2012 06:45 PM, Michael Roth wrote:
So IMO, returning arguments actually seems easier for both clients and the
server, and is more resilient to downstream changes. It does require a more
formal specification of the protocol though. Basically: "an option/field
may not be supported in older/future versions of QEMU, so it is up to
the client to check in advance by referencing the QAPI schema for their
qemu version or programatically via get_schema(<command>)"

The complexity of writing a client using get_schema() is close to staggering :-/

I'm not sure, I mean, take libvirt, you need to marshall up the
arguments anyway and put them into a QMP payload, so in that case the
client developer is aware of the schema that they're coding against,
and also understand the QAPI schema specification, and if the schema
is nested then so is the client version of that "schema".

So, conceptually at least, it seems like it wouldn't be that big a jump
to maintain an internal representation of their schema to
programatically check against the specification they were coding
against, it's just the part where they then need to bake it into the
client implementation that's a bit heavy-handed.

So let's work through a few examples. Today, you have to maintain a list of commands returned from query-commands and check for set membership:

if 'query-netdev2' in commands:
   qmp.query_netdev2(foo)
else:
   qmp.query_netdev()

Pretty simple. If we have a schema representation, we'll need to be able to check for arguments. That means we need a way to check if a command has an argument. We could do this as nested lists:

if (commands.has_key('query-netdev') and
    commands['query-netdev']['args'].has_key('interface')):
   qmp.query_netdev(foo)
else:
   qmp.query_netdev()

This is only really possible in a dynamically typed language, which sucks, but let's ignore that for now. This is a bit more complicated but unfortunately, it's not enough.

Because we can add members to structures and structures can be arguments. So we really need a way to say:

1) Do we have the query-netdev command
2) Does it take a parameter called interface of type NetDevArgument
3) Does the NetDevArgument have a member called 'foo'.

But this actually can be arbitrarily deep in terms of complex. Maybe you make a simple query language so you can execute schema queries in a single line.

So you have an interface definition that is the schema that describes an unstructured wire protocol and a query language to determine when and how the schema changes. If that doesn't ring a bell to you, congratulations, you've invented SOAP.

The interface description in SOAP is WSDL and XPath is the query language. Writing a SOAP client is a train wreck. It's so bad that even in dynamic languages, people almost always use code generators.

A good RPC makes the client simple. If that means we need to take care when introducing new interfaces, then it's a small price to pay for avoiding the nightmares of an over engineered RPC like SOAP.

Regards,

Anthony Liguori

Thinking about it more the, this does seem to be completely at odds with
any future prospects of a libqmp, so that's a pretty big trade-off...


Regards,

Anthony Liguori








reply via email to

[Prev in Thread] Current Thread [Next in Thread]