This law establishes a message exchange protocol somewhat
analogous to the flow control discipline of TCP/IP.
The law allows the exchange of two kinds of messages: ping
messages, which might represent such things as a question, or a request; and
pong messages, used as a reply to a previously received ping messages.
We call a ping message sent by x to y unresolved, if x
did not receive a corresponding pong to it. The ping-pong policy
regulates the flow of messages between any pair of agents (x, y)
as follows: x cannot send any pong message to y unless y has previously sent a ping
message to x; and x cannot send a second ping message to y unless y
answers with a pong message to x following the initial ping.
Note that this law differs technically from the previous laws in that it is based
on a very dynamic use of state.
The Prolog version of the ping pong policy is presented below:
law(pingpong,language(prolog)). sent(X,ping(M),Y) :- not(pingTo(Y)@CS), do(add(pingTo(Y))), do(forward). arrived(X,ping(M),Y) :- do(add(pingFrom(X))), do(deliver). sent(X,pong(M),Y) :- pingFrom(Y)@CS, do(remove(pingFrom(Y))), do(forward). arrived(X,pong(M),Y) :- do(remove(pingTo(X))), do(deliver). disconnected :- do(quit).
The corresponding Java law follows:
law(pingpong,language(java))
public class Pingpong extends Law {
public void sent(String source, String message, String dest) {
String pingToY = "pingTo(" + dest + ")";
String pingFromY = "pingFrom(" + dest + ")";
if (message.startsWith("ping(") && !CS.has(pingToY)) {
doAdd(pingToY);
doForward();
}
if (message.startsWith("pong(") && CS.has(pingFromY)) {
doRemove(pingFromY);
doForward();
}
}
public void arrived(String source, String message, String dest) {
if (message.startsWith("ping(")) {
doAdd("pingFrom(" + source + ")");
doDeliver();
}
if (message.startsWith("pong(")) {
doRemove("pingTo(" + source + ")");
doDeliver();
}
}
public void disconnected() {
doQuit();
}
}
In order to observe the behavior of this law, perform the following steps:
x; provide one of the URLs above.
y as above;
y@hostname; observe that the message does not get
propagated;
ping(something) to
y@hostname; observe how the message arrives at its
destination;
pong(somethingelse) to
x@hostname; observe how the message arrives at its
destination;