
// PingPongKeep.java
// Michele Loreti and the jSpace Developers, 2017
// Modified by Andrew Davison, ad@coe.psu.ac.th, May 2023

/* Two-way communication between the 'PingAgent' and 
   'PongAgent' threads which use two *remote* spaces 
   called PING_URI (PingSpace) and PONG_URI (PongSpace)

   PingAgent reads 'ping' tuples from the PingSpace, which
   are placed there by PongAgent.

   PongAgent reads 'pong' tuples from the PongSpace, which
   are placed there by PingAgent.

   An agent only writes a tuple after it has read one of its
   tuples. Deadlock is avoided by having PongAgent start by writing
   a ping to the PingSpace.

   There's no real need for two spaces here since the ping and
   pong tuples could all be placed in a single space.

   "The "keep" protocol means that all the tuple space operations
   in a thread use a single connection to a remote space. See
   PingPongConn.java for use of the "conn" protocol which opens
   a new connection for every tuple operation. From the user's
   point of view there's no difference.

   For more on distributed tuple spaces, see:
     https://github.com/pSpaces/Programming-with-Spaces/blob/master/tutorial-distributed-programming.md

  Usage:
    > compile.bat PingPongKeep.java
    > run.bat PingPongKeep

    Part of the application made up of:
       * PingPongKeep.java
       * PingAgent.java
       * PongAgent.java

  Other versions: 
    * PingPong.java
    * PingPongConn.java
*/

import java.io.*;
import java.net.*;

import org.jspace.*;


public class PingPongKeep
{
  private final static String SPACE_URI = "tcp://localhost:9001/?keep";

  private final static String PING_URI = 
                            "tcp://localhost:9001/PingSpace?keep";

  private final static String PONG_URI = 
                             "tcp://localhost:9001/PongSpace?keep";
     // make sure the space names match those in SpaceRepository.add()


  public static void main( String[] argv ) 
                   throws InterruptedException,
                          UnknownHostException, IOException
  {
    // create one reporitory with two spaces
    SpaceRepository repository = new SpaceRepository();
    repository.addGate(SPACE_URI);
    repository.add("PingSpace", new SequentialSpace());
    repository.add("PongSpace", new SequentialSpace());

    Thread t1 = new Thread( new PingAgent(
                               new RemoteSpace(PING_URI),
                               new RemoteSpace(PONG_URI)));
    Thread t2 = new Thread( new PongAgent(
                                new RemoteSpace(PING_URI),
                                new RemoteSpace(PONG_URI)));
        /* Note: each thread creates its own references to the
           two remote spaces. This ensues they each has their own
           gate to the spaces. 
        */
    t1.start();
    t2.start();

    SpaceUtils.waitTerminated(t1, t2);
    repository.shutDown();
  } /* main */

}  // end of PingPongKeep class
