00001 #include <mcp.H>
00002 #include <WURDEConfiguration.H>
00003
00004 using namespace WURDE;
00005 using namespace std;
00006
00007 namespace MCP{
00008
00009
00010 Module::Module(string name):
00011 m_lastTimestamp()
00012 {
00013 m_moduleName=name;
00014
00015 m_TTL.tv_sec=1;
00016 m_TTL.tv_usec=0;
00017 g_logdebug << "new module with name " << name << endl;
00018
00019 m_state=STATE_NULL;
00020 m_locale=LOCALE_NULL;
00021 m_managedType=PROC_NULL;
00022 m_attemptedStarts=0;
00023 m_maxAttempts=3;
00024 }
00025
00026 Module::Module() {
00027 m_lastTimestamp.zero();
00028 m_moduleName="unknown";
00029 m_TTL.tv_sec=1;
00030 m_TTL.tv_usec=0;
00031 m_state=STATE_NULL;
00032 m_locale=LOCALE_NULL;
00033 m_managedType=PROC_NULL;
00034 m_attemptedStarts=0;
00035 m_maxAttempts=3;
00036 }
00037
00038 Module::Module(HeartbeatInfoStruct &info){
00039 setModuleName(info.source);
00040 refresh(info);
00041 m_attemptedStarts=0;
00042 m_maxAttempts=3;
00043 }
00044
00045 Module::Module(HeartbeatDataStruct &data){
00046 setModuleName(data.source);
00047 beat(data);
00048 m_attemptedStarts=0;
00049 m_maxAttempts=3;
00050 }
00051
00052 bool Module::stale(){
00053 Time temp(m_TTL), current;
00054 current.now();
00055 temp=temp+temp+temp+m_lastTimestamp;
00056
00057 if(current>=temp){
00058 return true;
00059 }
00060
00061 return false;
00062 }
00063
00064 void Module::setTTL(double seconds){
00065 int count=0;
00066 while(seconds>0){
00067 seconds--;
00068 count++;
00069 }
00070
00071 m_TTL.tv_sec=count;
00072 m_TTL.tv_usec=(unsigned long)(1000000.0*seconds);
00073 }
00074
00075 bool Module::beat(HeartbeatDataStruct beat){
00076 string buffer="New beat for " + m_moduleName;
00077 if(beat.source!=m_moduleName){
00078 g_error("Beat called with wrong module heartbeat");
00079 return false;
00080 }
00081
00082 m_lastTimestamp=beat.timestamp;
00083 setTTL(beat.TTL);
00084
00085
00086
00087 return true;
00088 }
00089
00090 bool Module::refresh(HeartbeatInfoStruct info){
00091 if(info.source!=m_moduleName){
00092 g_error("Refresh called with wrong module info");
00093 return false;
00094 }
00095
00096
00097
00098 if(info.state.getValue()==STATE_INFO){
00099
00100 m_interfaces.clear();
00101
00102 m_interfaces=info.interfaces.getValue();
00103 vector<InterfaceStream>::iterator m_iter;
00104 #ifdef FULL_DEBUG
00105
00106
00107
00108 #endif
00109 setState(STATE_INACTIVE);
00110 g_logdebug << "Got stream information from " << m_moduleName << endl;
00111 }else if(info.state.getValue()==STATE_QUIT){
00112 setState(STATE_INACTIVE);
00113 g_debug("Got a quit");
00114 }else{
00115 g_debug("Some other info");
00116 setState(info.state.getValue());
00117 setType(info.managedType.getValue());
00118 setLocale(info.locale.getValue());
00119 }
00120 return true;
00121 }
00122
00126 string Module::findObjectMapping(string object, string interface, ConnectionStrategy strat){
00127 vector<Mapping>::iterator iter;
00128 string retval;
00129 bool found=false;
00130 char logbuf[1024];
00131
00132 sprintf(logbuf, "Looking for a module that can fulfill %s for %s",interface.c_str(),object.c_str());
00133 g_debug(logbuf);
00134
00135 if(strat==STRAT_ASSIGNED){
00136 g_debug("looking for assigned...");
00137
00138 for(iter=m_mappings.begin();iter!=m_mappings.end();iter++){
00139 if(iter->object==object&&iter->interface==interface){
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 retval=iter->source;
00150 found=true;
00151 break;
00152 }else{
00153 g_logdebug << "Found " << iter->object << " for " << iter->interface << " , but it's not what we want. " << endl;
00154 }
00155 }
00156 if(found){
00157 sprintf(logbuf, "Found %s", retval.c_str());
00158 g_debug(logbuf);
00159 return retval;
00160 }else{
00161 g_debug("Found nothing");
00162 return "";
00163 }
00164 }else if(strat==STRAT_NORMAL){
00165
00166 for(iter=m_mappings.begin();iter!=m_mappings.end();iter++){
00167
00168 if(iter->interface==interface){
00169
00170
00171
00172
00173
00174
00175 retval=iter->source;
00176
00177 found=true;
00178
00179 break;
00180 }else{
00181
00182 }
00183 }
00184
00185 if(found){
00186 sprintf(logbuf,"Found %s",retval.c_str());
00187 g_debug(logbuf);
00188 return retval;
00189 }else{
00190 g_debug("Found nothing");
00191 return "";
00192 }
00193 }else{
00194
00195
00196
00197 }
00198 return "";
00199 }
00200
00201
00202 void Module::addInterface(string interface, string name){
00203 InterfaceStream someinterface;
00204
00205 someinterface.type=interface;
00206 someinterface.streamname=name;
00207 m_interfaces.push_back(someinterface);
00208 }
00209
00210 bool Module::hasSupplier(string streamname,string type){
00211 vector<InterfaceStream>::iterator iter;
00212 char logbuf[1024];
00213 sprintf(logbuf,"Looking for %s of type %s in module %s",streamname.c_str(),type.c_str(),m_moduleName.c_str());
00214 g_debug(logbuf);
00215 for(iter=m_interfaces.begin();iter!=m_interfaces.end();iter++){
00216 if((iter->type==type)&&(iter->streamname==streamname)){
00217 return true;
00218 }else{
00219
00220 }
00221 }
00222 g_debug("Didn't find the supplier we were looking for");
00223 return false;
00224 }
00225
00226 bool Module::startUp(CommsManager &myManager, string someArgs){
00227 FILE *testhandle=NULL;
00228 string fullbinary;
00229 if(m_binary=="empty"){
00230 g_logdebug << "No binary for module " << m_moduleName << ". Continuing on." << endl;
00231 return true;
00232 }
00233 if(m_binary[0]!='/'){
00234 fullbinary=g_globalConfiguration.getBinDirectory()+"/"+m_binary;
00235 }else{
00236 fullbinary=m_binary;
00237 }
00238
00239 char buffer[512];
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 g_logdebug << "Using binary " << fullbinary << endl;
00251
00252
00253 const char *options[m_options.size()+3];
00254 options[0]=fullbinary.c_str();
00255 for(unsigned int i=0;i<m_options.size();i++){
00256 options[i+1]=m_options[i].c_str();
00257 }
00258 options[m_options.size()+1]=someArgs.c_str();
00259 options[m_options.size()+2]=NULL;
00260
00261 std::string logdir=g_globalConfiguration.getLogDirectory();
00262
00263
00264 switch(m_state){
00265 case STATE_RUN:
00266 case STATE_RESTART:
00267 case STATE_RESET:
00268 case STATE_STARTUP:
00269 return true;
00270 case STATE_FAIL:
00271 return false;
00272 default:
00273 break;
00274 }
00275
00276 testhandle=fopen(fullbinary.c_str(),"r");
00277
00278 if(testhandle){
00279 fclose(testhandle);
00280 m_lastTimestamp.now();
00281 m_state=STATE_STARTUP;
00282
00283 m_process=fork();
00284 if(m_process==0){
00285 myManager.closeConnections();
00286
00287 setsid();
00288 sprintf(buffer,"%s/%s-stdout",logdir.c_str(),m_moduleName.c_str());
00289 freopen(buffer,"w",stdout);
00290 sprintf(buffer,"%s/%s-stderr",logdir.c_str(),m_moduleName.c_str());
00291 freopen(buffer,"w",stderr);
00292 cout << "Invoking #" << fullbinary << "# with options:";
00293 for(int i=0;i<m_options.size();i++){
00294 cout << " " << m_options[i];
00295 }
00296 cout << endl;
00297
00298
00299
00300 execvp(fullbinary.c_str(),(char * const *)options);
00301 cout << "Something went wrong starting up the binary: " << fullbinary << ". it was : " << strerror(errno) << endl;
00302 exit(-1);
00303
00304 }
00305 return true;
00306 }else{
00307
00308 g_logerror << "Binary location for module " << m_moduleName << " is incorrect: " << fullbinary << " shortname: " << m_binary << endl;
00309 return false;
00310 }
00311 return false;
00312 }
00313
00314 }