Version: 8.3.0
GuiExecutor.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include <Python.h>
21 #include "SALOME_LifeCycleCORBA.hxx"
22 #include "SALOME_NamingService.hxx"
23 
24 #include "GuiExecutor.hxx"
25 #include "GuiObserver_i.hxx"
26 #include "QtGuiContext.hxx"
27 
28 #include "RuntimeSALOME.hxx"
29 
30 #include "Proc.hxx"
31 #include "Node.hxx"
32 #include "InputPort.hxx"
33 #include "OutputPort.hxx"
34 #include "Executor.hxx"
35 
36 
37 //#define _DEVDEBUG_
38 #include "YacsTrace.hxx"
39 
40 using namespace std;
41 using namespace YACS::HMI;
42 using namespace YACS::ENGINE;
43 
44 GuiExecutor::GuiExecutor(YACS::ENGINE::Proc* proc)
45 {
46  DEBTRACE("GuiExecutor::GuiExecutor");
47 
48  _proc = proc;
49  _context = QtGuiContext::getQtCurrent();
50 
51  _engineRef = YACS_ORB::YACS_Gen::_nil();
52  _procRef = YACS_ORB::ProcExec::_nil();
53  _observerRef = YACS_ORB::Observer::_nil();
54 
55  _execMode = YACS::CONTINUE;
56  _serv = 0;
57 
58  _isRunning = false;
59  _isSuspended = false;
60  _isStopOnError = false;
61  _shutdownLevel=1;
62 
63  _loadStateFile = "";
64  _breakpointList.clear();
65 }
66 
67 
68 GuiExecutor::~GuiExecutor()
69 {
70  DEBTRACE("GuiExecutor::~GuiExecutor");
71 }
72 
73 void GuiExecutor::closeContext()
74 {
75  DEBTRACE("GuiExecutor::closeContext");
76  _context = 0;
77 }
78 
79 void GuiExecutor::startResumeDataflow(bool initialize)
80 {
81  DEBTRACE("GuiExecutor::runDataflow " << initialize);
82  if (!_context)
83  {
84  DEBTRACE("context closed");
85  return;
86  }
87  if (CORBA::is_nil(_engineRef))
88  {
89  DEBTRACE("Create YACS ORB engine!");
91  CORBA::ORB_ptr orb = runTime->getOrb();
92  SALOME_NamingService namingService(orb);
93  SALOME_LifeCycleCORBA lcc(&namingService);
94  ostringstream containerName;
95  containerName << "localhost/YACSContainer" << QtGuiContext::getQtCurrent()->getStudyId();
96  Engines::EngineComponent_var comp = lcc.FindOrLoad_Component(containerName.str().c_str(), "YACS" );
97  _engineRef =YACS_ORB::YACS_Gen::_narrow(comp);
98  YASSERT(!CORBA::is_nil(_engineRef));
99  }
100 
101  checkEndOfDataflow(); // --- to allow change of the _isRunning state
102 
103  if (_isRunning)
104  {
105  if (_isSuspended)
106  {
107  _procRef->setExecMode(getCurrentExecMode());
108  _procRef->resumeCurrentBreakPoint();
109  _isSuspended = false;
110  }
111  return;
112  }
113 
114  _isRunning = true;
115 
116  if (CORBA::is_nil(_procRef))
117  {
118  DEBTRACE("init _procRef");
119  _procRef = _engineRef->LoadProc(_context->getFileName().toUtf8());
120  registerStatusObservers();
121  DEBTRACE("_procRef init");
122  }
123 
124  YASSERT(!CORBA::is_nil(_procRef));
125 
126  if (initialize)
127  _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
128  else
129  _procRef->setExecMode(getCurrentExecMode());
130  setBPList();
131 
132  if (_loadStateFile.empty())
133  {
134  DEBTRACE("Run from scratch!");
135  _procRef->Run();
136  }
137  else
138  {
139  DEBTRACE("Run from STATE!");
140  try
141  {
142  _procRef->RunFromState(_loadStateFile.c_str());
143  }
144  catch (...)
145  {
146  DEBTRACE("Runtime error: execution from the loaded state failed")
147  return;
148  }
149  }
150 }
151 
152 bool GuiExecutor::checkEndOfDataflow(bool display)
153 {
154  DEBTRACE("GuiExecutor::checkEndOfDataFlow");
155  if (_isRunning)
156  {
157  if (CORBA::is_nil(_procRef))
158  {
159  DEBTRACE("Runtime error: connection lost on a running scheme");
160  _isRunning = false;
161  return false;
162  }
163  if (_procRef->isNotFinished())
164  {
165  DEBTRACE("Remote Execution Already running...");
166  return false;
167  }
168  else
169  {
170  _isRunning = false;
171  // --- TODO: cleaning on server ...
172  }
173  }
174  return true;
175 }
176 
177 void GuiExecutor::killDataflow()
178 {
179  DEBTRACE("GuiExecutor::killDataflow");
180  if (_isRunning)
181  _procRef->stopExecution();
182 }
183 
184 void GuiExecutor::suspendDataflow()
185 {
186  DEBTRACE("GuiExecutor::suspendDataflow");
187  if (_isRunning)
188  _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
189 }
190 
191 void GuiExecutor::resumeDataflow()
192 {
193  DEBTRACE("GuiExecutor::resumeDataflow");
194  if (_isRunning)
195  {
196  _procRef->setExecMode(getCurrentExecMode());
197  _procRef->resumeCurrentBreakPoint();
198  }
199 }
200 
201 void GuiExecutor::stopDataflow()
202 {
203  DEBTRACE("GuiExecutor::stopDataflow");
204  if (_isRunning)
205  _procRef->stopExecution();
206 }
207 
208 void GuiExecutor::resetDataflow()
209 {
210  DEBTRACE("GuiExecutor::resetDataflow");
211  //update _isRunning
212  checkEndOfDataflow();
213  if (_isRunning)
214  _procRef->stopExecution();
215  checkEndOfDataflow();
216 
217  if (!_isRunning)
218  {
219  _isRunning = true;
220  _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
221  //full reset: set all nodes in error to READY state and start execution
222  _procRef->RestartFromState("");
223  }
224 }
225 
226 
227 void GuiExecutor::setStepByStepMode()
228 {
229  DEBTRACE("GuiExecutor::setStepByStepMode");
230  _execMode = YACS::STEPBYSTEP;
231  if (_isRunning)
232  _procRef->setExecMode(YACS_ORB::STEPBYSTEP);
233 }
234 
235 void GuiExecutor::setContinueMode()
236 {
237  DEBTRACE("GuiExecutor::setContinueMode");
238  _execMode = YACS::CONTINUE;
239  if (_isRunning)
240  _procRef->setExecMode(YACS_ORB::CONTINUE);
241 }
242 
243 void GuiExecutor::setBreakpointMode()
244 {
245  DEBTRACE("GuiExecutor::setBreakpointMode");
246  _execMode = YACS::STOPBEFORENODES;
247  if (_isRunning)
248  _procRef->setExecMode(YACS_ORB::STOPBEFORENODES);
249 }
250 
251 void GuiExecutor::setStopOnError(bool aMode)
252 {
253  DEBTRACE("GuiExecutor::setStopOnError " << aMode);
254  if (_isRunning)
255  {
256 #ifdef WIN32
257  _procRef->setStopOnError(aMode, (getenv("TEMP") + string("\\dumpStateOnError_") + getenv("USER") + string(".xml")).c_str());
258 #else
259  _procRef->setStopOnError(aMode, (string("/tmp/dumpStateOnError_") + getenv("USER") + string(".xml")).c_str());
260 #endif
261  _isStopOnError = true;
262  }
263 }
264 
265 void GuiExecutor::unsetStopOnError()
266 {
267  DEBTRACE("GuiExecutor::unsetStopOnError");
268  if (_isRunning)
269  {
270  _procRef->unsetStopOnError();
271  _isStopOnError = false;
272  }
273 }
274 
275 
276 void GuiExecutor::saveState(const std::string& xmlFile)
277 {
278  DEBTRACE("GuiExecutor::saveState " << xmlFile);
279  bool StartFinish = (getExecutorState() == YACS::NOTYETINITIALIZED ||
280  getExecutorState() == YACS::FINISHED);
281  if ( _isRunning ||
282  !(CORBA::is_nil(_procRef)) && StartFinish ) {
283  if ( !_procRef->saveState(xmlFile.c_str()) ) {
284  string what = "Impossible to open file for writing: " + xmlFile;
285  throw Exception(what);
286  }
287  }
288 }
289 
290 void GuiExecutor::setLoadStateFile(std::string xmlFile)
291 {
292  DEBTRACE("GuiExecutor::setLoadStateFile " << xmlFile);
293  _loadStateFile = xmlFile;
294 }
295 
296 
297 YACS_ORB::executionMode GuiExecutor::getCurrentExecMode()
298 {
299  DEBTRACE("GuiExecutor::getCurrentExecMode");
300  switch (_execMode)
301  {
302  case YACS::CONTINUE: return YACS_ORB::CONTINUE;
305  default: return YACS_ORB::CONTINUE;
306  }
307 }
308 
309 int GuiExecutor::getExecutorState()
310 {
311  DEBTRACE("GuiExecutor::getExecutorState");
312  if (_isRunning || !CORBA::is_nil(_procRef))
313  return _procRef->getExecutorState();
314  else if (CORBA::is_nil(_procRef))
316  else
317  return YACS::FINISHED;
318 }
319 
320 
321 void GuiExecutor::setBreakpointList(std::list<std::string> breakpointList)
322 {
323  DEBTRACE("GuiExecutor::setBreakpointList");
324  if (!_context)
325  {
326  DEBTRACE("context closed");
327  return;
328  }
329  _breakpointList.clear();
330  _breakpointList = breakpointList;
331  setBPList();
332  if ((_execMode == YACS::CONTINUE) && ! _breakpointList.empty())
333  {
334  _context->getGMain()->_breakpointsModeAct->setChecked(true);
335  setBreakpointMode();
336  }
337 }
338 
339 void GuiExecutor::addBreakpoint(std::string breakpoint)
340 {
341  DEBTRACE("addBreakpoint " << breakpoint);
342  if (!_context)
343  {
344  DEBTRACE("context closed");
345  return;
346  }
347  _breakpointList.push_back(breakpoint);
348  setBPList();
349  if ((_execMode == YACS::CONTINUE) && ! _breakpointList.empty())
350  {
351  _context->getGMain()->_breakpointsModeAct->setChecked(true);
352  setBreakpointMode();
353  }
354 }
355 
356 void GuiExecutor::removeBreakpoint(std::string breakpoint)
357 {
358  DEBTRACE("removeBreakpoint " << breakpoint);
359  _breakpointList.remove(breakpoint);
360  setBPList();
361 }
362 
363 void GuiExecutor::setNextStepList(std::list<std::string> nextStepList)
364 {
365  DEBTRACE("GuiExecutor::setNextStepList");
366  if (_isRunning)
367  {
368  YACS_ORB::stringArray listOfNextStep;
369  listOfNextStep.length(nextStepList.size());
370  int i=0;
371  for (list<string>::iterator it = nextStepList.begin(); it != nextStepList.end(); ++it)
372  listOfNextStep[i++] = (*it).c_str();
373  _procRef->setStepsToExecute(listOfNextStep);
374  }
375 }
376 
377 void GuiExecutor::registerStatusObservers()
378 {
379  DEBTRACE("GuiExecutor::registerStatusObservers");
380  if (CORBA::is_nil(_procRef))
381  {
382  DEBTRACE("Runtime error (yacsgui): Lost connection on YACS executor");
383  return;
384  }
385  if (CORBA::is_nil(_observerRef))
386  {
387  _serv = new GuiObserver_i(_proc);
388  _serv->SetImpl(this);
389  _observerRef = _serv->_this();
390  }
391  DEBTRACE("---");
392  _serv->SetRemoteProc(_procRef);
393  _serv->setConversion();
394  DEBTRACE("---");
395  std::list<Node*> aNodeSet = _proc->getAllRecursiveConstituents();
396  for ( std::list<Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ )
397  {
398  _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "status");
399  _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "progress");
400  }
401  _procRef->addObserver(_observerRef, _serv->getEngineId(_proc->getNumId()) , "executor");
402 }
403 
404 
405 
406 void GuiExecutor::setEngineRef(YACS_ORB::YACS_Gen_ptr ref)
407 {
408  DEBTRACE("GuiExecutor::setEngineRef");
409  _engineRef = ref;
410 }
411 
412 std::string GuiExecutor::getErrorDetails(YACS::ENGINE::Node* node)
413 {
414  DEBTRACE("GuiExecutor::getErrorDetails");
415  if (_serv)
416  {
417  int engineId=_serv->getEngineId(node->getNumId());
418  return _procRef->getErrorDetails(engineId);
419  }
420  return "---";
421 }
422 
423 std::string GuiExecutor::getErrorReport(YACS::ENGINE::Node* node)
424 {
425  DEBTRACE("GuiExecutor::getErrorReport");
426  if (_serv)
427  {
428  int engineId=_serv->getEngineId(node->getNumId());
429  return _procRef->getErrorReport(engineId);
430  }
431  return "---";
432 }
433 
434 std::string GuiExecutor::getContainerLog()
435 {
436  DEBTRACE("GuiExecutor::getContainerLog");
437  std::string msg="";
438  if (!CORBA::is_nil(_engineRef))
439  {
440  Engines::Container_var cont= _engineRef->GetContainerRef();
441  CORBA::String_var logname = cont->logfilename();
442  DEBTRACE(logname);
443  msg=logname;
444  std::string::size_type pos = msg.find(":");
445  msg=msg.substr(pos+1);
446  }
447  return msg;
448 }
449 
450 std::string GuiExecutor::getContainerLog(YACS::ENGINE::Node* node)
451 {
452  DEBTRACE("GuiExecutor::getContainerLog(YACS::ENGINE::Node* node)");
453  std::string msg;
454  if (_serv)
455  {
456  int engineId=_serv->getEngineId(node->getNumId());
457  CORBA::String_var logname = _procRef->getContainerLog(engineId);
458  msg=logname;
459  std::string::size_type pos = msg.find(":");
460  msg=msg.substr(pos+1);
461  }
462  return msg;
463 }
464 
465 void GuiExecutor::shutdownProc()
466 {
467  DEBTRACE("GuiExecutor::shutdownProc " << _shutdownLevel << "," << _isRunning);
468  checkEndOfDataflow();
469  if (!_isRunning)
470  _procRef->shutdownProc(_shutdownLevel);
471 }
472 
473 void GuiExecutor::setInPortValue(YACS::ENGINE::DataPort* port, std::string value)
474 {
475  DEBTRACE("GuiExecutor::setInPortValue");
476 
477  YACS::ENGINE::Node* node = port->getNode();
478  YACS::ENGINE::ComposedNode* rootNode = node->getRootNode();
479 
480  std::string nodeName;
481  if(rootNode == node)
482  nodeName = node->getName();
483  else
484  nodeName = rootNode->getChildName(node);
485 
486  std::string msg = _procRef->setInPortValue(nodeName.c_str(), port->getName().c_str(), value.c_str());
487 }
488 
489 bool GuiExecutor::event(QEvent *e)
490 {
491  DEBTRACE("GuiExecutor::event");
492  YACSEvent *yev = dynamic_cast<YACSEvent*>(e);
493  if (!yev) return false;
494  int numid = yev->getYACSEvent().first;
495  string event = yev->getYACSEvent().second;
496  DEBTRACE("<" << numid << "," << event << ">");
497  if (!_context)
498  {
499  DEBTRACE("context closed");
500  return true;
501  }
502  if (event == "executor") // --- Executor notification: state
503  {
504  int execState = _procRef->getExecutorState();
505  list<string> nextSteps;
506  if ((execState == YACS::WAITINGTASKS) || (execState == YACS::PAUSED))
507  {
508  YACS_ORB::stringArray_var nstp = _procRef->getTasksToLoad();
509  for (CORBA::ULong i=0; i<nstp->length(); i++)
510  nextSteps.push_back(nstp[i].in());
511  if (execState == YACS::PAUSED)
512  _isSuspended = true;
513  }
514  SubjectProc *sproc = _context->getSubjectProc();
515  sproc->update(YACS::HMI::UPDATEPROGRESS, execState, sproc);
516  }
517  else // --- Node notification
518  {
519  if (! _serv->_engineToGuiMap.count(numid))
520  return true;
521  int state = _procRef->getNodeState(numid);
522  int iGui = _serv->_engineToGuiMap[numid];
523  YASSERT(_context->_mapOfExecSubjectNode.count(iGui));
524  SubjectNode *snode = _context->_mapOfExecSubjectNode[iGui];
525  DEBTRACE("node " << snode->getName() << " state=" << state);
526 
527  if (event == "progress") { // --- Update progress bar
528  std::string progress = _procRef->getNodeProgress(numid);
529  snode->setProgress( progress );
530  snode->update(YACS::HMI::PROGRESS, state, snode);
531  }
532  else { // --- Update node ports
533  YACS::ENGINE::Node *node = snode->getNode();
534  list<InputPort*> inports = node->getLocalInputPorts();
535  list<InputPort*>::iterator iti = inports.begin();
536  for ( ; iti != inports.end(); ++iti)
537  {
538  string val = _procRef->getInPortValue(numid, (*iti)->getName().c_str());
539  DEBTRACE("node " << snode->getName() << " inport " << (*iti)->getName()
540  << " value " << val);
541  YASSERT(_context->_mapOfSubjectDataPort.count(*iti));
542  SubjectDataPort* port = _context->_mapOfSubjectDataPort[*iti];
543  port->setExecValue(val);
544  port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
545  }
546  list<OutputPort*> outports = node->getLocalOutputPorts();
547  list<OutputPort*>::iterator ito = outports.begin();
548  for ( ; ito != outports.end(); ++ito)
549  {
550  string val = _procRef->getOutPortValue(numid, (*ito)->getName().c_str());
551  DEBTRACE("node " << snode->getName() << " outport " << (*ito)->getName()
552  << " value " << val);
553  YASSERT(_context->_mapOfSubjectDataPort.count(*ito));
554  SubjectDataPort* port = _context->_mapOfSubjectDataPort[*ito];
555  port->setExecValue(val);
556  port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
557  }
558  snode->update(YACS::HMI::UPDATEPROGRESS, state, snode);
559  }
560  }
561 
562  return true;
563 }
564 
565 void GuiExecutor::setBPList()
566 {
567  DEBTRACE("GuiExecutor::setBPList");
568  if (_isRunning)
569  {
570  YACS_ORB::stringArray listOfBreakPoints;
571  listOfBreakPoints.length(_breakpointList.size());
572  int i=0;
573  for (list<string>::iterator it = _breakpointList.begin(); it != _breakpointList.end(); ++it)
574  listOfBreakPoints[i++] = (*it).c_str();
575  _procRef->setListOfBreakPoints(listOfBreakPoints);
576  }
577 }
578 
579 YACS::ExecutorState GuiExecutor::updateSchema(string jobState)
580 {
582 
583  int numid;
584  int state;
585  std::list<Node*> aNodeSet = _proc->getAllRecursiveConstituents();
586  for ( std::list<Node*>::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ){
587 
588  numid = (*it)->getNumId();
589 
590  state = _proc->getNodeState(numid);
591  SubjectNode *snode = _context->_mapOfExecSubjectNode[numid];
592 
593  YACS::ENGINE::Node *node = snode->getNode();
594  list<InputPort*> inports = node->getLocalInputPorts();
595  list<InputPort*>::iterator iti = inports.begin();
596  for ( ; iti != inports.end(); ++iti)
597  {
598  string val = _proc->getInPortValue(numid, (*iti)->getName().c_str());
599  YASSERT(_context->_mapOfSubjectDataPort.count(*iti));
600  SubjectDataPort* port = _context->_mapOfSubjectDataPort[*iti];
601  port->setExecValue(val);
602  port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
603  }
604  list<OutputPort*> outports = node->getLocalOutputPorts();
605  list<OutputPort*>::iterator ito = outports.begin();
606  for ( ; ito != outports.end(); ++ito)
607  {
608  string val = _proc->getOutPortValue(numid, (*ito)->getName().c_str());
609  YASSERT(_context->_mapOfSubjectDataPort.count(*ito));
610  SubjectDataPort* port = _context->_mapOfSubjectDataPort[*ito];
611  port->setExecValue(val);
612  port->update(YACS::HMI::UPDATEPROGRESS, 0, port);
613  }
614  snode->update(YACS::HMI::UPDATEPROGRESS, state, snode);
615  }
616  state = _proc->getRootNode()->getEffectiveState();
617  switch(state){
618  case YACS::LOADED:
619  case YACS::ACTIVATED:
620  if(jobState!="RUNNING")
621  execState = YACS::FINISHED;
622  else
623  execState = YACS::RUNNING;
624  break;
625  case YACS::FAILED:
626  case YACS::DONE:
627  execState = YACS::FINISHED;
628  break;
629  case YACS::SUSPENDED:
630  execState = YACS::PAUSED;
631  break;
632  }
633  SubjectProc *sproc = _context->getSubjectProc();
634  sproc->update(YACS::HMI::UPDATEPROGRESS, execState, sproc);
635 
636  return execState;
637 }