An IceStorm message is strongly typed and is represented by an invocation of a Slice operation: the operation name identifies the type of the message, and the operation parameters define the message contents. A message is published by invoking the operation on an IceStorm proxy in the normal fashion. Similarly, subscribers receive the message as a regular servant upcall. As a result, IceStorm uses the “push” model for message delivery; polling is not supported.
An application indicates its interest in receiving messages by subscribing to a topic. An IceStorm server supports any number of topics, which are created dynamically and distinguished by unique names. Each topic can have multiple publishers and subscribers.
A topic is essentially equivalent to an application-defined Slice interface: the operations of the interface define the types of messages supported by the topic. A publisher uses a proxy for the topic interface to send its messages, and a subscriber implements the topic interface (or an interface derived from the topic interface) in order to receive the messages. This is no different than if the publisher and subscriber were communicating directly in the traditional client-server style; the interface represents the contract between the client (the publisher) and the server (the subscriber), except IceStorm transparently forwards each message to multiple recipients.
IceStorm does not verify that publishers and subscribers are using compatible interfaces, therefore applications must ensure that topics are used correctly.
IceStorm messages are unidirectional, that is, they must have void return type, cannot have out-parameters, and cannot raise user exceptions. It follows that a publisher cannot receive replies from its subscribers. Any of the Ice transports (TCP, SSL, and UDP) can be used to publish and receive messages.
IceStorm supports the formation of topic graphs, also known as federation. A topic graph is formed by creating links between topics, where a
link is a unidirectional association from one topic to another. Each link has a
cost that may restrict message delivery on that link (see
Section 44.9.2). A message published on a topic is also published on all of the topic’s links for which the message cost does not exceed the link cost.
Once a message has been published on a link, the receiving topic publishes the message to its subscribers, but does not publish it on any of its links. In other words, IceStorm messages propagate at most one hop from the originating topic in a federation (see
Section 44.9.1).
Figure 44.3 presents an example of topic federation. Topic T
1 has links to T
2 and T
3, as indicated by the arrows. The subscribers S
1 and S
2 receive all messages published on T
2, as well as those published on T
1. Subscriber S
3 receives messages only from T
1, and S
4 receives messages from both T
3 and T
1.
IceStorm makes no attempt to prevent a subscriber from receiving duplicate messages. For example, if a subscriber is subscribed to both T
2 and T
3, then it would receive two requests for each message published on T
1.
IceStorm allows each subscriber to specify its own quality of service (QoS) parameters that affect the delivery of its messages. Quality of service parameters are represented as a dictionary of name–value pairs. The supported QoS parameters are described in
Section 44.10.
IceStorm’s default behavior maintains information about topics, links, and subscribers in a database. However, a message sent via IceStorm is not stored persistently, but rather is discarded as soon as it is delivered to the topic’s current set of subscribers. If an error occurs during delivery to a subscriber, IceStorm does not queue messages for that subscriber.
By default, IceStorm stores its persistent state in a Freeze database (see Chapter 39). However, you can configure IceStorm to use a different dabase, such as MySQL, among others (see
Section 44.12.6).
If IceStorm encounters a failure while attempting to deliver a message to a subscriber, the subscriber is immediately unsubscribed from the topic on which the message was published.
Note that this is important if you make changes to a Slice data type or operation signature: if you do, you must ensure that both publishers and subscribers use the same Slice definitions; if you do not, IceStorm is likely to encounter marshaling errors when forwarding an event to a subscriber with a mismatched Slice definition and remove the subscription.