[g-a-devel] AT-SPI caching and D-Bus usage
- From: Mike Gorse <mgorse alum wpi edu>
- To: gnome-accessibility-devel gnome org
- Subject: [g-a-devel] AT-SPI caching and D-Bus usage
- Date: Mon, 7 Oct 2013 15:45:21 -0400 (EDT)
AT-SPI was originally designed around CORBA, specifically ORBit. Its use
led to a large amount of inter-process communication. Method calls in
ORBit were fairly quick, so this was not a huge problem, although that
isn't to say that there were never performance issues. However, ORBit was
deprecated for GNOME 3, and Codethink undertook an investigation of the
feasibility of porting AT-SPi to D-Bus. Note that the D-Bus libraries were
not really designed to be used in cases where a large amount of
synchronous method calls are needed. Nevertheless, Codethink undertook an
investigation of the feasibility of porting AT-SPI to D-Bus. Their
main conclusions were that, although D-Bus method calls are slower than
the equivalent CORBA calls, a lot of AT-SPI traffic generated by Orca
comes from a handful of method calls--calls to fetch an object's name,
parent, children, or state set, for instance. If these data could be
cached, then a significant amount of traffic would become unnecessary.
This led to the current design, where some data are cached, and the
default assumption is that applications will send notifications when an
object's name, description, state, or children are changed. Calls
requesting other data, such as attributes or screen coordinates, result in
method calls. This design has a few problems:
- It relies on applications sending notifications any time an object's
states or children change. If an application fails to do this, then Orca
will see stale data, unless it has instructed AT-SPI not to cache certain
kinds of data for the given application. It is sometimes difficult for a
toolkit implementor to send notifications for every such change, and the
result is that AT-SPI2 is made fragile in a way that was not previouisly
the case.
- Not all data that an AT may need is cached. For instance, when Orca sees
an event, it wants to look at the attributes for the accessible that
triggered the event, in order to determine which toolkit sent it, in order
to decide which script to use. Attributes are not cached, so this means
that Orca always makes a round-trip D-Bus call to retrieve the attributes
of the object that just sent the event. Similarly, when building a flat
review context, it wants to know the extents of various accessibles on the
screen, and extents are not cached, so a significant number of round-trip
calls are needed in order to fetch extents for many different objects. One
solution would be to add more things to the data that AT-SPI caches (ie,
http://bugzilla.gnome.org/show_bug.cgi?id=649771), but this has the
downside of making AT-SPI even more reliant on applications to send events
when various things change, introducing the possibility for new bugs.
- Sometimes, it is necessary to avoid synchronous D-Bus calls altogether
(see https://bugzilla.gnome.org/show_bug.cgi?id=708387).
I think that a good solution would be two-fold:
- Allow an event listener to request particular data be sent along with an
event. For instance, Orca could request that an object's attributes be
sent. The attributes would be cached probably for the duration of the
event callback. While we're modifying the API for event listeners, it
would be good to take a look at
https://bugzilla.gnome.org/show_bug.cgi?id=640440.
- Add a function to allow various data to be fetched in one go. It would
take a callback to be called whtn the data is ready. For instance, perhaps
orca would want to know the roles, states, and extents of all
(non-transient) objects descending from a particular accessible. All of
this data would be stored in a cache that would be valid for the duration
of the callback(?). If, say, atspi_accessible_get_attributes is called
from within the callback and the attributes have been pre-fetched, then
return the attributes we have cached rather than make another D-Bus call.
In the long term, this might be able to replace the current caching
mechanism. Ie, something like:
typedef void (*AtspiQueryCallback) (void *user_data)
void atspi_query_accessible (AtspiAccessible *obj,
const gchar **properties,
AtspiQueryCallback *cb,
void *user_data,
gboolean allow_sync,
gboolean include_descendants,
GError **error);
If allow_sync is FALSE, then AT-SPI will throw an exception rather than
make a synchronous call. This could be used when it is desirable to
guarantee that no synchronous calls are made (probably anything running
inside gnome-shell would want this, since otherwise it can deadlock if it
queries an application which is in turn making a non-AT-SPI-related D-Bus
call to gnome-shell).
I'm not sure if having an "include descendants" parameter is best, or if
something more fine-grained would be better (perhaps an enum allowing just
the accessible, the accesible and its children, or the accessible and all
non-transient descendants?) Also, maybe we want a parameter to specify the
starting point--it might be useful to be able to specify an ancestor with
a given role as a starting point? This gets into whether it might be
useful to take a string parameter specifying a predicate. It may be worth
investigating whether xpath would be helpful / whether there are libraries
that would be useful in terms of parsing it.
Comments welcome.
-Mike
[Date Prev][
Date Next] [Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]