ReadHandler Changes - FREEDM-DGI/FREEDM GitHub Wiki

I've just pushed quite a few changes to how messages are handled to the master branch. The most significant part of this change is that the ReadHandlers in GroupManagement, LoadBalancing and StateCollection are now divided into smaller functions. A full list of what I've changed is below:

  1. Changed lbagent to be LBAgent to match the naming convention of the other modules.
  2. Removed HandleRead from all modules, and removed its virtual attribute.
  3. Removed SCPeerNode, LBPeerNode, and GMPeerNode, since they were largely unused. Enumerations provided by those classes were folded into their respective agents since that was the only place they were ever used. PeerNodePtr is now the PeerNodeType for all modules.
  4. Changed the capitalization of PeerList to Peerlist
  5. Created a global store of peers, CGlobalPeerList, which can be accessed for reading by any module. This store contains every peer known to the system, not just the ones in the group. Only group management and the handler base class can add peers to the store.
  6. I've provided a static method in GMAgent (GMAgent::ProcessPeerlist) which eliminates the duplicate code for parsing the Peerlists received by modules. This function returns a PeerSet of the peers which are in the group which will include the Group Leader
  7. Created a new common attribute for messages called "Handler" which determines which module handlers will process a message. It can be accessed by using SetHandler() or GetHandler(). This replaces calls which used to look like msg.m_submessages.put("lb","demand") with calls that look like msg.SetHandler("lb.demand")

Creating Handlers

Handlers always have the function signature void HandlerTYPE(CMessage msg, PeerNodePtr peer). Note the new argument peer. The handler will be passed a PeerNodePtr of the Peer which sent the message to the module. This peer is guaranteed to exist (ie it will never be null).

Handlers have to be registered in the constructor. This can be done with a call similiar to RegisterSubhandle("any.peerlist",boost::bind(&GMAgent::HandlePeerlist, this, _1, _2)); where any.peerlist is what the value of GetHandler() must be for the specified handler (The bound function) to be called.

Handlers are processed in FIFO order, and only the first matched handler will be used. Note also that using the string "any" for the handler will process any message. Therefore any handler registered after an any handler message will never be called.

Handlers should be documented with a special extra doxygen tag "@key" which indicates the handler that will trigger the message. An example is below:

///////////////////////////////////////////////////////////////////////////////
/// GMAgent::HandleAccept
/// @description Handles recieveing the invite accept
/// @key gm.Accept
/// @pre Precondition
/// @post Postcondition
///////////////////////////////////////////////////////////////////////////////`