How to handle requests that take a long time to complete

Schmottlach, Glenn GSchmott at harmanbecker.com
Thu Nov 20 10:40:18 PST 2008


I am trying to determine the recommended approach to handle a DBus
request to a service that takes a "long" time to complete. From the
client-side (e.g. the DBus service "proxy") most of the DBus language
bindings allow the client to either block waiting for a response or
register a callback function to handle the response asynchronously at a
later time.

 

If I am writing a DBus service, however, I have not run across a binding
that allows the server side callback to defer handling the request to a
time beyond the scope of the service callback (e.g. beyond the "return"
at the end of the callback). For example, suppose I provide a service
that has a method which query's a huge database. Typically querys may
take several seconds and during the time the service is waiting on the
response from an internal database, I don't want to block the mainloop
of the DBus service. In fact, I want to be able to handle multiple
overlapping requests (or at least queue these requests up for later
processing). So my server has a DBus method that looks like this:

 

void getResults(const char* cmd, char** results)

{

            // Issue request to the internal DB

 

            // Either block (do NOT want to do this), or better yet,
somehow defer replying to

            // this request at some point in the future.

 

            // I don't want the binding/wrapper code to immediately
return a result

            return;

}

 

If I block waiting on the response from the database, it ties up the
DBus main loop which is not what I want to do. Spawning a thread to wait
on the database doesn't help much either since when the function returns
most bindings (I think) expect the result to be filled in. Ideally, I'd
like to copy what state information I need related to the request and
on-going database query, stash that somewhere, register a callback for
the internal database to indicate completion, and return WITHOUT the
DBus binding immediately replying to the request.  In other proprietary
frameworks I have used there has been a method to "detach" the request
in the service handler and then later re-associate that request with the
results. I *think* the lowest level DBus library fundamentally supports
this notion of deferring a response but I am not sure how the more
mature DBus bindings/wrappers handle this. I'd rather NOT have to use a
one-way call where there is no immediate response but a signal is issued
later time containing the results and a key/token used to associate the
earlier request with the later response. It's cumbersome to design such
services.

 

Can anyone suggest the appropriate way to architect this pattern
(preferably using either the C++ or Glib binding to DBus)?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freedesktop.org/archives/dbus/attachments/20081120/aeb66b37/attachment.htm 


More information about the dbus mailing list