# The FreePastry Tutorial.

This tutorial is designed to get you cooking quickly with the FreePastry API and software toolkit.

#### Version @tutorial_version@; @tutorial_date@. For FreePastry version @freepastry_version@. Maintained by @maintainer@.

# Simulator Tutorial

## FreePastry's Direct Simulator

### Download the tutorial files: DirectTutorial.java, MyApp.java, MyMsg.java into a directory called rice/tutorial/direct/.

Before completing this Tutorial, we recommend completing Lesson 4 of the FreePastry tutorial.

FreePastry's Simulator is a Discreet Event Simulator. The puropse of this tutorial is to show you how to test/simulate your application on a medium sized network ( < 100,000 Nodes) with a minimum of complications/changes to your code. If you followed the advice of the FreePastry tutorial up to this point, it should be very easy to test your code in the simulator. Before we continue, let's list what FreePastry's simulator does and doesn't do:

### What the simulator does:

- Execute FreePastry applications without modification to the source code. (Other than the initiation code: Such as the PastryNodeFactory.)
- Execute the code faster than real-time. The simulator uses a virtual clock, not the computer's clock. So if you have the CPU/memory, a simulated environment can run much much faster than a real clock. Or if you simulate a network too large or resource intensive to be simulated in real-time, then your accuracy won't be affected by insufficient resources, the virtual clock only advances when there are no immediate tasks to be executed.
- Contrary to the previous point, the simulator can be executed with the system clock. This my be useful to interactive applications that run on a "human" timescale. Because FreePastry supports a "real-time" clock, if you have a powerful enough computer, you can simulate interactive applications such as games and real-time collaborative applications without using multiple physical machines and a real network.
- Accept a variety of topologies for network latency. FreePastry ships with 3 topologies: `Euclidean` (Planar), `Sphirical`, and `GenericNetwork` topologies. The Eucliedean and Sphirical topologies use geometric equations to determine latencies between nodes. The `GenericNetwork` accepts a latency matrix from a file that can be used to construct transit-stub, or more complex topologies. In our attempt to simulate larger and more realistic networks, in the future, we intend to distribute an implementation of the technology discribed in this paper Measurement-Based Analysis, Modeling, and Synthesis of the Internet Delay Space.

### What the simulator doesn't do:

- Simulate message loss, bandwidth, or varying latency.To improve performance, and reduce implementation cost, FreePastry's simulator does not simulate all of the factors that a sumlator such as ns-2 attempts to simulate. This is out of the scope of what we intend to include in the FreePastry distribution.

## Converting the previous tutorials to use the simulator

Simple, all you have to do is use a different `PastryNodeFactory`, specifically the `DirectPastryNodeFactory`. You must also provide a network topology. In this example, we will use the `EuclideanNetwork` topology. The next tutorial will show you how to import a latency matrix to simulate more realistic topology models. In this case we are converting Lesson 4 to use the simulator. If you've completed Lesson 4, you will see that it is very easy to convert to using FreePastry's Discreet Event Simulator. Changes: Other than the arguments (we don't need to accept a boot-port, socket, bind-port) and the Constructor. Only 2 things have changed between these versions: Here is the change to the PastryNodeFactory.

      PastryNodeFactory factory = new SocketPastryNodeFactory(nidFactory, bindport, env);

has been changed to:

        // create a new network
        NetworkSimulator simulator = new EuclideanNetwork(env);

        // set the max speed of the simulator so we can create several nodes in a short amount of time
        // by default the simulator will advance very fast while we are slow on the main() thread
        simulator.setMaxSpeed(1.0f);

        // construct the PastryNodeFactory, this is how we use rice.pastry.direct, with a Euclidean Network
        PastryNodeFactory factory = new DirectPastryNodeFactory(nidFactory, simulator, env);

First we create a implementation of a NetworkSimulator, the EuclideanNetwork. This is the network topology, in this case a plane. In the next tutorial, we will simulate using a latency matrix.

By default, the simulator is very aggressive at advancing time. The call to setMaxSpeed() limits the rate at wich the simulator can progress to "real-time". It is helpful to do this while you are setting up your network, because until you have some nodes to simulate, time will advance very quickly.

Finally we create our PastryNodeFactory which is similar to the construction of the SocketPastryNodeFactory, but takes a NetworkSimulator instead of a bindport.

The bootHandle Code:

      NodeHandle bootHandle = ((SocketPastryNodeFactory)factory).getNodeHandle(bootaddress);

has been changed to:

      // this way we can boot off the previous node
      bootHandle = node.getLocalHandle();

The difference being that we don't need to use an InetSocketAddress in the simulator because it is meaningliess in this context.

Once we complete the creation of our network, we go ahead and tell the simulator to run as fast as possible:

        // don't limit the simulation speed anymore
        simulator.setFullSpeed();

One last note: Because some of the network topologies use random coordinates to generate latencies, it can be important to set a minimum delay, in case nodes are specified in the identical, or "very-near" coordinates. In general, it is unlikely to get leas than a 2milli delay between nodes. To specify a minimum delay, you must set the param `pastry_direct_min_delay` to the appropriate value. FreePastry defaults this value to 2 millis. Complie and execute this code as before. Note that it runs much much faster than with the socket transport layer. Here is the example output of this code:

    java -cp .:FreePastry-@freepastry_version@.jar rice.tutorial.direct.DistTutorial 10
    :rice.pastry.direct.DirectPastryNodeFactory:0:No bootstrap node provided, starting a new ring...
    Finished creating new node Pastry node <0x9C1733..>
    Finished creating new node Pastry node <0x8AE001..>
    Finished creating new node Pastry node <0x0CADFD..>
    Finished creating new node Pastry node <0x8682F1..>
    Finished creating new node Pastry node <0xADF8A8..>
    Finished creating new node Pastry node <0x1DF4B2..>
    Finished creating new node Pastry node <0x179344..>
    Finished creating new node Pastry node <0x1158EB..>
    Finished creating new node Pastry node <0x922D50..>
    Finished creating new node Pastry node <0x978B20..>
    MyApp <0x9C1733..> sending to <0xA3ACA6..>
    MyApp <0x9C1733..> received MyMsg from <0x9C1733..> to <0xA3ACA6..>
    MyApp <0x8AE001..> sending to <0x7E9F4A..>
    MyApp <0x0CADFD..> sending to <0x061EA3..>
    MyApp <0x0CADFD..> received MyMsg from <0x0CADFD..> to <0x061EA3..>
    MyApp <0x8682F1..> sending to <0x39641C..>
    MyApp <0xADF8A8..> sending to <0x3697C6..>
    MyApp <0x1DF4B2..> sending to <0x9B0436..>
    MyApp <0x1DF4B2..> received MyMsg from <0xADF8A8..> to <0x3697C6..>
    MyApp <0x1DF4B2..> received MyMsg from <0x8682F1..> to <0x39641C..>
    MyApp <0x8682F1..> received MyMsg from <0x8AE001..> to <0x7E9F4A..>
    MyApp <0x179344..> sending to <0x785330..>
    MyApp <0x1158EB..> sending to <0xEDC192..>
    MyApp <0x922D50..> sending to <0x5ADAEB..>

    ...

### Congratulations! You have just simulated a handful of nodes in FreePastry's Discreet Event Simulator. This should make it much easier to test your application.