DaZeus  2.0
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
dazeus.cpp
Go to the documentation of this file.
1 
6 #include "dazeus.h"
7 #include "database.h"
8 #include "network.h"
9 #include "config.h"
10 #include "plugincomm.h"
11 #include "pluginmonitor.h"
12 #include <cassert>
13 #include <sstream>
14 #include <iostream>
15 
16 // #define DEBUG
17 #define VERBOSE
18 
25 dazeus::DaZeus::DaZeus( std::string configFileName )
26 : config_( 0 )
27 , configFileName_( configFileName )
28 , plugins_( 0 )
29 , plugin_monitor_( 0 )
30 , database_( 0 )
31 , networks_()
32 , running_(false)
33 {
34 }
35 
36 
41 {
42  std::vector<Network*>::iterator it;
43  for(it = networks_.begin(); it != networks_.end(); ++it)
44  {
45  (*it)->disconnectFromNetwork( Network::ShutdownReason );
46  delete *it;
47  }
48  networks_.clear();
49 
50  delete plugin_monitor_;
51  delete plugins_;
52  delete config_;
53  delete database_;
54 }
55 
56 
64 {
65 #ifdef DEBUG
66  fprintf(stderr, "dazeus::DaZeus::autoConnect() called: looking for networks to connect to\n");
67 #endif
68  std::vector<Network*>::iterator it;
69  for(it = networks_.begin(); it != networks_.end(); ++it)
70  {
71  Network *n = *it;
72  if( n->autoConnectEnabled() )
73  {
74 #ifdef DEBUG
75  fprintf(stderr, "Connecting to %s (autoconnect is enabled)\n", Network::toString(n).c_str());
76 #endif
77  n->connectToNetwork();
78  }
79 #ifdef DEBUG
80  else
81  {
82  fprintf(stderr, "Not connecting to %s, autoconnect is disabled.\n", Network::toString(n).c_str());
83  }
84 #endif
85  }
86 }
87 
88 
89 std::string dazeus::DaZeus::configFileName() const {
90  return configFileName_;
91 }
92 
97 {
98  return config_->isRead();
99 }
100 
101 
108 {
109  const DatabaseConfig *dbc = config_->getDatabaseConfig();
110  if(dbc == 0) {
111  fprintf(stderr, "Database configuration is absent, cannot continue.\n");
112  return false;
113  }
114  database_ = new Database(dbc->hostname, dbc->port, dbc->database, dbc->username, dbc->password);
115 
116  if( !database_->open() )
117  {
118  fprintf(stderr, "Could not connect to database: %s\n", database_->lastError().c_str());
119  return false;
120  }
121 
122  return true;
123 }
124 
129 {
130  return database_;
131 }
132 
133 
134 
139 {
140  assert(plugins_ != 0);
141  plugins_->init();
142 
143  return true;
144 }
145 
146 
155 {
156  assert( configFileName_.length() != 0 );
157 
158  if( config_ != 0 ) {
159  delete config_;
160  }
161 
162  config_ = new ConfigReader(configFileName_);
163 
164  if( !config_ )
165  return false;
166 
167  try {
168  config_->read();
169  } catch(ConfigReader::exception &e) {
170  std::cerr << "Failed to read configuration: " << e.what() << std::endl;
171  return false;
172  }
173 
174  const std::vector<NetworkConfig*> &networks = config_->getNetworks();
175 
176  if(!connectDatabase()) {
177  delete config_;
178  config_ = 0;
179  return false;
180  }
181 
182  if(plugins_)
183  delete plugins_;
184  plugins_ = new PluginComm( database_, config_, this );
185  plugin_monitor_ = new PluginMonitor(config_->getPluginSocket(),
186  config_->getGlobalConfig()->plugindirectory,
187  config_->getPlugins(),
188  config_->getNetworks());
189 
190  std::vector<NetworkConfig*>::const_iterator it;
191  for(it = networks.begin(); it != networks.end(); ++it)
192  {
193  Network *net = new Network( *it );
194  net->addListener(plugins_);
195  if( net == 0 ) {
196  delete config_;
197  config_ = 0;
198  return false;
199  }
200 
201  networks_.push_back( net );
202  }
203 
204  // Pretty number of initialisations viewer -- and also an immediate database
205  // check.
206  std::stringstream numInitsStr;
207  numInitsStr << database_->property("dazeus.numinits");
208  int numInits;
209  numInitsStr >> numInits;
210  if(!numInitsStr)
211  numInits = 0;
212  ++numInits;
213  numInitsStr.str(""); numInitsStr.clear();
214  numInitsStr << numInits;
215  database_->setProperty("dazeus.numinits", numInitsStr.str());
216  const char *suffix = "th";
217  if(numInits%100 == 11 ) ;
218  else if(numInits%100 == 12) ;
219  else if(numInits%100 == 13) ;
220  else if(numInits%10 == 1) suffix = "st";
221  else if(numInits%10 == 2) suffix = "nd";
222  else if(numInits%10 == 3) suffix = "rd";
223  printf("Initialising DaZeus for the %d%s time!\n", numInits, suffix);
224  return true;
225 }
226 
228 {
229  plugin_monitor_->sigchild();
230 }
231 
233 {
234  running_ = false;
235 }
236 
238 {
239  running_ = true;
240  while(running_) {
241  plugin_monitor_->runOnce();
242  // The only non-socket processing in DaZeus is done by the
243  // plugin monitor. It works using signals (primarily SIGCHLD),
244  // which already interrupt select(). However, its timing in
245  // re-starting plugins has a granularity of 5 seconds, so if it
246  // is waiting to restart a plugin, we will decrease our timeout
247  // length to once every second. If it is in a normal state, we
248  // can use any granularity we want.
249  plugins_->run(plugin_monitor_->shouldRun() ? 1 : 30);
250  }
251 }
252 
253 void dazeus::DaZeus::setConfigFileName(std::string filename) {
254  configFileName_ = filename;
255 }