source: src/Fragmentation/Automation/FragmentController.cpp@ dba6d1

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since dba6d1 was dba6d1, checked in by Frederik Heber <heber@…>, 13 years ago

Added FragmentController::getPresentJobs().

  • Property mode set to 100644
File size: 14.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2011 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * FragmentController.cpp
10 *
11 * Created on: Nov 27, 2011
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20// boost asio needs specific operator new
21#include <boost/asio.hpp>
22
23#include "CodePatterns/MemDebug.hpp"
24
25#include <boost/bind.hpp>
26#include <boost/foreach.hpp>
27#include <iostream>
28#include <vector>
29#include "Connection.hpp" // Must come before boost/serialization headers.
30#include <boost/serialization/vector.hpp>
31#include "CodePatterns/Info.hpp"
32#include "CodePatterns/Log.hpp"
33#include "FragmentJob.hpp"
34#include "FragmentResult.hpp"
35#include "ControllerChoices.hpp"
36
37#include "FragmentController.hpp"
38
39/** Constructor of class FragmentController.
40 *
41 * \param io_service io_service for the asynchronous operations
42 * \param _host hostname of server that accepts jobs
43 * \param _service of server
44 */
45FragmentController::FragmentController(
46 boost::asio::io_service& io_service,
47 const std::string& _host,
48 const std::string& _service) :
49 connection_(io_service),
50 host(_host),
51 service(_service),
52 Exitflag(OkFlag)
53{
54 Info info(__FUNCTION__);
55}
56
57/** Destructor of class FragmentController.
58 *
59 */
60FragmentController::~FragmentController()
61{}
62
63/** Handle completion of a connect operation.
64 *
65 * \param e error code if something went wrong
66 * \param endpoint_iterator endpoint of the connection
67 */
68void FragmentController::handle_connect_calc(const boost::system::error_code& e,
69 boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
70{
71 Info info(__FUNCTION__);
72 if (!e)
73 {
74 // Successfully established connection. Give choice.
75 enum ControllerChoices choice = ReceiveJobs;
76 connection_.async_write(choice,
77 boost::bind(&FragmentController::handle_SendJobs, this,
78 boost::asio::placeholders::error));
79 } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
80 // Try the next endpoint.
81 connection_.socket().close();
82 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
83 connection_.socket().async_connect(endpoint,
84 boost::bind(&FragmentController::handle_connect_calc, this,
85 boost::asio::placeholders::error, ++endpoint_iterator));
86 } else {
87 // An error occurred. Log it and return. Since we are not starting a new
88 // operation the io_service will run out of work to do and the client will
89 // exit.
90 Exitflag = ErrorFlag;
91 ELOG(1, e.message());
92 }
93}
94
95/** Handle completion of a connect operation.
96 *
97 * \param e error code if something went wrong
98 * \param endpoint_iterator endpoint of the connection
99 */
100void FragmentController::handle_connect_check(const boost::system::error_code& e,
101 boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
102{
103 Info info(__FUNCTION__);
104 if (!e)
105 {
106 // Successfully established connection. Give choice.
107 enum ControllerChoices choice = CheckState;
108 connection_.async_write(choice,
109 boost::bind(&FragmentController::handle_ReceiveDoneJobs, this,
110 boost::asio::placeholders::error));
111 } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
112 // Try the next endpoint.
113 connection_.socket().close();
114 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
115 connection_.socket().async_connect(endpoint,
116 boost::bind(&FragmentController::handle_connect_check, this,
117 boost::asio::placeholders::error, ++endpoint_iterator));
118 } else {
119 // An error occurred. Log it and return. Since we are not starting a new
120 // operation the io_service will run out of work to do and the client will
121 // exit.
122 Exitflag = ErrorFlag;
123 ELOG(1, e.message());
124 }
125}
126
127/** Handle completion of a connect operation.
128 *
129 * \param e error code if something went wrong
130 * \param endpoint_iterator endpoint of the connection
131 */
132void FragmentController::handle_connect_get(const boost::system::error_code& e,
133 boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
134{
135 Info info(__FUNCTION__);
136 if (!e)
137 {
138 // Successfully established connection. Give choice.
139 enum ControllerChoices choice = SendResults;
140 connection_.async_write(choice,
141 boost::bind(&FragmentController::handle_ReceivingResults, this,
142 boost::asio::placeholders::error));
143 } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
144 // Try the next endpoint.
145 connection_.socket().close();
146 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
147 connection_.socket().async_connect(endpoint,
148 boost::bind(&FragmentController::handle_connect_check, this,
149 boost::asio::placeholders::error, ++endpoint_iterator));
150 } else {
151 // An error occurred. Log it and return. Since we are not starting a new
152 // operation the io_service will run out of work to do and the client will
153 // exit.
154 Exitflag = ErrorFlag;
155 ELOG(1, e.message());
156 }
157}
158
159/** Handle completion of a connect operation.
160 *
161 * \param e error code if something went wrong
162 * \param endpoint_iterator endpoint of the connection
163 */
164void FragmentController::handle_connect_shutdown(const boost::system::error_code& e,
165 boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
166{
167 Info info(__FUNCTION__);
168 if (!e)
169 {
170 // Successfully established connection. Give choice.
171 enum ControllerChoices choice = Shutdown;
172 connection_.async_write(choice,
173 boost::bind(&FragmentController::handle_FinishOperation, this,
174 boost::asio::placeholders::error));
175 } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
176 // Try the next endpoint.
177 connection_.socket().close();
178 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
179 connection_.socket().async_connect(endpoint,
180 boost::bind(&FragmentController::handle_connect_calc, this,
181 boost::asio::placeholders::error, ++endpoint_iterator));
182 } else {
183 // An error occurred. Log it and return. Since we are not starting a new
184 // operation the io_service will run out of work to do and the client will
185 // exit.
186 Exitflag = ErrorFlag;
187 ELOG(1, e.message());
188 }
189}
190
191/** Callback function when operation has been completed.
192 *
193 * \param e error code if something went wrong
194 */
195void FragmentController::handle_FinishOperation(const boost::system::error_code& e)
196{
197 Info info(__FUNCTION__);
198 if (!e)
199 {
200 LOG(1, "INFO: Operation completed.");
201 }
202 else
203 {
204 // An error occurred.
205 Exitflag = ErrorFlag;
206 ELOG(1, e.message());
207 }
208
209 // Since we are not starting a new operation the io_service will run out of
210 // work to do and the client will exit.
211}
212
213/** Callback function when jobs have been sent.
214 *
215 * \param e error code if something went wrong
216 */
217void FragmentController::handle_SendJobs(const boost::system::error_code& e)
218{
219 Info info(__FUNCTION__);
220 if (!e)
221 {
222 // Successfully established connection. Start operation to read the vector
223 // of jobs. The connection::async_write() function will automatically
224 // encode the data that is written to the underlying socket.
225 LOG(1, "INFO: Sending "+toString(jobs.size())+" jobs ...");
226 connection_.async_write(jobs,
227 boost::bind(&FragmentController::handle_FinishOperation, this,
228 boost::asio::placeholders::error));
229 }
230 else
231 {
232 // An error occurred.
233 Exitflag = ErrorFlag;
234 ELOG(1, e.message());
235 }
236
237 // Since we are not starting a new operation the io_service will run out of
238 // work to do and the client will exit.
239}
240
241/** Callback function when results have been received.
242 *
243 * \param e error code if something went wrong
244 */
245void FragmentController::handle_ReceivingResults(const boost::system::error_code& e)
246{
247 Info info(__FUNCTION__);
248 if (!e)
249 {
250 // The connection::async_read() function will automatically
251 // decode the data that is written to the underlying socket.
252 connection_.async_read(results,
253 boost::bind(&FragmentController::handle_ReceivedResults, this,
254 boost::asio::placeholders::error));
255 }
256 else
257 {
258 // An error occurred.
259 Exitflag = ErrorFlag;
260 ELOG(1, e.message());
261 }
262
263 // Since we are not starting a new operation the io_service will run out of
264 // work to do and the client will exit.
265}
266
267/** Callback function when doneJobs have been received.
268 *
269 * \param e error code if something went wrong
270 */
271void FragmentController::handle_ReceivedResults(const boost::system::error_code& e)
272{
273 Info info(__FUNCTION__);
274
275 LOG(1, "INFO: Received "+toString(results.size())+" results ...");
276
277 handle_FinishOperation(e);
278}
279
280/** Callback function when doneJobs have been received.
281 *
282 * \param e error code if something went wrong
283 */
284void FragmentController::handle_ReceiveDoneJobs(const boost::system::error_code& e)
285{
286 Info info(__FUNCTION__);
287 if (!e)
288 {
289 // The connection::async_read() function will automatically
290 // decode the data that is written to the underlying socket.
291 LOG(1, "INFO: Checking number of done jobs ...");
292 connection_.async_read(doneJobs,
293 boost::bind(&FragmentController::handle_FinishOperation, this,
294 boost::asio::placeholders::error));
295 }
296 else
297 {
298 // An error occurred.
299 Exitflag = ErrorFlag;
300 ELOG(1, e.message());
301 }
302}
303
304/** Internal function to resolve all possible connection endpoints.
305 *
306 * \return endpoint iterator of connection
307 */
308boost::asio::ip::tcp::resolver::iterator FragmentController::getEndpointIterator()
309{
310 // Resolve the host name into an IP address.
311 boost::asio::ip::tcp::resolver resolver(connection_.socket().get_io_service());
312 boost::asio::ip::tcp::resolver::query query(host, service);
313 boost::asio::ip::tcp::resolver::iterator endpoint_iterator =
314 resolver.resolve(query);
315
316 return endpoint_iterator;
317}
318
319/** Internal function to connect to the endpoint of the server asynchronuously.
320 *
321 * We require internal connetion_ and host and service to be set up for this.
322 */
323void FragmentController::connect_calc()
324{
325 Info info(__FUNCTION__);
326 // Resolve the host name into an IP address.
327 boost::asio::ip::tcp::resolver::iterator endpoint_iterator = getEndpointIterator();
328 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
329
330 // Start an asynchronous connect operation.
331 std::cout << "Connecting to endpoint " << endpoint << " to calc " << std::endl;
332 connection_.socket().async_connect(endpoint,
333 boost::bind(&FragmentController::handle_connect_calc, this,
334 boost::asio::placeholders::error, ++endpoint_iterator));
335}
336
337/** Internal function to connect to the endpoint of the server asynchronuously.
338 *
339 * We require internal connetion_ and host and service to be set up for this.
340 */
341void FragmentController::connect_check()
342{
343 Info info(__FUNCTION__);
344 // Resolve the host name into an IP address.
345 boost::asio::ip::tcp::resolver::iterator endpoint_iterator = getEndpointIterator();
346 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
347
348 // Start an asynchronous connect operation.
349 std::cout << "Connecting to endpoint " << endpoint << " to check " << std::endl;
350 connection_.socket().async_connect(endpoint,
351 boost::bind(&FragmentController::handle_connect_check, this,
352 boost::asio::placeholders::error, ++endpoint_iterator));
353}
354
355/** Internal function to connect to the endpoint of the server asynchronuously.
356 *
357 * We require internal connetion_ and host and service to be set up for this.
358 */
359void FragmentController::connect_get()
360{
361 Info info(__FUNCTION__);
362 // Resolve the host name into an IP address.
363 boost::asio::ip::tcp::resolver::iterator endpoint_iterator = getEndpointIterator();
364 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
365
366 // Start an asynchronous connect operation.
367 std::cout << "Connecting to endpoint " << endpoint << " to get results " << std::endl;
368 connection_.socket().async_connect(endpoint,
369 boost::bind(&FragmentController::handle_connect_get, this,
370 boost::asio::placeholders::error, ++endpoint_iterator));
371}
372
373/** Internal function to connect to the endpoint of the server asynchronuously.
374 *
375 * We require internal connetion_ and host and service to be set up for this.
376 */
377void FragmentController::connect_shutdown()
378{
379 Info info(__FUNCTION__);
380 // Resolve the host name into an IP address.
381 boost::asio::ip::tcp::resolver::iterator endpoint_iterator = getEndpointIterator();
382 boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
383
384 // Start an asynchronous connect operation.
385 std::cout << "Connecting to endpoint " << endpoint << " to get results " << std::endl;
386 connection_.socket().async_connect(endpoint,
387 boost::bind(&FragmentController::handle_connect_shutdown, this,
388 boost::asio::placeholders::error, ++endpoint_iterator));
389}
390
391/** Internal function to disconnect connection_ correctly.
392 *
393 */
394void FragmentController::disconnect()
395{
396 //connection_.socket().close();
397}
398
399/** Place number of jobs into this controller.
400 *
401 * \param _jobs jobs to add
402 */
403void FragmentController::addJobs(const std::vector<FragmentJob> &_jobs)
404{
405 jobs.reserve(jobs.size()+_jobs.size());
406 BOOST_FOREACH(FragmentJob job, _jobs) {
407 jobs.push_back(job);
408 }
409}
410
411/** Prepares the calculation of the results for the current jobs.
412 */
413void FragmentController::calculateResults()
414{
415 Info info(__FUNCTION__);
416 // connect
417 connect_calc();
418 //disconnect
419 disconnect();
420}
421
422/** Prepares the calculation of the results for the current jobs.
423 */
424void FragmentController::checkResults()
425{
426 Info info(__FUNCTION__);
427 // connect
428 connect_check();
429 //disconnect
430 disconnect();
431}
432
433/** Getter for results.
434 *
435 * \sa calculateResults()
436 * \return vector of results for the added jobs (\sa addJobs()).
437 */
438std::vector<FragmentResult> FragmentController::getResults()
439{
440 Info info(__FUNCTION__);
441 return results;
442}
443
444/** Function to initiate receival of results.
445 *
446 */
447void FragmentController::obtainResults()
448{
449 // connect
450 connect_get();
451 //disconnect
452 disconnect();
453}
454
455/** Function to initiate shutdown of server.
456 *
457 */
458void FragmentController::shutdown()
459{
460 // connect
461 connect_shutdown();
462 //disconnect
463 disconnect();
464}
465
466/** Getter for doneJobs.
467 *
468 * \sa checkResults()
469 * \param doneJobs
470 */
471size_t FragmentController::getDoneJobs() const
472{
473 return doneJobs;
474}
475
476/** Getter for number of jobs present in the queue.
477 *
478 * \return jobs.size()
479 */
480size_t FragmentController::getPresentJobs() const
481{
482 return jobs.size();
483}
Note: See TracBrowser for help on using the repository browser.