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@.



Timer

Scheduling tasks on the FreePastry timer.

Download the tutorial files: DistTutorial.java, MyApp.java into a directory called rice/tutorial/timer/.

This tutorial will show you how to schedule a task on the FreePastry thread. To be compatible with the commonAPI, the approach is to schedule a message to be sent to yourself at a regular interval.

Let's start with the changes to MyApp.

First a simple message.

  class MessageToSelf implements Message {
    public int getPriority() {
      return 0;
    }    
  }

Note that due to laziness, I have constructed this Message as an inner class of MyApp. This is fine for what we are going to use it for, but beware that it you will get a NotSerializableException if you attempt to send this message over the wire. While the Message may be serializable it has an implicit reference to MyApp, the containing class. When the message is serialized, FreePastry will also attempt to serialize MyApp which will fail and throw the exception.

Here is the change to the constructor of MyApp, where we schedule the MessageToSelf. The first parameter is the Message that will be sent to MyApp. The second is the delay (in millis) until it is first sent. The third parameter is the period at which the message should be repeated.

    // Send MessageToSelf every 5 seconds, starting in 3 seconds
    messageToSelfTask = endpoint.scheduleMessage(new MessageToSelf(), 3000, 5000);

As you can see, we have asked FreePastry to deliver the MessageToSelf in 3 seconds, and then continue to deliver it again every 5 seconds. Note that there is also a version of scheduleMessage() that doesn't take the 3rd parameter, and therefore doesn't repeat.

We stored the task as a member variable so that we can cancel it later.

  CancellableTask messageToSelfTask;

Whenever we receive the MessageToSelf we are just going to print out the current time. However, in your application you could call a method to do periodic maintenance, send messages to other nodes etc.

  public void deliver(Id id, Message message) {
    System.out.println(this+" received "+message);
    if (message instanceof MessageToSelf) {
      // This will get called every 5 seconds, on Pastry's thread.
      // Thus now we can assume we are on Pastry's thread.
      // TODO: whatever... send messages to other nodes? print out status?
      System.out.println("I got the MessageToSelf at time:"+System.currentTimeMillis());
    }
  }

Finally, we make a public method to cancel the task.

  public void cancelTask() {
    messageToSelfTask.cancel(); 
  }

The DistTutorial.java is based on lesson3, but we removed the code to print the leafset. For this example it is unnecessary to launch multiple pastry nodes, so we will only launch one. We added a bit of code after constructing the MyApp to cancel the task after 15 seconds.

    // construct a new MyApp
    MyApp app = new MyApp(node);
    
    // wait 15 seconds
    env.getTimeSource().sleep(15000);
    
    // cancel the task
    app.cancelTask();

Ok, time to run it! Your output should resemble the following:

java -cp .:FreePastry-@freepastry_version@.jar rice.tutorial.timer.DistTutorial 9001 localhost 9001
:1122932166578:Error connecting to address /10.9.8.7:9001: java.net.ConnectException: Connection refused: no further information
:1122932166578:No bootstrap node provided, starting a new ring...
Finished creating new node SocketNodeHandle (<0x3C1EEA..>/FOO/10.9.8.7:9001 [9038308767327354496])
MyApp <0x3C1EEA..> received rice.tutorial.timer.MyApp$MessageToSelf@d70d7a
I got the MessageToSelf at time:1115228553359
MyApp <0x3C1EEA..> received rice.tutorial.timer.MyApp$MessageToSelf@d70d7a
I got the MessageToSelf at time:1115228558359
MyApp <0x3C1EEA..> received rice.tutorial.timer.MyApp$MessageToSelf@d70d7a
I got the MessageToSelf at time:1115228563359

Congratulations! Now you can schedule and cancel tasks without launching your own thread.