source: sample/pingpong/PingPong.cpp@ 12768

Last change on this file since 12768 was 12351, checked in by s_taenzer@…, 11 years ago

Pingpong: Logging with Log4Cxx doesn't allow endls in the middle, use \n instead
Also initialise counter

File size: 7.1 KB
Line 
1#include "PingPong.h"
2#include <boost/property_tree/ptree.hpp>
3#include <boost/property_tree/json_parser.hpp>
4
5using namespace ariba;
6
7namespace ariba {
8namespace application {
9namespace pingpong {
10
11// logging
12use_logging_cpp( PingPong );
13
14// the service that the pingpong wants to use
15ServiceID PingPong::PINGPONG_SERVICEID = ServiceID( 111 );
16
17// construction
18PingPong::PingPong( string config) :
19 node(),
20 counter( 0 ),
21 pingId( 0 ),
22 config_file(config)
23{
24 Timer::setInterval( 5000 );
25}
26
27// destruction
28PingPong::~PingPong() {
29}
30
31// implementation of the startup interface
32void PingPong::startup()
33{
34 using boost::property_tree::ptree;
35 using boost::property_tree::json_parser::read_json;
36
37 // set up logging
38 logging_rootlevel_debug();
39 logging_classlevel_debug(PingPong);
40
41 logging_info( "[PINGPONG]\t starting up PingPong service ... " );
42
43 // read config
44 ptree config;
45 try
46 {
47 read_json(config_file, config);
48 }
49 catch ( exception& e )
50 {
51 logging_warn("ERROR: Failed to read config file »" << config_file << "«: ");
52 logging_warn(e.what());
53 logging_warn("---> Using fallback config.");
54
55 config.put("ariba.spovnet_name", "pingpong");
56 }
57
58 // use node name also in the application
59 name = config.get("ariba.node_name", "NO_NAME");
60
61 // bind communication and node listener
62 node.bind( this ); /*NodeListener*/
63 node.bind( this, PingPong::PINGPONG_SERVICEID); /*CommunicationListener*/
64
65 // connecting
66 logging_debug( "connecting ... " );
67
68 node.connect(config.get_child("ariba"));
69
70 // ping pong started up...
71 logging_info( "[PINGPONG]\t pingpong starting up with"
72 << " [spovnetid " << node.getSpoVNetId().toString() << "]"
73 << " and [nodeid " << node.getNodeId().toString() << "]" );
74}
75
76// implementation of the startup interface
77void PingPong::shutdown() {
78
79 logging_info( "[PINGPONG]\t pingpong service starting shutdown sequence ..." );
80
81 // stop timer
82 Timer::stop();
83
84 // leave spovnet
85 node.leave();
86
87 // unbind communication and node listener
88 node.unbind( this ); /*NodeListener*/
89 node.unbind( this, PingPong::PINGPONG_SERVICEID ); /*CommunicationListener*/
90
91 // now we are completely shut down
92 logging_info( "pingpong service shut down" );
93}
94
95// timer event
96void PingPong::eventFunction()
97{
98 // We ping all nodes that are known in the overlay structure
99 // this can be all nodes (OneHop) overlay or just some neighbors
100 // in case of a Chord or Kademlia structure
101 // NOTE: Currently ariba only supports the Chord overlay.
102
103 // In this sample we use auto-links: we just send out our message
104 // to the node and the link is established automatically. for more
105 // control we would use the node->establishLink function to create
106 // a link and start using the link in the CommunicationListener::onLinkUp
107 // function that is implemented further down in PingPong::onLinkUp
108
109 // NOTE: This example still uses the old deprecated ariba::message messages
110 // with the ariba built-in serialization.
111 // For future applications please use the new reboost::message_t messages.
112 // Data is stored in high efficient zero-copy buffers of type
113 // reboost::shared_buffer_t. These buffers hold plain data, so you have to
114 // serialize the data "on your own".
115 // We recommend third-party serialization libraries like:
116 // - Protocol Buffers (http://en.wikipedia.org/wiki/Protocol_Buffers)
117 // - MessagePack (http://en.wikipedia.org/wiki/MessagePack)
118
119
120 // don't do anything if we have no neighbors
121 if ( node.getNeighborNodes().size() == 0)
122 {
123 logging_info( "[PINGPONG]\t +++ no neighbors +++" );
124 return;
125 }
126
127
128 pingId++;
129 logging_info( "\n|||||||||| >>>>>>>>>>\n"
130 << "[PINGPONG]\t PINGING overlay neighbors with ping id " << pingId );
131 PingPongMessage pingmsg( pingId, name );
132
133 //-----------------------------------------------------------------------
134 // Option 1: get all neighboring nodes and send the message to each
135 //-----------------------------------------------------------------------
136 counter++;
137 if (counter<0 || counter>4) {
138 counter = 0;
139 string s;
140 for (int i=0; i<names.size();i++) {
141 if (i!=0) s+= ", ";
142 s = s+names[i];
143 }
144 logging_info("[PINGPONG]\t ----> I am " << name << " and I know " << s);
145 names.clear();
146 }
147
148 vector<NodeID> nodes = node.getNeighborNodes();
149 BOOST_FOREACH( NodeID nid, nodes ){
150 logging_info( "[PINGPONG]\t sending ping message to " << nid.toString() );
151 node.sendMessage( pingmsg, nid, PingPong::PINGPONG_SERVICEID );
152 }
153
154 //-----------------------------------------------------------------------
155 // Option 2: send a "broadcast message" that actually does the same thing
156 // internally, gets all neighboring nodes and sends the message
157 //-----------------------------------------------------------------------
158 // node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_SERVICEID );
159}
160
161void PingPong::onJoinCompleted( const SpoVNetID& vid ) {
162 logging_info( "pingpong node join completed, spovnetid=" << vid.toString() );
163
164 // start the timer to ping every second
165 Timer::start();
166}
167
168void PingPong::onJoinFailed( const SpoVNetID& vid ) {
169 logging_error("pingpong node join failed, spovnetid=" << vid.toString() );
170}
171
172void PingPong::onLeaveCompleted( const SpoVNetID& vid ){
173 logging_info("pingpong node leave completed, spovnetid=" << vid.toString() );
174}
175
176void PingPong::onLeaveFailed( const SpoVNetID& vid ){
177 logging_error("pingpong node leave failed, spovnetid=" << vid.toString() );
178}
179
180void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) {
181 PingPongMessage* pingmsg = msg.getMessage()->convert<PingPongMessage> ();
182 bool found=false;
183 for (int i=0;i<names.size(); i++) if (names[i]==pingmsg->getName()) found=true;
184 if (!found) names.push_back(pingmsg->getName());
185 logging_info( "\n<<<<<<<<<< ||||||||||\n"
186 << "[PINGPONG]\t RECEIVED ping message on link "
187 << lnk.toString()
188 << " " << (node.isLinkDirect(lnk) ? "[DIRECT-LINK]" : "[INDIRECT-LINK]")
189 << " HopCount: " << node.getHopCount(lnk)
190 << " from node " << remote.toString()
191 << " (" << pingmsg->getName() << ")"
192 << ": " << pingmsg->info() );
193 delete pingmsg;
194}
195
196void PingPong::onLinkUp(const LinkID& lnk, const NodeID& remote){
197 logging_info( "received link-up event for link " << lnk.toString()
198 << " and node " << remote.toString() );
199}
200
201void PingPong::onLinkDown(const LinkID& lnk, const NodeID& remote){
202 logging_info( "received link-down event for link " << lnk.toString()
203 << " and node " << remote.toString() );
204}
205
206void PingPong::onLinkChanged(const LinkID& lnk, const NodeID& remote){
207 logging_info( "link-changed event for link " << lnk.toString()
208 << " and node " << remote.toString() );
209}
210
211bool PingPong::onLinkRequest(const NodeID& remote) {
212 logging_info( "node " << remote.toString() << " wants to build up a link with us ... allowing" );
213 return true;
214}
215
216void PingPong::onLinkFail(const LinkID& lnk, const NodeID& remote){
217 logging_info( "received link-failed event for link " << lnk.toString()
218 << " and node " << remote.toString() );
219}
220
221}}} // namespace ariba, application, pingpong
Note: See TracBrowser for help on using the repository browser.