// Copyright (c) 2005-2009 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include /////////////////////////////////////////////////////////////////////////////// // // Start this example by providing an arbitrary number of URLs on the command // line. It will re-spawn itself to each of the URLs. Each instance will // increment a number stored in a central counter store, using the advert service. // // // example usage (slightly shortened): // // merzky@boskop:~/saga/core/examples/tutorial$ saga-advert remove_entry /tutorial/depending_jobs/counter // // merzky@boskop:~/saga/core/examples/tutorial$ saga-advert dump_directory /tutorial/depending_jobs/ // /tutorial/depending_jobs/ // // merzky@boskop:~/saga/core/examples/tutorial$ make && ./depending_jobs fork://localhost fork://localhost // advert entry does not yet exist - initialize counter to 0 // // merzky@boskop:~/saga/core/examples/tutorial$ saga-advert dump_directory /tutorial/depending_jobs/ // /tutorial/depending_jobs/ // /tutorial/depending_jobs/counter // value : 2 // // merzky@boskop:~/saga/core/examples/tutorial$ make && ./depending_jobs fork://localhost fork://localhost // // merzky@boskop:~/saga/core/examples/tutorial$ saga-advert dump_directory /tutorial/depending_jobs/ // /tutorial/depending_jobs/ // /tutorial/depending_jobs/counter // value : 4 // /////////////////////////////////////////////////////////////////////////////// #define RESULT_STORE "/tutorial/depending_jobs/counter" // place in advert to store counter to #define JOB_PATH "./depending_jobs" // put the correct path here /////////////////////////////////////////////////////////////////////////////// // retrieve the current value from the advert (counter store) bool get_counter(int& counter) { counter = 0; try { saga::advert::entry e (RESULT_STORE, saga::advert::Read); counter = boost::lexical_cast (e.get_attribute ("value")); } catch (saga::does_not_exist const& e) { std::cout << "advert entry does not yet exist - initialize counter to 0" << std::endl; counter = 0; return true; } catch (saga::exception const& e) { if (e.get_error() != saga::NoSuccess) std::cerr << "saga::exception caught: " << e.what () << std::endl; return false; } catch (std::exception const& e) { std::cerr << "std::exception caught: " << e.what () << std::endl; return false; } catch (...) { std::cerr << "unexpected exception caught" << std::endl; return false; } return true; } /////////////////////////////////////////////////////////////////////////////// // store the current value into the advert (counter store) bool set_counter(int counter) { try { saga::advert::entry e(RESULT_STORE, saga::advert::CreateParents | saga::advert::Create | saga::advert::ReadWrite); e.set_attribute ("value", boost::lexical_cast (counter)); } catch (saga::exception const& e) { std::cerr << "saga::exception caught: " << e.what () << std::endl; return false; } catch (std::exception const& e) { std::cerr << "std::exception caught: " << e.what () << std::endl; return false; } catch (...) { std::cerr << "unexpected exception caught" << std::endl; return false; } return true; } /////////////////////////////////////////////////////////////////////////////// // the routine spawning the SAGA jobs and waiting for their counter void respawn(int argc, char *argv[]) { assert(argc > 1); // we shouldn't end up here without any given URL try { // start the johb server on the given URL saga::url url (argv[1]); saga::job::service js (url); // compose the command line, skip first argument std::string commandline (JOB_PATH); for (int i = 2; i < argc; ++i) { commandline += " "; commandline += argv[i]; } // run the job saga::job::job j = js.run_job(commandline); // wait for the job to start saga::job::state s = j.get_state(); while (s != saga::job::Running && s != saga::job::Failed) s = j.get_state(); // if the job didn't start successfully, print error message if (s == saga::job::Failed) { std::cerr << "SAGA job: " << j.get_job_id() << " failed (state: " << saga::job::detail::get_state_name(s) << ")\n"; } // wait for the job to Finish s = j.get_state(); while (s == saga::job::Running) s = j.get_state(); } catch (saga::exception const& e) { std::cerr << "saga::exception caught: " << e.what () << std::endl; } catch (std::exception const& e) { std::cerr << "std::exception caught: " << e.what () << std::endl; } catch (...) { std::cerr << "unexpected exception caught" << std::endl; } } /////////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { if (argc == 1) { // no more URLs are given, we're done! int counter = 0; if (get_counter(counter)) std::cout << "The overall counter is: " << counter << std::endl; } else { // otherwise get current value, increment it, and store new value int counter = 0; get_counter (counter); // will set counter to zero initially // re-spawn this job, increment counter // if set_counter fails, don't bother to respawn if (set_counter(counter + 1)) respawn(argc, argv); } return 0; }