Description

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 law

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).
It can be found at:
http://www.moses.rutgers.edu/examples/pingpong/Pingpong.law

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();
    }
}
It can be found at:
http://www.moses.rutgers.edu/examples/pingpong/Pingpong.java1

Running the example

In order to observe the behavior of this law, perform the following steps:

  • start a controller;
  • using the web-based interface, create an agent with the name x; provide one of the URLs above.
  • create another agent with the name y as above;
  • try to send an arbitrary message from x to y@hostname; observe that the message does not get propagated;
  • send the message ping(something) to y@hostname; observe how the message arrives at its destination;
  • try to re-send the message above; observe again that the message does not get propagated;
  • from y send the message pong(somethingelse) to x@hostname; observe how the message arrives at its destination;
  • try to re-send the same message again; observe that this message does not get propagated either;
  • continue by sending ping messages.