From 6e5e65676a2f93b92874d209d768dffb3369c53c Mon Sep 17 00:00:00 2001 From: ribes Date: Wed, 28 Jul 2010 16:37:29 +0000 Subject: [PATCH] - major update for module JOBMANAGER: - compliant with last LIBBATCH version - bug fixes - load and save jobs - It's now a launcher observer - Thread safe work --- Makefile.am | 2 +- configure.ac | 1 + idl/JOBMANAGER_IDL.idl | 30 ++ idl/Makefile.am | 22 ++ src/engine/BL_Job.cxx | 126 +++++++- src/engine/BL_Job.hxx | 29 +- src/engine/BL_JobsManager.cxx | 396 +++++++++++++++-------- src/engine/BL_JobsManager.hxx | 57 +++- src/engine/BL_Observer.hxx | 8 +- src/engine/BL_SALOMEServices.cxx | 150 ++++++++- src/engine/BL_SALOMEServices.hxx | 20 +- src/engine/Makefile.am | 7 +- src/genericgui/BL_CreateJobWizard.cxx | 13 +- src/genericgui/BL_GenericGui.cxx | 38 ++- src/genericgui/BL_GenericGui.hxx | 1 + src/genericgui/BL_JobTab.cxx | 8 + src/genericgui/BL_JobsManager_QT.cxx | 88 ++++- src/genericgui/BL_JobsManager_QT.hxx | 21 +- src/genericgui/BL_QModelManager.cxx | 21 ++ src/genericgui/BL_QModelManager.hxx | 1 + src/genericgui/JM_EditSalomeResource.cxx | 13 +- src/genericgui/Makefile.am | 1 + src/salomegui/Makefile.am | 3 + src/standalone/Makefile.am | 2 + 24 files changed, 860 insertions(+), 198 deletions(-) create mode 100644 idl/JOBMANAGER_IDL.idl create mode 100644 idl/Makefile.am diff --git a/Makefile.am b/Makefile.am index 6e7f6e1..d2868e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,6 +19,6 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src doc +SUBDIRS = idl src doc EXTRA_DIST = build_configure diff --git a/configure.ac b/configure.ac index da86c8e..b6c4557 100644 --- a/configure.ac +++ b/configure.ac @@ -122,6 +122,7 @@ fi AC_OUTPUT([ \ Makefile \ + idl/Makefile \ src/Makefile \ src/bases/Makefile \ src/engine/Makefile \ diff --git a/idl/JOBMANAGER_IDL.idl b/idl/JOBMANAGER_IDL.idl new file mode 100644 index 0000000..2640078 --- /dev/null +++ b/idl/JOBMANAGER_IDL.idl @@ -0,0 +1,30 @@ +// Copyright (C) 2009-2010 EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _JOBMANAGER_IDL_ +#define _JOBMANAGER_IDL_ + +#include "SALOME_ContainerManager.idl" + +module JOBMANAGER +{ + interface LauncherObserver : Engines::SalomeLauncherObserver {}; +}; + +#endif diff --git a/idl/Makefile.am b/idl/Makefile.am new file mode 100644 index 0000000..f20ae3c --- /dev/null +++ b/idl/Makefile.am @@ -0,0 +1,22 @@ +salomeidldir = $(prefix)/idl +salomeincludedir = $(includedir)/salome +libdir = $(prefix)/lib/salome + +BUILT_SOURCES = JOBMANAGER_IDLSK.cc +IDL_FILES = JOBMANAGER_IDL.idl + +lib_LTLIBRARIES = libJOBMANAGER_IDL.la +salomeidl_DATA = $(IDL_FILES) + +nodist_libJOBMANAGER_IDL_la_SOURCES = JOBMANAGER_IDLSK.cc +nodist_salomeinclude_HEADERS = JOBMANAGER_IDL.hh + +libJOBMANAGER_IDL_la_CXXFLAGS = -I. @KERNEL_CXXFLAGS@ +libJOBMANAGER_IDL_la_LIBADD = $(KERNEL_LIBS) + +%SK.cc %.hh : %.idl + $(OMNIORB_IDL) -bcxx @OMNIORB_IDLCXXFLAGS@ -I$(KERNEL_ROOT_DIR)/idl/salome $< + +CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx + +EXTRA_DIST = $(IDL_FILES) diff --git a/src/engine/BL_Job.cxx b/src/engine/BL_Job.cxx index 16d329d..6cf4c84 100644 --- a/src/engine/BL_Job.cxx +++ b/src/engine/BL_Job.cxx @@ -70,12 +70,29 @@ BL::Job::getName() return _name; } -void +void BL::Job::setType(BL::Job::JobType type) { _type = type; } +void +BL::Job::setType(const std::string & type) +{ + if (type == "command") + { + setType(BL::Job::COMMAND); + } + else if (type == "yacs_file") + { + setType(BL::Job::YACS_SCHEMA); + } + else if (type == "python_salome") + { + setType(BL::Job::PYTHON_SALOME); + } +} + BL::Job::JobType BL::Job::getType() { @@ -83,7 +100,7 @@ BL::Job::getType() } void -BL::Job::setJobFile(std::string & job_file) +BL::Job::setJobFile(const std::string & job_file) { _job_file = job_file; } @@ -95,7 +112,7 @@ BL::Job::getJobFile() } void -BL::Job::setEnvFile(std::string & env_file) +BL::Job::setEnvFile(const std::string & env_file) { _env_file = env_file; } @@ -136,7 +153,7 @@ BL::Job::getFilesParameters() } void -BL::Job::setResource(std::string & resource) +BL::Job::setResource(const std::string & resource) { _resource_choosed = resource; } @@ -148,7 +165,7 @@ BL::Job::getResource() } void -BL::Job::setBatchQueue(std::string & queue) +BL::Job::setBatchQueue(const std::string & queue) { _batch_queue = queue; } @@ -171,6 +188,105 @@ BL::Job::getState() return _state; } +std::string +BL::Job::setStringState(const std::string & state) +{ + std::string result(""); + + // Check if state is an error + if (state != "CREATED" && + state != "IN_PROCESS" && + state != "QUEUED" && + state != "RUNNING" && + state != "PAUSED" && + state != "FINISHED" && + state != "FAILED" && + state != "NOT_CREATED" && + state != "ERROR" + ) + { + DEBTRACE("Error state in setStringState"); + result = state; + } + + if (result == "") + { + if (state == "CREATED") + { + if (_state != BL::Job::CREATED) + { + setState(BL::Job::CREATED); + result = "new_state"; + } + } + else if (state == "NOT_CREATED") + { + if (_state != BL::Job::NOT_CREATED) + { + setState(BL::Job::NOT_CREATED); + result = "new_state"; + } + } + else if (state == "QUEUED") + { + if (_state != BL::Job::QUEUED) + { + setState(BL::Job::QUEUED); + result = "new_state"; + } + } + else if (state == "IN_PROCESS") + { + if (_state != BL::Job::IN_PROCESS) + { + setState(BL::Job::IN_PROCESS); + result = "new_state"; + } + } + else if (state == "RUNNING") + { + if (_state != BL::Job::RUNNING) + { + setState(BL::Job::RUNNING); + result = "new_state"; + } + } + else if (state == "PAUSED") + { + if (_state != BL::Job::PAUSED) + { + setState(BL::Job::PAUSED); + result = "new_state"; + } + } + else if (state == "FINISHED") + { + if (_state != BL::Job::FINISHED) + { + setState(BL::Job::FINISHED); + result = "new_state"; + } + } + else if (state == "ERROR") + { + if (_state != BL::Job::ERROR) + { + setState(BL::Job::ERROR); + result = "new_state"; + } + } + else if (state == "FAILED") + { + if (_state != BL::Job::FAILED) + { + setState(BL::Job::FAILED); + result = "new_state"; + } + } + } + return result; +} + void BL::Job::setThreadState(BL::Job::ThreadState state) { diff --git a/src/engine/BL_Job.hxx b/src/engine/BL_Job.hxx index 72e265e..210ee0f 100644 --- a/src/engine/BL_Job.hxx +++ b/src/engine/BL_Job.hxx @@ -39,42 +39,44 @@ namespace BL{ enum JobType {YACS_SCHEMA, COMMAND, PYTHON_SALOME}; void setType(BL::Job::JobType type); + void setType(const std::string & type); BL::Job::JobType getType(); - void setJobFile(std::string & job_file); + void setJobFile(const std::string & job_file); std::string & getJobFile(); - void setEnvFile(std::string & env_file); + void setEnvFile(const std::string & env_file); std::string & getEnvFile(); struct BatchParam { - std::string batch_directory; - std::string maximum_duration; - std::string expected_memory; - int nb_proc; + std::string batch_directory; + std::string maximum_duration; + std::string expected_memory; + int nb_proc; }; void setBatchParameters(BL::Job::BatchParam & param); BL::Job::BatchParam & getBatchParameters(); struct FilesParam { - std::string result_directory; - std::list input_files_list; - std::list output_files_list; + std::string result_directory; + std::list input_files_list; + std::list output_files_list; }; void setFilesParameters(BL::Job::FilesParam & param); BL::Job::FilesParam & getFilesParameters(); - void setResource(std::string & resource); + void setResource(const std::string & resource); std::string & getResource(); - void setBatchQueue(std::string & queue); + void setBatchQueue(const std::string & queue); std::string & getBatchQueue(); - enum State {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR}; + enum State {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR, FAILED, NOT_CREATED}; void setState(BL::Job::State state); BL::Job::State getState(); + std::string setStringState(const std::string & state); enum ThreadState {NOTHING, STARTING}; void setThreadState(BL::Job::ThreadState state); @@ -83,7 +85,6 @@ namespace BL{ void setSalomeLauncherId(int id); int getSalomeLauncherId(); - private: BL::Job::State _state; BL::Job::ThreadState _thread_state; @@ -93,7 +94,7 @@ namespace BL{ BL::Job::JobType _type; std::string _job_file; std::string _env_file; - + BL::Job::BatchParam _batch_params; BL::Job::FilesParam _files_params; std::string _resource_choosed; diff --git a/src/engine/BL_JobsManager.cxx b/src/engine/BL_JobsManager.cxx index 7a56458..62a6999 100644 --- a/src/engine/BL_JobsManager.cxx +++ b/src/engine/BL_JobsManager.cxx @@ -18,13 +18,16 @@ // #include "BL_JobsManager.hxx" +#include BL::JobsManager::JobsManager(BL::SALOMEServices * salome_services) { DEBTRACE("Creating BL::JobsManager"); BL_ASSERT(salome_services); _salome_services = salome_services; + _salome_services->set_manager(this); _observer = NULL; + _name_counter = 0; } BL::JobsManager::~JobsManager() @@ -51,6 +54,7 @@ BL::JobsManager::createJob(const std::string & name) BL::Job * new_job = NULL; + _thread_mutex_jobs_map.lock(); _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) { @@ -62,6 +66,7 @@ BL::JobsManager::createJob(const std::string & name) else DEBTRACE("createJob Error !!!! Job already exist: " << name); + _thread_mutex_jobs_map.unlock(); return new_job; } @@ -70,20 +75,22 @@ BL::JobsManager::addJobToLauncher(const std::string & name) { DEBTRACE("addJobToLauncher BL::JobsManager"); + _thread_mutex_jobs_map.lock(); _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) { // TODO: SHOULD SEND an exeception... DEBMSG("[addJobToLauncher] failed, job was not found"); } - + _thread_mutex_jobs_map.unlock(); + std::string result = ""; result = _salome_services->create_job(_jobs_it->second); if (_observer) if (result != "") { + _jobs_it->second->setState(BL::Job::NOT_CREATED); _observer->sendEvent("create_job", "Error", name, result); - _jobs_it->second->setState(BL::Job::ERROR); } else _observer->sendEvent("create_job", "Ok", name, ""); @@ -93,6 +100,7 @@ void BL::JobsManager::removeJob(const std::string & name) { DEBTRACE("removeJob BL::JobsManager"); + _thread_mutex_jobs_map.lock(); _jobs_it = _jobs.find(name); if (_jobs_it != _jobs.end()) { @@ -105,12 +113,13 @@ BL::JobsManager::removeJob(const std::string & name) if (_observer) if (result != "") - _observer->sendEvent("delete_job", "Error", name, result); + _observer->sendEvent("delete_job", "Error", name, result); else - _observer->sendEvent("delete_job", "Ok", name, ""); + _observer->sendEvent("delete_job", "Ok", name, ""); } else DEBTRACE("removeJob Error !!!! Job does not exist: " << name); + _thread_mutex_jobs_map.unlock(); } BL::Job * @@ -129,47 +138,27 @@ BL::JobsManager::getJobs() bool BL::JobsManager::job_already_exist(const std::string & name) { - _jobs_it = _jobs.find(name); + bool result = true; + _thread_mutex_jobs_map.lock(); + _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) - return false; - else - return true; + result = false; + _thread_mutex_jobs_map.unlock(); + + return result; } void BL::JobsManager::start_job(const std::string & name) { DEBTRACE("BL::JobsManager::start_job called for job: " << name); + // Prepare Info for thread + BL::JobsManager::thread_info * ti = new thread_info(); + ti->object_ptr = this; + ti->job_name = name; + omni_thread::create(BL::JobsManager::starting_job_thread, ti); - // Check job exits - _jobs_it = _jobs.find(name); - if (_jobs_it == _jobs.end()) - { - DEBTRACE("BL::JobsManager::start_job job unknown: " << name); - return; - } - else - { - _thread_mutex.lock(); - BL::Job * job = _jobs_it->second; - // Check Job Exec State - multithread protection - if (job->getThreadState() == BL::Job::NOTHING) - { - // Prepare Info for thread - BL::JobsManager::thread_info * ti = new thread_info(); - ti->object_ptr = this; - ti->job_name = name; - job->setState(BL::Job::IN_PROCESS); - job->setThreadState(BL::Job::STARTING); - omni_thread::create(BL::JobsManager::starting_job_thread, ti); - } - else - { - DEBTRACE("BL::JobsManager::start_job nothin to do, job already starting, job name: " << name); - } - _thread_mutex.unlock(); - } } void @@ -179,27 +168,34 @@ BL::JobsManager::starting_job_thread(void * object_ptr) BL::JobsManager::thread_info * ti = reinterpret_cast(object_ptr); BL::JobsManager * object = ti->object_ptr; std::string job_name = ti->job_name; - BL::Job * job = object->getJob(job_name); - - std::string result = object->_salome_services->start_job(job); - object->_thread_mutex.lock(); - // End - if (result == "") + // Check job exits + object->_thread_mutex_jobs_map.lock(); + object->_jobs_it = object->_jobs.find(job_name); + if (object->_jobs_it == object->_jobs.end()) { - if (object->_observer) - object->_observer->sendEvent("start_job", "Ok", job_name, ""); - job->setState(BL::Job::QUEUED); - job->setThreadState(BL::Job::NOTHING); + DEBTRACE("BL::JobsManager::start_job job unknown: " << job_name); } else { - if (object->_observer) - object->_observer->sendEvent("start_job", "Error", job_name, result); - job->setState(BL::Job::ERROR); - job->setThreadState(BL::Job::NOTHING); + BL::Job * job = object->getJob(job_name); + std::string result = object->_salome_services->start_job(job); + if (result == "") + { + job->setState(BL::Job::QUEUED); + job->setThreadState(BL::Job::NOTHING); + if (object->_observer) + object->_observer->sendEvent("start_job", "Ok", job_name, ""); + } + else + { + job->setState(BL::Job::ERROR); + job->setThreadState(BL::Job::NOTHING); + if (object->_observer) + object->_observer->sendEvent("start_job", "Error", job_name, result); + } } - object->_thread_mutex.unlock(); + object->_thread_mutex_jobs_map.unlock(); } void @@ -207,16 +203,17 @@ BL::JobsManager::refresh_jobs() { DEBTRACE("refresh_jobs BL::JobsManager called"); - omni_thread::create(BL::JobsManager::refresh_job, this); + omni_thread::create(BL::JobsManager::refresh_jobs_thread, this); } void -BL::JobsManager::refresh_job(void * object_ptr) +BL::JobsManager::refresh_jobs_thread(void * object_ptr) { DEBTRACE("refresh_job BL::JobsManager called"); BL::JobsManager * object = reinterpret_cast(object_ptr); //iterate on all jobs + object->_thread_mutex_jobs_map.lock(); _jobs_map::iterator jobs_it; jobs_it = object->_jobs.begin(); for(;jobs_it != object->_jobs.end();jobs_it++) @@ -224,105 +221,55 @@ BL::JobsManager::refresh_job(void * object_ptr) BL::Job * job = jobs_it->second; if (job->getSalomeLauncherId() != -1) { - object->_thread_mutex.lock(); if (job->getThreadState() == BL::Job::NOTHING) { - BL::Job::State job_state = job->getState(); - if (job_state != BL::Job::FINISHED or job_state != BL::Job::ERROR) - { - std::string result = object->_salome_services->refresh_job(job); - if (result == "CREATED") - { - if (job_state != BL::Job::CREATED) - { - job->setState(BL::Job::CREATED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "QUEUED") - { - if (job_state != BL::Job::QUEUED) - { - job->setState(BL::Job::QUEUED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "IN_PROCESS") - { - if (job_state != BL::Job::IN_PROCESS) - { - job->setState(BL::Job::IN_PROCESS); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "RUNNING") - { - if (job_state != BL::Job::RUNNING) - { - job->setState(BL::Job::RUNNING); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "PAUSED") - { - if (job_state != BL::Job::PAUSED) - { - job->setState(BL::Job::PAUSED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "FINISHED") - { - if (job_state != BL::Job::FINISHED) - { - job->setState(BL::Job::FINISHED); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else if (result == "ERROR") - { - if (job_state != BL::Job::ERROR) - { - job->setState(BL::Job::ERROR); - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); - } - } - else - { - // Error using launcher... - if (object->_observer) - object->_observer->sendEvent("refresh_job", "Error", job->getName(), result); - } - } + BL::Job::State job_state = job->getState(); + if (job_state != BL::Job::FINISHED && + job_state != BL::Job::ERROR && + job_state != BL::Job::FAILED && + job_state != BL::Job::NOT_CREATED) + { + std::string result_launcher = object->_salome_services->refresh_job(job); + std::string result_job = job->setStringState(result_launcher); + if (result_job == "new_state") + { + if (object->_observer) + object->_observer->sendEvent("refresh_job", "Ok", job->getName(), "new state"); + } + else if (result_job != "") + { + // Error using launcher... + if (object->_observer) + object->_observer->sendEvent("refresh_job", "Error", job->getName(), result_launcher); + } + } } - object->_thread_mutex.unlock(); } } + object->_thread_mutex_jobs_map.unlock(); } void BL::JobsManager::get_results_job(const std::string & name) { DEBTRACE("get_results_job BL::JobsManager called"); - + + _thread_mutex_jobs_map.lock(); // Check job exits _jobs_it = _jobs.find(name); if (_jobs_it == _jobs.end()) { DEBTRACE("BL::JobsManager::get_results_job job unknown: " << name); + _thread_mutex_jobs_map.unlock(); return; } else { BL::Job * job = _jobs_it->second; - if (job->getState() == BL::Job::FINISHED) + if (job->getState() == BL::Job::FINISHED || + job->getState() == BL::Job::ERROR || + job->getState() == BL::Job::FAILED + ) { // Prepare Info for thread BL::JobsManager::thread_info * ti = new thread_info(); @@ -333,6 +280,7 @@ BL::JobsManager::get_results_job(const std::string & name) else { DEBTRACE("BL::JobsManager::get_results_job job bad job state !"); + _thread_mutex_jobs_map.unlock(); return; } } @@ -347,7 +295,6 @@ BL::JobsManager::get_results_job_thread(void * object_ptr) std::string job_name = ti->job_name; BL::Job * job = object->getJob(job_name); - object->_thread_mutex_results.lock(); std::string result = object->_salome_services->get_results_job(job); // End @@ -361,5 +308,188 @@ BL::JobsManager::get_results_job_thread(void * object_ptr) if (object->_observer) object->_observer->sendEvent("get_results_job", "Error", job_name, result); } - object->_thread_mutex_results.unlock(); + object->_thread_mutex_jobs_map.unlock(); +} + +void +BL::JobsManager::save_jobs(const std::string & xml_file) +{ + DEBTRACE("BL::JobsManager::save_jobs called for : " << xml_file); + + // Prepare Info for thread + BL::JobsManager::thread_info_file * ti = new thread_info_file(); + ti->object_ptr = this; + ti->file_name = xml_file; + omni_thread::create(BL::JobsManager::save_jobs_thread, ti); +} + +void +BL::JobsManager::load_jobs(const std::string & xml_file) +{ + DEBTRACE("BL::JobsManager::load_jobs called for : " << xml_file); + + // Prepare Info for thread + BL::JobsManager::thread_info_file * ti = new thread_info_file(); + ti->object_ptr = this; + ti->file_name = xml_file; + omni_thread::create(BL::JobsManager::load_jobs_thread, ti); +} + +void +BL::JobsManager::save_jobs_thread(void * object_ptr) +{ + DEBTRACE("save_jobs_thread BL::JobsManager called"); + BL::JobsManager::thread_info_file * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + std::string file_name = ti->file_name; + + object->_thread_mutex_jobs_map.lock(); + std::string result = object->_salome_services->save_jobs(file_name); + object->_thread_mutex_jobs_map.unlock(); + + if (result != "") + if (object->_observer) + object->_observer->sendEvent("save_jobs", "Error", "", result); +} + +void +BL::JobsManager::load_jobs_thread(void * object_ptr) +{ + DEBTRACE("load_jobs_thread BL::JobsManager called"); + BL::JobsManager::thread_info_file * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + std::string file_name = ti->file_name; + + object->_thread_mutex_jobs_map.lock(); + std::string result = object->_salome_services->load_jobs(file_name); + object->_thread_mutex_jobs_map.unlock(); + + if (result != "") + if (object->_observer) + object->_observer->sendEvent("load_jobs", "Error", "", result); +} + +void +BL::JobsManager::launcher_event_save_jobs(const std::string & data) +{ + if (_observer) + _observer->sendEvent("save_jobs", "Ok", "", data); +} + +void +BL::JobsManager::launcher_event_load_jobs(const std::string & data) +{ + if (_observer) + _observer->sendEvent("load_jobs", "Ok", "", data); +} + +void +BL::JobsManager::launcher_event_new_job(const std::string & data) +{ + int job_number; + std::istringstream job_number_stream(data); + if (job_number_stream >> job_number) + { + BL::JobsManager::thread_info_new_job * ti = new thread_info_new_job(); + ti->object_ptr = this; + ti->job_number = job_number; + omni_thread::create(BL::JobsManager::launcher_event_new_job_thread, ti); + } +} + +void +BL::JobsManager::launcher_event_new_job_thread(void * object_ptr) +{ + DEBTRACE("Start of BL::JobsManager::launcher_event_new_job_thread"); + BL::JobsManager::thread_info_new_job * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + int job_number = ti->job_number; + + object->_thread_mutex_jobs_map.lock(); + + // 1: Check if job is not already on our map + bool job_in_map = false; + _jobs_map::iterator jobs_it; + jobs_it = object->_jobs.begin(); + for(;jobs_it != object->_jobs.end();jobs_it++) + { + BL::Job * job = jobs_it->second; + if (job->getSalomeLauncherId() == job_number) + job_in_map = true; + } + + if (!job_in_map) + { + // 2: We try to get job informations + + BL::Job * new_job = object->_salome_services->get_new_job(job_number); + + // 3: We add it + if (new_job) + { + // 4: Check if job has a name or if the name already exists + if (new_job->getName() == "") + { + std::ostringstream name_stream; + name_stream << "no_name_" << object->_name_counter; + object->_name_counter++; + new_job->setName(name_stream.str()); + } + + _jobs_map::iterator _jobs_it_name = object->_jobs.find(new_job->getName()); + if (_jobs_it_name != object->_jobs.end()) + { + std::ostringstream name_stream; + name_stream << new_job->getName() << "_" << object->_name_counter; + object->_name_counter++; + new_job->setName(name_stream.str()); + } + // 5: Insert job + object->_jobs[new_job->getName()] = new_job; + if (object->_observer) + object->_observer->sendEvent("add_job", "Ok", new_job->getName(), ""); + } + } + + object->_thread_mutex_jobs_map.unlock(); +} + +void +BL::JobsManager::launcher_event_remove_job(const std::string & data) +{ + int job_number; + std::istringstream job_number_stream(data); + if (job_number_stream >> job_number) + { + BL::JobsManager::thread_info_new_job * ti = new thread_info_new_job(); + ti->object_ptr = this; + ti->job_number = job_number; + omni_thread::create(BL::JobsManager::launcher_event_remove_job_thread, ti); + } +} + +void +BL::JobsManager::launcher_event_remove_job_thread(void * object_ptr) +{ + DEBTRACE("Start of BL::JobsManager::launcher_event_remove_job_thread"); + BL::JobsManager::thread_info_new_job * ti = reinterpret_cast(object_ptr); + BL::JobsManager * object = ti->object_ptr; + int job_number = ti->job_number; + + object->_thread_mutex_jobs_map.lock(); + + _jobs_map::iterator jobs_it; + jobs_it = object->_jobs.begin(); + for(;jobs_it != object->_jobs.end();jobs_it++) + { + BL::Job * job = jobs_it->second; + if (job->getSalomeLauncherId() == job_number) + { + job->setSalomeLauncherId(-1); + if (object->_observer) + object->_observer->sendEvent("to_remove_job", "Ok", job->getName(), ""); + } + } + + object->_thread_mutex_jobs_map.unlock(); } diff --git a/src/engine/BL_JobsManager.hxx b/src/engine/BL_JobsManager.hxx index 20b2b81..f9d9f81 100644 --- a/src/engine/BL_JobsManager.hxx +++ b/src/engine/BL_JobsManager.hxx @@ -32,35 +32,65 @@ namespace BL{ + class SALOMEServices; + class JobsManager { public: JobsManager(BL::SALOMEServices * salome_services); virtual ~JobsManager(); + // Add QT observer void setObserver(BL::Observer * observer); + // useful methods BL::Job * createJob(const std::string & name); - void addJobToLauncher(const std::string & name); - void removeJob(const std::string & name); - BL::Job * getJob(const std::string & name); std::map & getJobs(); - bool job_already_exist(const std::string & name); - virtual void start_job(const std::string & name); - virtual void refresh_jobs(); - virtual void get_results_job(const std::string & name); + // remote methods + void addJobToLauncher(const std::string & name); + void removeJob(const std::string & name); + virtual void start_job(const std::string & name); static void starting_job_thread(void * object_ptr); + + virtual void get_results_job(const std::string & name); static void get_results_job_thread(void * object_ptr); - static void refresh_job(void * object_ptr); + + virtual void refresh_jobs(); + static void refresh_jobs_thread(void * object_ptr); + + virtual void load_jobs(const std::string & xml_file); + virtual void save_jobs(const std::string & xml_file); + static void load_jobs_thread(void * object_ptr); + static void save_jobs_thread(void * object_ptr); + + // event from launcher + void launcher_event_save_jobs(const std::string & data); + void launcher_event_load_jobs(const std::string & data); + void launcher_event_new_job(const std::string & data); + static void launcher_event_new_job_thread(void * object_ptr); + void launcher_event_remove_job(const std::string & data); + static void launcher_event_remove_job_thread(void * object_ptr); struct thread_info { - BL::JobsManager * object_ptr; - std::string job_name; + BL::JobsManager * object_ptr; + std::string job_name; + }; + + struct thread_info_file + { + BL::JobsManager * object_ptr; + std::string file_name; + }; + + struct thread_info_new_job + { + BL::JobsManager * object_ptr; + int job_number; }; protected: @@ -72,8 +102,11 @@ namespace BL{ _jobs_map _jobs; _jobs_map::iterator _jobs_it; - omni_mutex _thread_mutex; - omni_mutex _thread_mutex_results; + // Mutex used for the jobs map + omni_mutex _thread_mutex_jobs_map; + + // To avoid two jobs with the same name + int _name_counter; }; } diff --git a/src/engine/BL_Observer.hxx b/src/engine/BL_Observer.hxx index b2b271a..9e47edc 100644 --- a/src/engine/BL_Observer.hxx +++ b/src/engine/BL_Observer.hxx @@ -30,10 +30,10 @@ namespace BL{ Observer() {}; virtual ~Observer() {}; - virtual void sendEvent(const std::string & action, - const std::string & event_name, - const std::string & job_name, - const std::string & data) = 0; + virtual void sendEvent(const std::string & action, + const std::string & event_name, + const std::string & job_name, + const std::string & data) = 0; }; } diff --git a/src/engine/BL_SALOMEServices.cxx b/src/engine/BL_SALOMEServices.cxx index d54be81..8a53923 100644 --- a/src/engine/BL_SALOMEServices.cxx +++ b/src/engine/BL_SALOMEServices.cxx @@ -18,6 +18,7 @@ // #include "BL_SALOMEServices.hxx" +#include static std::ostream & operator<<(std::ostream & os, const CORBA::Exception & e) @@ -40,6 +41,7 @@ BL::SALOMEServices::SALOMEServices() _salome_naming_service = NULL; _lcc = NULL; _state = false; + _manager = NULL; } BL::SALOMEServices::~SALOMEServices() @@ -64,6 +66,7 @@ BL::SALOMEServices::initNS() DEBMSG("SALOME Launcher is not reachable!") return_value = false; } + _salome_launcher->addObserver(_this()); obj = _salome_naming_service->Resolve("/ResourcesManager"); _resources_manager = Engines::ResourcesManager::_narrow(obj); @@ -104,8 +107,8 @@ BL::SALOMEServices::getResourceList() { for (int i = 0; i < resourceList->length(); i++) { - const char* aResource = (*resourceList)[i]; - resource_list.push_back(aResource); + const char* aResource = (*resourceList)[i]; + resource_list.push_back(aResource); } delete resourceList; } @@ -243,6 +246,7 @@ BL::SALOMEServices::create_job(BL::Job * job) } // Files + job_parameters->job_name = CORBA::string_dup(job->getName().c_str()); job_parameters->job_file = CORBA::string_dup(job->getJobFile().c_str()); job_parameters->env_file = CORBA::string_dup(job->getEnvFile().c_str()); BL::Job::FilesParam files = job->getFilesParameters(); @@ -402,3 +406,145 @@ BL::SALOMEServices::get_results_job(BL::Job * job) } return ret; } + +std::string +BL::SALOMEServices::save_jobs(const std::string & file_name) +{ + CORBA::String_var file = CORBA::string_dup(file_name.c_str()); + std::string ret = ""; + try + { + _salome_launcher->saveJobs(file); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in saveJobs !"); + ret = ex.details.text.in(); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive CORBA System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "CORBA System Exception - see SALOME logs"; + } + return ret; +} + +std::string +BL::SALOMEServices::load_jobs(const std::string & file_name) +{ + CORBA::String_var file = CORBA::string_dup(file_name.c_str()); + std::string ret = ""; + try + { + _salome_launcher->loadJobs(file); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in loadJobs !"); + ret = ex.details.text.in(); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive CORBA System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + ret = "CORBA System Exception - see SALOME logs"; + } + return ret; +} + +void +BL::SALOMEServices::notify(const char* event_name, const char * event_data) +{ + DEBMSG("Launcher event received " << event_name << " " << event_data); + + std::string event(event_name); + std::string data(event_data); + + if (event == "SAVE_JOBS") + { + _manager->launcher_event_save_jobs(data); + } + else if (event == "LOAD_JOBS") + { + _manager->launcher_event_load_jobs(data); + } + else if (event == "NEW_JOB") + { + _manager->launcher_event_new_job(data); + } + else if (event == "REMOVE_JOB") + { + _manager->launcher_event_remove_job(data); + } + else + { + DEBMSG("Unkown launcher event received"); + } +} + +BL::Job * +BL::SALOMEServices::get_new_job(int job_number) +{ + DEBMSG("Start of BL::SALOMEServices::get_new_job"); + BL::Job * job_return = NULL; + Engines::JobParameters * job_parameters = NULL; + try + { + job_parameters = _salome_launcher->getJobParameters(job_number); + } + catch (const SALOME::SALOME_Exception & ex) + { + DEBMSG("SALOME Exception in saveJobs !"); + } + catch (const CORBA::SystemException& ex) + { + DEBMSG("Receive CORBA System Exception: " << ex); + DEBMSG("Check SALOME servers..."); + } + + if (job_parameters) + { + job_return = new BL::Job(); + job_return->setSalomeLauncherId(job_number); + + job_return->setName(job_parameters->job_name.in()); + job_return->setType(job_parameters->job_type.in()); + job_return->setJobFile(job_parameters->job_file.in()); + job_return->setEnvFile(job_parameters->env_file.in()); + job_return->setBatchQueue(job_parameters->queue.in()); + + BL::Job::FilesParam param; + param.result_directory = job_parameters->result_directory.in(); + for (CORBA::ULong i = 0; i < job_parameters->in_files.length(); i++) + param.input_files_list.push_back(job_parameters->in_files[i].in()); + for (CORBA::ULong i = 0; i < job_parameters->out_files.length(); i++) + param.output_files_list.push_back(job_parameters->out_files[i].in()); + job_return->setFilesParameters(param); + + BL::Job::BatchParam batch_param; + batch_param.batch_directory = job_parameters->work_directory.in(); + batch_param.maximum_duration = job_parameters->maximum_duration.in(); + batch_param.nb_proc = job_parameters->resource_required.nb_proc; + std::ostringstream mem_stream; + mem_stream << job_parameters->resource_required.mem_mb << "mb"; + batch_param.expected_memory = mem_stream.str(); + job_return->setBatchParameters(batch_param); + + job_return->setResource(job_parameters->resource_required.name.in()); + + // Get current state + std::string result_job = job_return->setStringState(refresh_job(job_return)); + if (result_job == "new_state") {} + else if (result_job != "") + { + // Error in getting state + DEBMSG("Error in getting state of the new job!"); + delete job_return; + job_return = NULL; + } + delete job_parameters; + } + + return job_return; +} diff --git a/src/engine/BL_SALOMEServices.hxx b/src/engine/BL_SALOMEServices.hxx index d96c1cd..5170cf1 100644 --- a/src/engine/BL_SALOMEServices.hxx +++ b/src/engine/BL_SALOMEServices.hxx @@ -26,13 +26,19 @@ #include "SALOME_NamingService.hxx" #include "SALOME_LifeCycleCORBA.hxx" #include "SALOME_ContainerManager.hh" +#include "BL_JobsManager.hxx" #include #include #include +#include "JOBMANAGER_IDL.hh" + + namespace BL{ + class JobsManager; + struct ResourceDescr { std::string name; @@ -52,7 +58,8 @@ namespace BL{ std::string iprotocol; }; - class SALOMEServices + class SALOMEServices : + public POA_JOBMANAGER::LauncherObserver { public: SALOMEServices(); @@ -60,17 +67,26 @@ namespace BL{ bool initNS(); + void set_manager(BL::JobsManager * manager) {_manager = manager;} + std::list getResourceList(); BL::ResourceDescr getResourceDescr(const std::string& name); void addResource(BL::ResourceDescr & new_resource); void removeResource(const std::string & name); + std::string save_jobs(const std::string & file_name); + std::string load_jobs(const std::string & file_name); + std::string create_job(BL::Job * job); std::string start_job(BL::Job * job); std::string refresh_job(BL::Job * job); std::string delete_job(BL::Job * job); std::string get_results_job(BL::Job * job); + BL::Job * get_new_job(int job_number); + + virtual void notify(const char* event_name, const char * event_data); + private: CORBA::ORB_var _orb; SALOME_NamingService * _salome_naming_service; @@ -78,6 +94,8 @@ namespace BL{ Engines::SalomeLauncher_var _salome_launcher; Engines::ResourcesManager_var _resources_manager; + BL::JobsManager * _manager; + bool _state; }; diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 82fdcd3..8056412 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -28,7 +28,10 @@ libBL_Engine_la_SOURCES = BL_JobsManager.hxx BL_JobsManager.cxx \ libBL_Engine_la_CXXFLAGS = -I$(top_srcdir)/src/bases \ $(OMNIORB_INCLUDES) \ - -I$(KERNEL_ROOT_DIR)/include/salome + -I$(KERNEL_ROOT_DIR)/include/salome \ + -I../../idl -libBL_Engine_la_LIBADD = $(top_builddir)/src/bases/libBL_Bases.la +libBL_Engine_la_LIBADD = $(top_builddir)/src/bases/libBL_Bases.la \ + $(top_builddir)/idl/libJOBMANAGER_IDL.la \ + @OMNIORB_LIBS@ diff --git a/src/genericgui/BL_CreateJobWizard.cxx b/src/genericgui/BL_CreateJobWizard.cxx index a5a5b34..319fad7 100644 --- a/src/genericgui/BL_CreateJobWizard.cxx +++ b/src/genericgui/BL_CreateJobWizard.cxx @@ -80,8 +80,11 @@ BL::CreateJobWizard::clone(const std::string & name) { BL::Job * job = _jobs_manager->getJob(name); - // We can only edit a job in CREATED, ERROR - if (job->getState() == BL::Job::CREATED or job->getState() == BL::Job::ERROR) + // We can only edit a job in CREATED, ERROR, FAILED and NOT_CREATED + if (job->getState() == BL::Job::CREATED || + job->getState() == BL::Job::ERROR || + job->getState() == BL::Job::FAILED || + job->getState() == BL::Job::NOT_CREATED) { setField("job_name", QString(name.c_str())); _job_name_page->_check_name = false; @@ -379,7 +382,6 @@ BL::YACSSchemaPage::YACSSchemaPage(QWidget * parent) label->setWordWrap(true); QPushButton * yacs_file_button = new QPushButton(tr("Choose YACS Schema file")); - yacs_file_button->show(); connect(yacs_file_button, SIGNAL(clicked()), this, SLOT(choose_file())); _yacs_file_text = new QLineEdit(this); @@ -388,7 +390,6 @@ BL::YACSSchemaPage::YACSSchemaPage(QWidget * parent) _yacs_file_text->setReadOnly(true); QPushButton * command_env_file_button = new QPushButton(tr("Choose an environnement file")); - command_env_file_button->show(); connect(command_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file())); _line_env_file = new QLineEdit(this); registerField("env_yacs_file", _line_env_file); @@ -463,14 +464,12 @@ BL::CommandMainPage::CommandMainPage(QWidget * parent) // command QPushButton * command_file_button = new QPushButton(tr("Choose a command file")); - command_file_button->show(); connect(command_file_button, SIGNAL(clicked()), this, SLOT(choose_command_file())); _line_command = new QLineEdit(this); registerField("command", _line_command); _line_command->setReadOnly(true); QPushButton * command_env_file_button = new QPushButton(tr("Choose an environnement file")); - command_env_file_button->show(); connect(command_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file())); _line_env_file = new QLineEdit(this); registerField("env_command_file", _line_env_file); @@ -917,14 +916,12 @@ BL::PythonSalomeMainPage::PythonSalomeMainPage(QWidget * parent) // PythonSalome QPushButton * PythonSalome_file_button = new QPushButton(tr("Choose a Python file")); - PythonSalome_file_button->show(); connect(PythonSalome_file_button, SIGNAL(clicked()), this, SLOT(choose_PythonSalome_file())); _line_PythonSalome = new QLineEdit(this); registerField("PythonSalome", _line_PythonSalome); _line_PythonSalome->setReadOnly(true); QPushButton * PythonSalome_env_file_button = new QPushButton(tr("Choose an environnement file")); - PythonSalome_env_file_button->show(); connect(PythonSalome_env_file_button, SIGNAL(clicked()), this, SLOT(choose_env_file())); _line_env_file = new QLineEdit(this); registerField("env_PythonSalome_file", _line_env_file); diff --git a/src/genericgui/BL_GenericGui.cxx b/src/genericgui/BL_GenericGui.cxx index 7050d71..38e50a1 100644 --- a/src/genericgui/BL_GenericGui.cxx +++ b/src/genericgui/BL_GenericGui.cxx @@ -243,6 +243,20 @@ BL::GenericGui::delete_job() } } +void +BL::GenericGui::delete_job_external(const QString & name) +{ + _jobs_manager->delete_job(name); + _model_manager->deleteJob(name); + emit job_deleted(name); + if (name == _job_name_selected) + { + _row_selected = -1; + _job_name_selected = ""; + updateButtonsStates(); + } +} + void BL::GenericGui::delete_job_internal() { @@ -359,7 +373,7 @@ BL::GenericGui::updateButtonsStates() _buttons->disable_start_button(); _delete_job_action->setEnabled(true); _buttons->enable_delete_button(); - _get_results_job_action->setEnabled(false); + _get_results_job_action->setEnabled(true); _buttons->disable_get_results_button(); _restart_job_action->setEnabled(true); _buttons->enable_restart_button(); @@ -375,6 +389,28 @@ BL::GenericGui::updateButtonsStates() _restart_job_action->setEnabled(true); _buttons->enable_restart_button(); break; + + case BL::Job::FAILED: + _start_job_action->setEnabled(false); + _buttons->disable_start_button(); + _delete_job_action->setEnabled(true); + _buttons->enable_delete_button(); + _get_results_job_action->setEnabled(true); + _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(true); + _buttons->enable_restart_button(); + break; + + case BL::Job::NOT_CREATED: + _start_job_action->setEnabled(false); + _buttons->disable_start_button(); + _delete_job_action->setEnabled(true); + _buttons->enable_delete_button(); + _get_results_job_action->setEnabled(false); + _buttons->disable_get_results_button(); + _restart_job_action->setEnabled(true); + _buttons->enable_restart_button(); + break; } } else diff --git a/src/genericgui/BL_GenericGui.hxx b/src/genericgui/BL_GenericGui.hxx index f6492bb..9541802 100644 --- a/src/genericgui/BL_GenericGui.hxx +++ b/src/genericgui/BL_GenericGui.hxx @@ -56,6 +56,7 @@ namespace BL void delete_job_internal(); void deleteDockWidget(); + void delete_job_external(const QString & name); public slots: diff --git a/src/genericgui/BL_JobTab.cxx b/src/genericgui/BL_JobTab.cxx index 9a901e4..14ca50c 100644 --- a/src/genericgui/BL_JobTab.cxx +++ b/src/genericgui/BL_JobTab.cxx @@ -167,6 +167,10 @@ BL::JobTab::job_selected(const QModelIndex & index) _job_state_label_value->setText("Paused"); else if (job->getState() == BL::Job::ERROR) _job_state_label_value->setText("Error"); + else if (job->getState() == BL::Job::FAILED) + _job_state_label_value->setText("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + _job_state_label_value->setText("Not Created"); else _job_state_label_value->setText("Finished"); @@ -237,6 +241,10 @@ BL::JobTab::itemChanged(QStandardItem * item) _job_state_label_value->setText("Paused"); else if (job->getState() == BL::Job::ERROR) _job_state_label_value->setText("Error"); + else if (job->getState() == BL::Job::FAILED) + _job_state_label_value->setText("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + _job_state_label_value->setText("Not Created"); else _job_state_label_value->setText("Finished"); } diff --git a/src/genericgui/BL_JobsManager_QT.cxx b/src/genericgui/BL_JobsManager_QT.cxx index fabacd7..cf74511 100644 --- a/src/genericgui/BL_JobsManager_QT.cxx +++ b/src/genericgui/BL_JobsManager_QT.cxx @@ -39,6 +39,7 @@ BL::JobsManager_QT::JobsManager_QT(QWidget * parent, BL::GenericGui * main_gui, DEBTRACE("Creating BL::JobsManager_QT"); _main_gui = main_gui; setObserver(this); + _model = NULL; // Widget Part @@ -46,8 +47,9 @@ BL::JobsManager_QT::JobsManager_QT(QWidget * parent, BL::GenericGui * main_gui, _load_jobs = new QPushButton("Load Jobs"); _save_jobs = new QPushButton("Save Jobs"); - _load_jobs->setEnabled(false); - _save_jobs->setEnabled(false); + connect(_load_jobs, SIGNAL(clicked()), this, SLOT(load_jobs_button())); + connect(_save_jobs, SIGNAL(clicked()), this, SLOT(save_jobs_button())); + _auto_refresh_jobs = new QPushButton("Auto Refresh: no"); _timer = new QTimer(this); _timer->stop(); @@ -93,6 +95,42 @@ BL::JobsManager_QT::~JobsManager_QT() DEBTRACE("Destroying BL::JobsManager_QT"); } +void +BL::JobsManager_QT::set_model(QStandardItemModel * model) +{ + _model = model; +} + +void +BL::JobsManager_QT::load_jobs_button() +{ + DEBTRACE("load_jobs"); + QString jobs_file = QFileDialog::getOpenFileName(this, + tr("Choose an xml jobs file"), "", + tr("xml (*.xml);;All Files (*)")); + if (jobs_file == "") + { + write_normal_text("Load jobs action cancelled\n"); + } + else + load_jobs(jobs_file.toStdString()); +} + +void +BL::JobsManager_QT::save_jobs_button() +{ + DEBTRACE("save_jobs"); + QString jobs_file = QFileDialog::getSaveFileName(this, + tr("Choose an xml jobs file"), "", + tr("xml (*.xml);;All Files (*)")); + if (jobs_file == "") + { + write_normal_text("Save jobs action cancelled\n"); + } + else + save_jobs(jobs_file.toStdString()); +} + void BL::JobsManager_QT::RefreshJobs() { @@ -366,6 +404,50 @@ BL::JobsManager_QT::event(QEvent * e) write_error_text(" ***\n"); } } + else if (event->action == "save_jobs") + { + if (event->event_name == "Error") + { + write_error_text("Error in saving jobs: \n"); + write_error_text("*** "); + write_error_text((event->data).c_str()); + write_error_text(" ***\n"); + } + else + { + QString str((event->data).c_str()); + write_normal_text("Jobs saved in file " + str + "\n"); + } + } + else if (event->action == "load_jobs") + { + if (event->event_name == "Error") + { + write_error_text("Error in loading jobs: \n"); + write_error_text("*** "); + write_error_text((event->data).c_str()); + write_error_text(" ***\n"); + } + else + { + QString str((event->data).c_str()); + write_normal_text("Jobs loaded from file " + str + "\n"); + } + } + else if (event->action == "add_job") + { + if (event->event_name == "Ok") + { + QString str((event->job_name).c_str()); + write_normal_text("New job added " + str + "\n"); + emit new_job_added(str); + } + } + else if (event->action == "to_remove_job") + { + if (event->event_name == "Ok") + _main_gui->delete_job_external((event->job_name).c_str()); + } else { QString str((event->action).c_str()); @@ -389,9 +471,11 @@ BL::JobsManager_QT::write_normal_text(const QString & text) void BL::JobsManager_QT::write_error_text(const QString & text) { + _log->setReadOnly(false); QTextCursor cursor = _log->textCursor(); QTextCharFormat text_format; text_format.setForeground(Qt::red); cursor.insertText(text, text_format); _log->setTextCursor(cursor); + _log->setReadOnly(true); } diff --git a/src/genericgui/BL_JobsManager_QT.hxx b/src/genericgui/BL_JobsManager_QT.hxx index b821c18..a3f8a9d 100644 --- a/src/genericgui/BL_JobsManager_QT.hxx +++ b/src/genericgui/BL_JobsManager_QT.hxx @@ -34,9 +34,9 @@ namespace BL{ { public: JobManagerEvent(const std::string & action_i, - const std::string & event_name_i, - const std::string & job_name_i, - const std::string & data_i); + const std::string & event_name_i, + const std::string & job_name_i, + const std::string & data_i); virtual ~JobManagerEvent(); public: @@ -48,8 +48,8 @@ namespace BL{ class GenericGui; class JobsManager_QT: virtual public QDockWidget, - virtual public BL::JobsManager, - virtual public BL::Observer + virtual public BL::JobsManager, + virtual public BL::Observer { Q_OBJECT @@ -64,14 +64,16 @@ namespace BL{ void restart_job(const std::string & name); virtual void sendEvent(const std::string & action, - const std::string & event_name, - const std::string & job_name, - const std::string & data); + const std::string & event_name, + const std::string & job_name, + const std::string & data); bool event(QEvent * e); void write_normal_text(const QString & text); void write_error_text(const QString & text); + void set_model(QStandardItemModel * model); + protected: void create_job_with_wizard(BL::CreateJobWizard & wizard); @@ -84,6 +86,8 @@ namespace BL{ void five_minutes_refresh(); void thirty_minutes_refresh(); void one_hour_refresh(); + void load_jobs_button(); + void save_jobs_button(); signals: void new_job_added(const QString & name); @@ -96,6 +100,7 @@ namespace BL{ QTimer * _timer; QTextEdit * _log; BL::GenericGui * _main_gui; + QStandardItemModel * _model; }; } diff --git a/src/genericgui/BL_QModelManager.cxx b/src/genericgui/BL_QModelManager.cxx index ae563ad..6352d85 100644 --- a/src/genericgui/BL_QModelManager.cxx +++ b/src/genericgui/BL_QModelManager.cxx @@ -26,6 +26,7 @@ BL::QModelManager::QModelManager(QObject * parent, BL::JobsManager_QT * jobs_man _jobs_manager = jobs_manager; _model = new QStandardItemModel(this); + jobs_manager->set_model(_model); QStringList headers; headers << "Job Name" << "Type" << "State" << "Resource" << "Launcher Id"; _model->setHorizontalHeaderLabels(headers); @@ -69,6 +70,10 @@ BL::QModelManager::new_job_added(const QString & name) new_job_state = new QStandardItem("Paused"); else if (job->getState() == BL::Job::ERROR) new_job_state = new QStandardItem("Error"); + else if (job->getState() == BL::Job::FAILED) + new_job_state = new QStandardItem("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + new_job_state = new QStandardItem("Not Created"); else new_job_state = new QStandardItem("Finished"); @@ -104,6 +109,10 @@ BL::QModelManager::job_state_changed(const QString & name) job_state_item->setText("Paused"); else if (job->getState() == BL::Job::ERROR) job_state_item->setText("Error"); + else if (job->getState() == BL::Job::FAILED) + job_state_item->setText("Failed"); + else if (job->getState() == BL::Job::NOT_CREATED) + job_state_item->setText("Not Created"); else job_state_item->setText("Finished"); } @@ -114,6 +123,18 @@ BL::QModelManager::deleteJob(int row) _model->removeRow(row); } +void +BL::QModelManager::deleteJob(const QString & name) +{ + QList list = _model->findItems(name); + if (list.size() != 1) + { + DEBMSG("WARNING LIST IS NOT ONLY ONE !"); + } + if (list.size() > 0) + _model->removeRow(list[0]->row()); +} + void BL::QModelManager::job_selected(const QModelIndex & index) { diff --git a/src/genericgui/BL_QModelManager.hxx b/src/genericgui/BL_QModelManager.hxx index 81fb1e4..0048eca 100644 --- a/src/genericgui/BL_QModelManager.hxx +++ b/src/genericgui/BL_QModelManager.hxx @@ -38,6 +38,7 @@ namespace BL{ QStandardItemModel * getModel(); void deleteJob(int row); + void deleteJob(const QString & name); public slots: void new_job_added(const QString & name); diff --git a/src/genericgui/JM_EditSalomeResource.cxx b/src/genericgui/JM_EditSalomeResource.cxx index 2caf956..fa44c4a 100644 --- a/src/genericgui/JM_EditSalomeResource.cxx +++ b/src/genericgui/JM_EditSalomeResource.cxx @@ -20,8 +20,8 @@ #include "JM_EditSalomeResource.hxx" #include "BL_Traces.hxx" -JM::EditSalomeResource::EditSalomeResource(QWidget *parent, BL::SALOMEServices * salome_services, - const std::string & resource_name) : QDialog(parent) +JM::EditSalomeResource::EditSalomeResource(QWidget *parent, BL::SALOMEServices * salome_services, + const std::string & resource_name) : QDialog(parent) { DEBTRACE("Creating JM::EditSalomeResource"); BL_ASSERT(parent); @@ -33,7 +33,7 @@ JM::EditSalomeResource::EditSalomeResource(QWidget *parent, BL::SALOMEServices * //setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); // Widget code - + // Part 1 QGroupBox * main_groupBox = new QGroupBox("Main values"); QLabel * name_label = new QLabel("Name:"); @@ -120,6 +120,7 @@ JM::EditSalomeResource::EditSalomeResource(QWidget *parent, BL::SALOMEServices * _batch_line->addItem("lsf"); _batch_line->addItem("sge"); _batch_line->addItem("ssh"); + _batch_line->addItem("ccc"); _batch_line->setCurrentIndex(-1); QLabel * mpiImpl_label = new QLabel("MPI impl:"); @@ -211,6 +212,8 @@ JM::EditSalomeResource::get_infos() _batch_line->setCurrentIndex(2); else if (batch == "ssh") _batch_line->setCurrentIndex(3); + else if (batch == "ccc") + _batch_line->setCurrentIndex(4); else _batch_line->setCurrentIndex(-1); @@ -270,8 +273,8 @@ JM::EditSalomeResource::add_component() { bool ok; QString text = QInputDialog::getText(this, "Add a component", - "Component name:", QLineEdit::Normal, - "", &ok); + "Component name:", QLineEdit::Normal, + "", &ok); if (ok && !text.isEmpty()) _componentList->addItem(text); } diff --git a/src/genericgui/Makefile.am b/src/genericgui/Makefile.am index 22132ff..3efd185 100644 --- a/src/genericgui/Makefile.am +++ b/src/genericgui/Makefile.am @@ -45,6 +45,7 @@ libBL_GenericGui_la_CXXFLAGS = $(qt4_cppflags) \ -I$(top_srcdir)/src/engine \ -I$(KERNEL_ROOT_DIR)/include/salome \ $(OMNIORB_INCLUDES) \ + -I../../idl \ -I$(top_srcdir)/src/wrappers libBL_GenericGui_la_LDFLAGS = $(qt4_ldflags) diff --git a/src/salomegui/Makefile.am b/src/salomegui/Makefile.am index a79e4fe..88532c4 100644 --- a/src/salomegui/Makefile.am +++ b/src/salomegui/Makefile.am @@ -29,6 +29,7 @@ nodist_libJOBMANAGER_la_SOURCES = $(MOC_FILES) libJOBMANAGER_la_CXXFLAGS = $(qt4_cppflags) \ $(OMNIORB_INCLUDES) \ + -I../../idl \ -I$(KERNEL_ROOT_DIR)/include/salome \ -I$(GUI_ROOT_DIR)/include/salome \ -I$(top_srcdir)/src/genericgui \ @@ -41,6 +42,8 @@ libJOBMANAGER_la_LDFLAGS = -L$(GUI_ROOT_DIR)/lib/salome \ $(qt4_ldflags) libJOBMANAGER_la_LIBADD = $(qt4_libs) \ + $(top_builddir)/idl/libJOBMANAGER_IDL.la \ + @OMNIORB_LIBS@ \ $(top_builddir)/src/bases/libBL_Bases.la \ $(top_builddir)/src/engine/libBL_Engine.la \ $(top_builddir)/src/genericgui/libBL_GenericGui.la \ diff --git a/src/standalone/Makefile.am b/src/standalone/Makefile.am index 3b55258..5db222a 100644 --- a/src/standalone/Makefile.am +++ b/src/standalone/Makefile.am @@ -28,6 +28,7 @@ jobmanager_gui_CXXFLAGS = $(qt4_cppflags) \ -I$(top_srcdir)/src/engine \ -I$(KERNEL_ROOT_DIR)/include/salome \ $(OMNIORB_INCLUDES) \ + -I../../idl \ -I$(top_srcdir)/src/wrappers \ -I$(top_srcdir)/src/genericgui @@ -38,6 +39,7 @@ jobmanager_gui_LDADD = -lQtGui -lQtCore \ $(top_builddir)/src/engine/libBL_Engine.la \ $(top_builddir)/src/wrappers/libBL_Wrappers_Qt.la \ @OMNIORB_LIBS@ \ + $(top_builddir)/idl/libJOBMANAGER_IDL.la \ -L$(KERNEL_ROOT_DIR)/lib/salome -lSalomeLifeCycleCORBA -lSalomeIDLKernel -lSalomeNS EXTRA_DIST = start_jobmanager.sh.in -- 2.39.2