Methods
ObserveChannels | (o: Account, o: Connection, a(oa{sv}): Channels, o: Dispatch_Operation, ao: Requests_Satisfied, a{sv}: Observer_Info) | → | nothing |
Properties
ObserverChannelFilter | aa{sv} (Channel_Class_List) | Read only | |
Recover | b | Read only |
Description
Observers monitor the creation of new channels. This functionality can be used for things like message logging. All observers are notified simultaneously.
Observers SHOULD NOT modify the state of a channel except via user interaction.
We want Observer UIs for file transfer channels (a progress bar for the transfer) to be able to have a Cancel button.
Observers MUST NOT carry out actions that exactly one process must take responsibility for (e.g. acknowledging Text messages, or carrying out the actual transfer in a file transfer channel).
Since arbitrarily many observers can be activated for each channel, it would not make sense for observers to do things that can only be done by one process (acknowledging Text messages, carrying out streaming for StreamedMedia channels, doing the actual data transfer for file transfers, setting up the out-of-band connection for Tubes). The Handler is responsible for such tasks.
Handlers MAY, of course, delegate responsibility for these tasks to other processes (including those run as observers), but this MUST be done explicitly via a request from the Handler to the Observer.
Whenever a collection of new channels is signalled, the channel dispatcher will notify all running or activatable observers whose ObserverChannelFilter property (possibly as cached in the .client file) indicates that they are interested in some of the channels.
Observers are activated for all channels in which they have registered an interest - incoming, outgoing or automatically created - although of course the ObserverChannelFilter property can be set to filter on the Requested property.
Because it might take time for an observer to become ready (for instance, a Text logger needs to wait until pending messages have been downloaded), the channel dispatcher must wait (up to some timeout) for all observers to return from ObserveChannels before letting anything destructive happen. Destructive things (e.g. acknowledging messages) are defined to be done by handlers, therefore HandleWith and Claim aren't allowed to succeed until all observers are ready.
Methods
ObserveChannels (o: Account, o: Connection, a(oa{sv}): Channels, o: Dispatch_Operation, ao: Requests_Satisfied, a{sv}: Observer_Info) → nothing
Parameters
- Account — o
- Connection — o
- Channels — a(oa{sv}) (Channel_Details_List)
- Dispatch_Operation — o
- Requests_Satisfied — ao
- Observer_Info — a{sv}
recovering
- b- True if ObserveChannels was called on existing channel due to
observer recovery, otherwise False.
This allows observers to distinguish between new channels (the normal case), and existing channels that were given to the observer in order to catch up on previous events (perhaps after a previous instance of the same observer crashed).
The path to the ChannelDispatchOperation for these channels, or the special value '/' if there is no ChannelDispatchOperation (because the channels were requested, not incoming).
If the Observer calls Claim or HandleWith on the dispatch operation, it MUST be careful to avoid deadlock, since these methods cannot return until the Observer has returned from ObserveChannels.
This allows an Observer to Claim a set of channels without having to match up calls to this method with calls to AddDispatchOperation.
Additional information about these channels. Currently defined keys are:
All defined keys for this dictionary are optional; observers MAY safely ignore any entry in this dictionary.
Called by the channel dispatcher when channels in which the observer has registered an interest are announced in a NewChannels signal.
If the same NewChannels signal announces some channels that match the filter, and some that do not, then only a subset of the channels (those that do match the filter) are passed to this method.
If the channel dispatcher will split up the channels from a single NewChannels signal and dispatch them separately (for instance because no installed Handler can handle all of them), it will call ObserveChannels several times.
The observer MUST NOT return from this method call until it is ready for a handler for the channel to run (which may change the channel's state).
The channel dispatcher must wait for observers to start up, to avoid the following race: text channel logger (observer) gets ObserveChannels, text channel handler gets HandleChannels channel handler starts up faster and acknowledges messages, logger never sees those messages.
The channel dispatcher SHOULD NOT change its behaviour based on whether this method succeeds or fails: there are no defined D-Bus errors for this method, and if it fails, this only indicates that an Observer is somehow broken.
The expected error response in the channel dispatcher is to log a warning, and otherwise continue as though this method had succeeded.
Properties
ObserverChannelFilter — aa{sv} (Channel_Class_List)
A specification of the channels in which this observer is interested. The ObserveChannels method should be called by the channel dispatcher whenever any of the new channels in a NewChannels signal match this description.
Only certain D-Bus types have useful semantics for matching like this, so only certain types are allowed:
- Integers of all sizes, including byte (y, n, q, i, u, x, t)
- Matched by numeric value, regardless of type (e.g. 42 as a 16-bit signed integer 'n' is considered equal to 42 as a 32-bit unsigned integer 'u')
- Booleans (b)
- Matched by equality in the obvious way; not considered equal to any other type
- Strings (s)
- Matched by equality in the obvious way; not considered equal to any other type
- Object paths (o)
- Matched by equality in the obvious way; not considered equal to any other type
This property never changes while the observer process owns its Client bus name. For activatable processes, the filter can change due to an upgrade - the channel dispatcher SHOULD observe changes to .client files using a mechanism like inotify.
Not allowing this property to change is a simplification, particularly for activatable processes (we reject the possibility that a process with a .client file, when activated, has a filter that differs from what its .client file said).
If an Observer wants to add extra channels to its list of interests at runtime, it can register an additional Client bus name (for instance, the org.freedesktop.Telepathy.Client.Empathy process with unique name :1.42 could additionally register org.freedesktop.Telepathy.Client.Empathy._1_42) with additional filters. To remove those filters, it can release the bus name; it could even re-claim the bus name immediately, with different filters.
The same principle is applied to Approvers and Handlers.
For observers that have a .client file, the channel dispatcher
may discover this property from keys of the form
"propertyname type
",
in groups in the .client file whose name is the name of this
interface followed by .ObserverChannelFilter
,
a space and an ASCII decimal number starting from 0.
Values in the .client file are encoded in exactly the same way as
the default-p
keys in .manager files, as
described in the ConnectionManager interface (but note that not all
types supported in .manager files can appear in .client files).
For instance, a .client file for an observer that is only interested in Text channels, with CONTACT or ROOM handles, that were requested by a local client:
[org.freedesktop.Telepathy.Client] Interfaces=org.freedesktop.Telepathy.Client.Observer; [org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 0] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=1 org.freedesktop.Telepathy.Channel.Requested b=true [org.freedesktop.Telepathy.Client.Observer.ObserverChannelFilter 1] org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text org.freedesktop.Telepathy.Channel.TargetHandleType u=2 org.freedesktop.Telepathy.Channel.Requested b=true
Recover — b
If true, upon the startup of this observer, ObserveChannels will be called for every already existing channel matching its ObserverChannelFilter
When activatable client having this property disappears from the bus and there are channels matching its ObserverChannelFilter, ObserveChannels will be called immediately to reactivate it again.
This means that if an activatable Observer crashes, it will be restarted as soon as possible; while there is an unavoidable possibility that it will miss some events during this process (particularly Text messages), this window of event loss is kept to a minimum.
Non-activatable observers can't take advantage of this mechanism, but setting this property on a non-activatable observer does allow it to "catch up" on channels that are currently active at the time that it starts up.
When the ObserveChannels method is called due to observer recovery, the "Observer_Info" dictionary will contain one extra item with key "recovering" and boolean value of True.