The ability to link topics together into a federation provides IceStorm applications with a lot of flexibility, while the notion of a “cost” associated with links allows applications to restrict the flow of messages in creative ways. IceStorm applications have complete control of topic federation using the
TopicManager interface described in the online
Slice Reference, allowing links to be created and removed dynamically as necessary. For many applications, however, the topic graph is static and therefore can be configured using the administrative tool discussed in
Section 44.8.
In this case, messages published on A are propagated to
B, but
B does not propagate
A’s messages to
C. Therefore, subscriber S
B receives messages published on topics
A and
B, but subscriber S
C only receives messages published on topics
B and
C. If the application needs messages to propagate from
A to
C, then a link must be established directly between
A and
C.
As described in Section 44.9.1, IceStorm messages are only propagated on the originating topic’s immediate links. In addition, applications can use the notion of cost to further restrict message propagation.
A cost is associated with messages and links. When a message is published on a topic, the topic compares the cost associated with each of its links against the message cost, and only propagates the message on those links whose cost equals or exceeds the message cost. A cost value of zero (
0) has the following implications:
Publisher P1 publishes a message on topic
A with a cost of
1. This message is propagated on the link to topic
B because the link has a cost of
0 and therefore accepts all messages. The message is also propagated on the link to topic
C, because the message cost does not exceed the link cost (
1). On the other hand, the message published by P
2 with a cost of
2 is only propagated on the link to
B.
The cost of a message is specified in an Ice request context. Each Ice proxy operation has an implicit argument of type
Ice::Context representing the request context (see
Section 32.12). This argument is rarely used, but it is the ideal location for specifying the cost of an IceStorm message because an application only needs to supply a request context if it actually uses IceStorm’s cost feature. If the request context does not contain a cost value, the message is assigned the default cost value of zero (
0).
Measurement m = getMeasurement();
Ice::Context ctx;
ctx["cost"] = "5";
monitor‑>report(m, ctx);
Measurement m = getMeasurement();
java.util.HashMap ctx = new java.util.HashMap();
ctx.put("cost", "5");
monitor.report(m, ctx);
A subscriber can discover the cost of a message by examining the request context supplied in the
Ice::Current argument. For example, here is a C++ implementation of
Monitor::report that displays the cost value if it is present:
virtual void report(const Measurement& m,
const Ice::Current& curr) {
Ice::Context::const_iterator p = curr.ctx.find("cost");
cout << "Measurement report:" << endl
<< " Tower: " << m.tower << endl
<< " W Spd: " << m.windSpeed << endl
<< " W Dir: " << m.windDirection << endl
<< " Temp: " << m.temperature << endl
<< " Temp: " << m.temperature << endl;
if (p != curr.ctx.end())
cout << " Cost: " << p‑>second << endl;
cout << endl;
}
public void report(Measurement m, Ice.Current curr) {
String cost = null;
if (curr.ctx != null)
cost = curr.ctx.get("cost");
System.out.println(
"Measurement report:\n" +
" Tower: " + m.tower + "\n" +
" W Spd: " + m.windSpeed + "\n" +
" W Dir: " + m.windDirection + "\n" +
" Temp: " + m.temperature);
if (cost != null)
System.out.println(" Cost: " + cost);
System.out.println();
}
For the sake of efficiency, the Ice for Java run time may supply a null value for the request context in
Ice.Current, therefore an application is required to check for null before using the request context.
Given the restrictions on message propagation described in the previous sections, creating a complex topic graph can be a tedious endeavor. Of course, creating a topic graph is not typically a common occurrence, since IceStorm keeps a persistent record of the graph. However, there are situations where an automated procedure for creating a topic graph can be valuable, such as during development when the graph might change significantly and often, or when graphs need to be recomputed based on changing costs.
A simple way to automate the creation of a topic graph is to create a text file containing commands to be executed by the IceStorm administration tool. For example, the commands to create the topic graph shown in
Figure 44.5 are shown below:
If we store these commands in the file graph.txt, we can execute them using the following command:
$ icestormadmin ‑‑Ice.Config=config graph.txt
We assume that the configuration file config contains the definition for the property
IceStormAdmin.TopicManager.Default.
Note that, if you federate IceStorm servers, you must ensure that the proxies for the linked topics always use the same host and port (or, alternatively, can be indirectly bound via IceGrid), otherwise the federation cannot be re-established if one of the servers in the federation shuts down and is restarted later.