An Example of a Single-Threaded Maestro Application

This document is a part of online Ensemble documentation, under Maestro Open Toolkit.

The program in the example below defines a subclass (called Mbr) of the Maestro_GroupMember class. Note that multicast, view, and heartbeat callbacks (which are no-op in the base class) are overloaded to implement application-specific functionality.

In the main function, several Mbr objects are created and join the group. Note that all group-member objects are created with the same threading mode (MAESTRO_MODE_SINGLE_THREADED).

In the single-threaded mode, all downcalls to group-member objects can only be done from within group-callback methods. In this example, all multicast messages are sent from within heartbeat callbacks.



#include "Maestro.h"
#define NMEMBERS 10

class  Mbr: public Maestro_GroupMember {
public:

  // Initialize the group-member object and join the group.
  Mbr(Maestro_GrpMemb_Options &ops) : Maestro_GroupMember(ops) {
    join();			// Join the group
  }

protected:

  // This callback is invoked when a multicast message is received.
  void grpMemb_ReceiveCast_Callback(Maestro_EndpID &origin,
				    Maestro_Message &msg) {
    Maestro_String contents;
    msg >> contents;
    cout << "CAST from " << origin << ": " << contents << endl;
  }

  // This callback is invoked when a new view is accepted.
  void grpMemb_AcceptedView_Callback(Maestro_GrpMemb_ViewData &viewData,
				     Maestro_Message &msg) {
    cout << "Accepted View: " << viewData.members << endl ;
  }

  // This callback is invoked periodically. 
  void grpMemb_Heartbeat_Callback(unsigned time) { 
    Maestro_Message msg;
    Maestro_String contents("hello");
    msg << contents;
    cast(msg);			// Send a multicast message.
  }
};

main(int argc, char *argv[]) {
  Mbr *m[NMEMBERS];
  int i;

  Maestro_GrpMemb_Options ops;
  ops.heartbeatRate = 1000;	// Schedule a heartbeat every 1000 msec.

  ops.groupName = "lapa";
  ops.protocol = "Top:Heal:Switch:Leave:Inter:Intra:Elect:Merge:Sync:Suspect:Top_appl:Pt2pt:Frag:Stable:Mnak:Bottom";
  ops.transports = "UDP";
  ops.programName = argv[0];

  // Start Maestro/Ensemble in single-threaded mode.
  ops.threadMode = MAESTRO_MODE_SINGLE_THREADED;

  // Create NMEMBERS group-member objects.
  for (i = 0; i < NMEMBERS; i++)
    m[i] = new Mbr(i, ops);

  // Start Maestro/Ensemble.  
  // Note that Maestro_GroupMember::start() function does not return.
  Maestro_String progName(argv[0]);
  Maestro_GroupMember::start(progName);
  assert(0);
}


send mail to alexey@cs.cornell.edu