Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DatabaseQueryWorkUnitManager.hh
Go to the documentation of this file.
1 // (c) Copyright Rosetta Commons Member Institutions.
2 // (c) This file is part of the Rosetta software suite and is made available under license.
3 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
4 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
5 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
6 
7 /// @file DatabaseQueryWorkUnitManager.hh
8 ///
9 /// @brief An MPI work unit manager that runs a given database query and creates a DatabaseEntryWorkUnit for each of the result rows. This class is templated such
10 /// that the specific type of DatabaseEntryWorkUnit created is the template class.
11 
12 /// @author Tim Jacobs
13 
14 #ifndef INCLUDED_protocols_wum_DatabaseQueryWorkUnitManager_hh
15 #define INCLUDED_protocols_wum_DatabaseQueryWorkUnitManager_hh
16 
17 //Unit
19 
22 
23 //Core
24 #include <core/types.hh>
25 
26 //Utility and basic
27 #include <basic/database/sql_utils.hh>
28 
29 #include <utility/sql_database/DatabaseSessionManager.hh>
30 #include <utility/string_util.hh>
31 
32 //Basic
33 #include <basic/Tracer.hh>
34 
35 //C++
36 #include <string>
37 #include <map>
38 
39 static basic::Tracer TR("protocols.wum.DatabaseQueryWorkUnitManager");
40 
41 namespace protocols{
42 namespace wum{
43 
44 template <class T>
46 public:
47 
48  DatabaseQueryWorkUnitManager(core::Size master_rank, utility::sql_database::sessionOP db_session, std::string query_string, std::string wu_type);
49 
50  //void set_defaults();
51 
53 
54  virtual void go();
55 
56 protected: // overloaded functions
57 
58  virtual void init(){/*no resume functionality yet*/}
59 
60  virtual void process_inbound_wus();
61 
62  virtual void process_outbound_wus();
63 
64 protected: // added functions
65 
67 
68 protected: // Accesors
69 
71 
73 
74 private:
75 
76  // static settings
79 
80  // database specific
81  utility::sql_database::sessionOP db_session_;
83 };
84 
85 template <class T>
86 DatabaseQueryWorkUnitManager<T>::DatabaseQueryWorkUnitManager(core::Size master_rank, utility::sql_database::sessionOP db_session, std::string query_string, std::string wu_type):
87 MPI_WorkUnitManager( 'M' ),
88 my_emperor_(0),
89 master_rank_( master_rank ),
90 db_session_( db_session ),
91 query_string_(query_string)
92 {
94 }
95 
96 template <class T>
97 void
99  using cppdb::statement;
100  using cppdb::result;
101  using namespace std;
102 
103  //ensure that template class is derived from database entry work unit
104  // BOOST_CONCEPT_ASSERT((DatabaseEntryWorkUnit<T>));
105 
106  TR << "Adding DB WU for each row in query result" << std::endl;
107 
108  statement query_statement(basic::database::safely_prepare_statement(query_string_,db_session_));
109 
110  result res(basic::database::safely_read_from_database(query_statement));
111 
112  core::Size wu_counter = 0;
113  while(res.next()){
114  ++wu_counter;
115 
116  map<string,string> row_map;
117 
118  for(int i=0; i<res.cols(); ++i){
119  string key(res.name(i));
120 
121  string value("");
122  res.fetch(i,value);
123 
124  row_map[key]=value;
125  }
126 
127  //create the speicific
128  // T new_wu = new T(row_map);
129  // new_wu->set_wu_type(wu_type);
130 
131  DatabaseEntryWorkUnitOP new_wu = new T(row_map);
132  new_wu->set_wu_type(wu_type);
133 
134  outbound().add( new_wu );
135  }
136  TR << "Added " << wu_counter << " database WUs to queue" << endl;
137 }
138 
139 template <class T>
140 void
142  // initialize master (this is a virtual function call and this function is overloaded by the children of this class)
143  TR << "Init Master: " << protocols::wum::mpi_rank() << std::endl;
144  init();
145 
146  TR << "Master Node: Waiting for job requests..." << std::endl;
147  while(true){
148 
149  //check the outbound queue and send MPI messages accordingly - If nothing outbound then prepare to recieve MPI messages.
150  //The tag of the MPI message dictates the next action (ie. sending a work unit/recieving a work unit)
151  TR << "Master: processing msgs.." << std::endl;
152  process_incoming_msgs();
153 
154  //Collect all the incoming work units, cast them to the proper type and execute their jobs
155  TR << "Master: process incoming" << std::endl;
156  process_inbound_wus();
157 
158  TR << "Master: process outbound" << std::endl;
159  process_outbound_wus();
160 
161  // ok, we've done all our work, now wait until we hear from our slaves
162  process_incoming_msgs( true );
163 
164  print_stats_auto();
165  }
166 }
167 
168 /// @brief Process the inbound WUs (these will be the same DB work units send during the constructor - but now they have the data we want).
169 template <class T>
170 void
172 
173  if( inbound().size() > 0 ){
174  TR << "Processing inbound WUs on master.." << std::endl;
175  }
176 
177  //Create a database transaction for all database queries created by the slaves
178  db_session_->begin();
179  while( inbound().size() > 0 )
180  {
181  protocols::wum::WorkUnitBaseOP next_wu = inbound().pop_next();
182  runtime_assert( next_wu );
183 
184  // skip returning waiting WUs
185  if ( next_wu->get_wu_type() == "waitwu" ) continue;
186 
187  // Upcast to a DatabaseEntryWorkUnit WU
188  DatabaseEntryWorkUnit* db_wu = dynamic_cast< DatabaseEntryWorkUnit * > ( (protocols::wum::WorkUnitBase*) (&(*next_wu)) );
189 
190  // If upcast was unsuccessful - warn and ignore.
191  if ( db_wu == NULL ){
192  TR << "WARNING: Master recieved a non-db WU" << std::endl;
193  next_wu->print( TR );
194  continue;
195  }
196 
197  cppdb::statement query_statement(basic::database::safely_prepare_statement(db_wu->result_query_string(),db_session_));
198  basic::database::safely_write_to_database(query_statement);
199 
200  }
201  //Commit the transaction
202  db_session_->commit();
203 }
204 
205 /// @brief create the database WUs and add them to the outgoing queue
206 template <class T>
207 void
209  //All outbound wus are taken care of in the constructor
210 }
211 
212 } //namespace wum
213 } //namespace protocols
214 
215 #endif