[Interest] QtDBus interface design question

Thiago Macieira thiago.macieira at intel.com
Mon Nov 11 21:03:23 CET 2013


On quinta-feira, 7 de novembro de 2013 19:01:57, Roland Winklmeier wrote:
> Hey there,

Hello Roland

As promised, I have found time to read your email and reply.

> I have a daemon application built with C++/Qt. It is a client for a
> network and should run in the background. The plan was to connect the UI
> via DBus to this daemon in order to make the objects inside the daemon
> also available to other external tools/addons. So far nothing special,
> this is done in many places in KDE.

When discussing D-Bus, please don't mention "network" :-)

People might jump at you and say that D-Bus isn't meant to be used across a 
network. That's not what you're trying to do -- your application just happens 
to do networking somewhere else in it.

> The thing is , the object hierarchy is quite deep and complicated. The
> best example is the object managing the applications settings, lets call
> it CSettingsManager : public QObject. It holds several client QObjects,
> representing each a different setting group:
> 
> CSettingsManager
> 
> |--- CServerSettings
> |--- CUserSettings
> |--- CLoggingSettings
> |--- CGuiSettings
> 
> Now we want to expose these hierarchy via DBus. After reading thousands
> of DBus applications and their interfaces, we decided to try the
> following interface:
> 
> /CSettingsManager
> /CSettingsManager/CServerSettings
> /CSettingsManager/CUserSettings
> /CSettingsManager/CLoggingSettings
> /CSettingsManager/CGuiSettings

Sounds reasonable.

> I think up to now its convenient. Instead of passing custom classes via
> DBus, I thought its better to register the child objects too and just
> point to the object via a QDbusObjectPath argument. So anyone can act
> and react on the real object via DBus.
> For example I can call CSettingsManager::getServerSettings() {return
> QDBusObjectPath "/CSettingsManager/CServerSettings" } and create a
> QDbusAbstractInterface with the returned objectpath and call methods on
> the child object. So far so good. I have to mention here, the number of
> CServerSettings is dynamic and decided during runtime (based on what is
> specificed in the configuration file).

I'm not sure I understood what you meant here.

If the path is fixed and known to all clients, there's no point in adding a 
method that returns it. If it's always going to be the same, the clients 
should just avoid the extra round-trip and should send the request directly.

Maybe what you meant is because of what follows:

> The DBus interface for example could look like:
> 
> /CSettingsManager/CServerSettings/Server1
> /CSettingsManager/CServerSettings/Server2
> ...
> /CSettingsManager/CServerSettings/ServerN

Sounds good. Your first idea has probably been to register one QObject per 
path. That's a valid solution. However, do it only if you had those QObjects 
(one per path) anyway, to hold the data and to control the lifetime.

Otherwise, there's another trick: you can register the same QObject multiple 
times and simply get the targeted path from the incoming QDBusMessage (which 
you can get by deriving that class multiply from QObject and from 
QDBusContext).

> The issue is now, I want to have a table view displaying the properties
> for each Server and let the user edit it.
> 
> --------------------------------------
> 
> |Server 1 | IP address | port | name |
> |Server 2 | IP address | port | name |
> |Server 3 | IP address | port | name |
> 
> --------------------------------------

Why do you want to have that table? Is that normal activity in your service? 
Or is this something that you'll use once in a blue moon, to test how it's 
going?

The reason I ask is that the answer will determine whether you should have a 
fast API to retrieve everything, or if it's acceptable that the client must do 
multiple calls to collect all the information.

> I could get a list of all objects and start retrieving their properties,
> but lets suppose I have 1000 rows with 4 properties each = 4000 Dbus
> calls to build the table. The performance would be horrible.

Indeed, hence the question above.

> The only solution I can imagine is to pass the entire table in one DBus
> message, but how. I cannot pass the objects itself, because I cannot
> transfer an QObject via DBus. Creating plain structs and pass them is an
> option but is rather dirty to me.

Creating structs and passing an array of structs is the only way.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20131112/67c8fb9e/attachment.sig>


More information about the Interest mailing list