The Gaudi Framework  v30r5 (c7afbd0d)
ApplicationMgr.cpp
Go to the documentation of this file.
1 // Include files
2 #include "ApplicationMgr.h"
3 
4 #include "AlgorithmManager.h"
5 #include "DLLClassManager.h"
6 #include "ServiceManager.h"
7 
10 #include "GaudiKernel/IRunable.h"
11 #include "GaudiKernel/IService.h"
13 
14 #include "GaudiKernel/MsgStream.h"
16 #include "GaudiKernel/SmartIF.h"
17 
19 
20 #include "GaudiKernel/StatusCode.h"
21 #include "GaudiKernel/System.h"
22 #include "GaudiKernel/Time.h"
23 
24 #include "GaudiCoreSvcVersion.h"
25 
26 using System::getEnv;
27 using System::isEnvSet;
28 
29 #include <algorithm>
30 #include <cassert>
31 #include <ctime>
32 #include <limits>
33 
34 #define ON_DEBUG if ( UNLIKELY( m_outputLevel <= MSG::DEBUG ) )
35 #define ON_VERBOSE if ( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) )
36 
38 
39 // Implementation class for the Application Manager. In this way the
40 // ApplicationMgr class is a fully insulated concrete class. Clients
41 // (main programs) will not need to re-compile if there are changes
42 // in the implementation
43 
44 //=======================================================================
45 // Constructor
46 //=======================================================================
48 {
49  // IInterface initialization
50  addRef(); // Initial count set to 1
51 
52  // Instantiate component managers
53  m_managers[IService::interfaceID().id()] = new ServiceManager( this );
54 
55  m_svcLocator = svcManager();
56 
57  // Instantiate internal services
58  // SvcLocator/Factory HAS to be already instantiated
59  m_classManager = new DLLClassManager( this );
60 
61  AlgorithmManager* algMgr = new AlgorithmManager( this );
62  m_managers[IAlgorithm::interfaceID().id()] = algMgr;
63  // m_managers[IAlgorithm::interfaceID().id()] = new HiveAlgorithmManager(this);
64 
65  // This property is not hosted in the ApplicationMgr instance
66  declareProperty( "AlgTypeAliases", algMgr->typeAliases(),
67  "Aliases of algorithm types, to replace an algorithm type for every instance" );
68 
69  // ServiceMgr Initialization loop checking
70  svcManager()->setLoopCheckEnabled( m_loopCheck );
71 
72  m_svcMapping = {"EvtDataSvc/EventDataSvc",
73  "DetDataSvc/DetectorDataSvc",
74  "HistogramSvc/HistogramDataSvc",
75  "HbookCnv::PersSvc/HbookHistSvc",
76  "RootHistCnv::PersSvc/RootHistSvc",
77  "EvtPersistencySvc/EventPersistencySvc",
78  "DetPersistencySvc/DetectorPersistencySvc",
79  "HistogramPersistencySvc/HistogramPersistencySvc"};
80 }
81 
82 //============================================================================
83 // IInterface implementation: queryInterface::addRef()
84 //============================================================================
86 {
87  if ( !ppvi ) {
88  return StatusCode::FAILURE;
89  }
90 
91  // try to find own/direct interfaces:
92  StatusCode sc = base_class::queryInterface( iid, ppvi );
93  if ( sc.isSuccess() ) return sc;
94 
95  // find indirect interfaces :
96  if ( ISvcLocator::interfaceID().versionMatch( iid ) ) {
97  return serviceLocator()->queryInterface( iid, ppvi );
98  }
99  if ( ISvcManager::interfaceID().versionMatch( iid ) ) {
100  return svcManager()->queryInterface( iid, ppvi );
101  }
102  if ( IAlgManager::interfaceID().versionMatch( iid ) ) {
103  return algManager()->queryInterface( iid, ppvi );
104  }
105  if ( IClassManager::interfaceID().versionMatch( iid ) ) {
106  return m_classManager->queryInterface( iid, ppvi );
107  }
108  if ( IMessageSvc::interfaceID().versionMatch( iid ) ) {
109  *ppvi = m_messageSvc.get();
110  if ( m_messageSvc ) m_messageSvc->addRef();
111  // Note that 0 can be a valid IMessageSvc pointer value (when used for
112  // MsgStream).
113  return StatusCode::SUCCESS;
114  }
115  *ppvi = nullptr;
116  return StatusCode::FAILURE;
117 }
118 
119 //============================================================================
120 // ApplicationMgr::i_startup()
121 //============================================================================
123 {
124 
125  StatusCode sc;
126 
127  // declare factories in current module
129 
130  // Note: we cannot use CommonMessaging methods here because MessageSvc is not there yet
131  MsgStream log( nullptr, name() );
132 
133  // Create the Message service
134  auto msgsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "MessageSvc", m_messageSvcType ) );
135  if ( !msgsvc ) {
136  log << MSG::FATAL << "Error creating MessageSvc of type " << m_messageSvcType << endmsg;
137  return StatusCode::FAILURE;
138  }
139  // Get the useful interface from Message services
140  m_messageSvc = m_svcLocator->service( "MessageSvc" );
141  if ( !m_messageSvc ) {
142  log << MSG::FATAL << "Error retrieving MessageSvc." << endmsg;
143  return StatusCode::FAILURE;
144  }
145 
146  auto jobsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "JobOptionsSvc", m_jobOptionsSvcType ) );
147  // Create the Job Options service
148  if ( !jobsvc ) {
149  log << MSG::FATAL << "Error creating JobOptionsSvc" << endmsg;
150  return StatusCode::FAILURE;
151  }
152  // Get the useful interface from Message services
153  m_jobOptionsSvc = m_svcLocator->service( "JobOptionsSvc" );
154  if ( !m_jobOptionsSvc ) {
155  log << MSG::FATAL << "Error retrieving JobOptionsSvc." << endmsg;
156  return StatusCode::FAILURE;
157  }
158 
159  auto jobOptsIProp = jobsvc.as<IProperty>();
160  if ( !jobOptsIProp ) {
161  log << MSG::FATAL << "Error locating JobOptionsSvc" << endmsg;
162  return StatusCode::FAILURE;
163  }
164  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "TYPE", m_jobOptionsType ) );
165  if ( !sc.isSuccess() ) {
166  log << MSG::FATAL << "Error setting TYPE option in JobOptionsSvc" << endmsg;
167  return sc;
168  }
169 
170  if ( !m_jobOptionsPreAction.empty() ) {
171  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONPARAMS", m_jobOptionsPreAction ) );
172  if ( !sc.isSuccess() ) {
173  log << MSG::FATAL << "Error setting JobOptionsPreAction option in JobOptionsSvc" << endmsg;
174  return sc;
175  }
176  }
177 
178  if ( !m_jobOptionsPostAction.empty() ) {
179  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONACTION", m_jobOptionsPostAction ) );
180  if ( !sc.isSuccess() ) {
181  log << MSG::FATAL << "Error setting JobOptionsPostAction option in JobOptionsSvc" << endmsg;
182  return sc;
183  }
184  }
185 
186  if ( !m_jobOptionsPath.empty() ) { // The command line takes precedence
187  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", m_jobOptionsPath ) );
188  if ( !sc.isSuccess() ) {
189  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc" << endmsg;
190  return sc;
191  }
192  } else if ( isEnvSet( "JOBOPTPATH" ) ) { // Otherwise the Environment JOBOPTPATH
193  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", getEnv( "JOBOPTPATH" ) ) );
194  if ( !sc.isSuccess() ) {
195  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc from env" << endmsg;
196  return sc;
197  }
198  } else { // Otherwise the default
199  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", "../options/job.opts" ) );
200  if ( !sc.isSuccess() ) {
201  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc to default" << endmsg;
202  return sc;
203  }
204  }
205  jobOptsIProp.reset();
206 
207  // Sets my default the Output Level of the Message service to be
208  // the same as this
209  auto msgSvcIProp = msgsvc.as<IProperty>();
210  msgSvcIProp->setProperty( Gaudi::Property<int>( "OutputLevel", m_outputLevel ) ).ignore();
211  msgSvcIProp.reset();
212 
213  sc = jobsvc->sysInitialize();
214  if ( !sc.isSuccess() ) {
215  log << MSG::FATAL << "Error initializing JobOptionsSvc" << endmsg;
216  return sc;
217  }
218  sc = msgsvc->sysInitialize();
219  if ( !sc.isSuccess() ) {
220  log << MSG::FATAL << "Error initializing MessageSvc" << endmsg;
221  return sc;
222  }
223 
224  // Make sure output level caches are up to date.
226 
227  return sc;
228 }
229 
230 //============================================================================
231 // IAppMgrUI implementation: ApplicationMgr::configure()
232 //============================================================================
234 {
235 
236  // Check if the state is compatible with the transition
237  MsgStream tlog( m_messageSvc, name() );
239  tlog << MSG::INFO << "Already Configured" << endmsg;
240  return StatusCode::SUCCESS;
241  }
243  tlog << MSG::FATAL << "configure: Invalid state \"" << m_state << "\"" << endmsg;
244  return StatusCode::FAILURE;
245  }
247 
248  // Reset application return code.
250 
251  StatusCode sc;
252  sc = i_startup();
253  if ( !sc.isSuccess() ) {
254  return sc;
255  }
256 
257  {
259  // Get my own options using the Job options service
260  if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
261  sc = m_jobOptionsSvc->setMyProperties( name(), this );
262  if ( !sc.isSuccess() ) {
263  log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
264  return sc;
265  }
266  }
267 
268  // Make sure that the OutputLevel is in sync
271 
272  // Check current outputLevel to eventually inform the MessageSvc
273  if ( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
274  // Print a welcome message
275  log << MSG::ALWAYS << std::endl
276  << "=================================================================="
277  << "==================================================================" << std::endl
278  << " "
279  << " Welcome to " << m_appName.value();
280 
281  if ( !m_appVersion.empty() ) {
282  log << MSG::ALWAYS << " version " << m_appVersion.value();
283  } else {
284  log << MSG::ALWAYS << " (GaudiCoreSvc "
285  << "v" << GAUDICORESVC_MAJOR_VERSION << "r" << GAUDICORESVC_MINOR_VERSION
286 #if GAUDICORESVC_PATCH_VERSION
287  << "p" << GAUDICORESVC_PATCH_VERSION
288 #endif
289  << ")";
290  }
291 
292  // Add the host name and current time to the message
293  log << MSG::ALWAYS << std::endl
294  << " "
295  << " running on " << System::hostName() << " on " << Gaudi::Time::current().format( true ) << std::endl
296  << "=================================================================="
297  << "==================================================================" << endmsg;
298  }
299 
300  // print all own properties if the options "PropertiesPrint" is set to true
301  if ( m_propertiesPrint ) {
302  const auto& properties = getProperties();
303  log << MSG::ALWAYS << "List of ALL properties of " << System::typeinfoName( typeid( *this ) ) << "/" << this->name()
304  << " #properties = " << properties.size() << endmsg;
305  for ( const auto& property : properties ) {
306  log << "Property ['Name': Value] = " << *property << endmsg;
307  }
308  }
309 
310  // Check if StatusCode need to be checked
311  if ( m_codeCheck ) {
313  sc = svcManager()->addService( "StatusCodeSvc", -9999 );
314  if ( sc.isFailure() ) {
315  log << MSG::FATAL << "Error adding StatusCodeSvc" << endmsg;
316  return StatusCode::FAILURE;
317  } else {
318  ON_VERBOSE
319  log << MSG::VERBOSE << "added service StatusCodeSvc" << endmsg;
320  }
321  } else {
323  }
324 
325  // set the requested environment variables
326  for ( auto& var : m_environment ) {
327  const std::string& name = var.first;
328  const std::string& value = var.second;
329  std::string old = System::getEnv( name.c_str() );
330  const MSG::Level lvl = ( !old.empty() && ( old != "UNKNOWN" ) ) ? MSG::WARNING : MSG::DEBUG;
331  if ( UNLIKELY( m_outputLevel <= lvl ) ) log << lvl << "Setting " << name << " = " << value << endmsg;
332  System::setEnv( name, value );
333  }
334 
335  // Declare Service Types
336  for ( auto& j : m_svcMapping ) {
338  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
339  log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
340  return StatusCode::FAILURE;
341  } else {
342  ON_VERBOSE
343  log << MSG::VERBOSE << "declared service " << j << endmsg;
344  }
345  }
346  for ( auto& j : m_svcOptMapping ) {
348  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
349  log << MSG::ERROR << "declaring svc type:'" << j << "' failed." << endmsg;
350  return StatusCode::FAILURE;
351  }
352  }
353 
354  //--------------------------------------------------------------------------
355  // Declare other Services and Algorithms by loading DLL's
356  sc = decodeDllNameList();
357  if ( sc.isFailure() ) {
358  log << MSG::ERROR << "Failure loading declared DLL's" << endmsg;
359  return sc;
360  }
361 
362  //--------------------------------------------------------------------------
363  // Deal with the services explicitly declared by the user.
364  sc = decodeExtSvcNameList();
365  if ( sc.isFailure() ) {
366  log << MSG::ERROR << "Failure during external service association" << endmsg;
367  return sc;
368  }
369 
371  if ( sc.isFailure() ) {
372  log << MSG::ERROR << "Failure during external service creation" << endmsg;
373  return sc;
374  }
375 
376  //--------------------------------------------------------------------------
377  // Retrieve intrinsic services. If needed configure them.
378  //--------------------------------------------------------------------------
379  const Gaudi::Utils::TypeNameString evtloop_item( m_eventLoopMgr );
380  sc = svcManager()->addService( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
381  if ( !sc.isSuccess() ) {
382  log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endmsg;
383  return sc;
384  } else {
385  ON_VERBOSE
386  log << MSG::VERBOSE << "added service " << evtloop_item << endmsg;
387  }
388 
390  if ( !m_runable ) {
391  log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
392  << m_runableType.name() << endmsg;
393  return sc;
394  }
395  m_processingMgr = m_svcLocator->service( evtloop_item );
396  if ( !m_processingMgr ) {
397  log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
398  << "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
399  return sc;
400  }
401 
402  // Establish Update Handlers for ExtSvc and DLLs Properties
403  m_extSvcNameList.declareUpdateHandler( &ApplicationMgr::extSvcNameListHandler, this );
404  m_createSvcNameList.declareUpdateHandler( &ApplicationMgr::createSvcNameListHandler, this );
405  m_dllNameList.declareUpdateHandler( &ApplicationMgr::dllNameListHandler, this );
406 
407  if ( m_actHistory ) {
408  // Create HistorySvc with a priority to ensure it's initialized last, finalized first
409  sc = svcManager()->addService( "HistorySvc", std::numeric_limits<int>::max() );
410  if ( sc.isFailure() ) {
411  log << MSG::FATAL << "Error adding HistorySvc" << endmsg;
412  return StatusCode::FAILURE;
413  }
414  }
415 
416  log << MSG::INFO << "Application Manager Configured successfully" << endmsg;
418  return StatusCode::SUCCESS;
419 }
420 
421 //============================================================================
422 // IAppMgrUI implementation: ApplicationMgr::initialize()
423 //============================================================================
425 {
426  StatusCode sc;
427 
429 
430  // Make sure output level caches are up to date.
432 
433  // I cannot add these services in configure() because they are coming from GaudiUtils
434  // and it messes up genconf when rebuilding it.
435  if ( m_stopOnSignal ) {
436  // Instantiate the service that schedules a stop when a signal is received
437  std::string svcname( "Gaudi::Utils::StopSignalHandler" );
438  sc = svcManager()->addService( svcname );
439  if ( sc.isFailure() ) {
440  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
441  }
442  }
443 
444  if ( m_stalledEventMonitoring ) {
445  // Instantiate the service that schedules a stop when a signal is received
446  std::string svcname( "StalledEventMonitor" );
447  sc = svcManager()->addService( svcname );
448  if ( sc.isFailure() ) {
449  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
450  }
451  }
452 
454  log << MSG::INFO << "Already Initialized!" << endmsg;
455  return StatusCode::SUCCESS;
456  }
458  log << MSG::FATAL << "initialize: Invalid state \"" << m_state << "\"" << endmsg;
459  return StatusCode::FAILURE;
460  }
462 
463  //--------------------------------------------------------------------------
464  // Initialize the list of top Services
465  //--------------------------------------------------------------------------
466  sc = svcManager()->initialize();
467  if ( !sc.isSuccess() ) return sc;
468 
469  sc = algManager()->initialize();
470  if ( !sc.isSuccess() ) return sc;
471 
472  //--------------------------------------------------------------------------
473  // Final steps: Inform user and change internal state
474  //--------------------------------------------------------------------------
475  log << MSG::INFO << "Application Manager Initialized successfully" << endmsg;
477 
478  return sc;
479 }
480 
481 //============================================================================
482 // IAppMgrUI implementation: ApplicationMgr::start()
483 //============================================================================
485 {
486 
488  StatusCode sc;
489 
491  log << MSG::INFO << "Already Initialized!" << endmsg;
492  return StatusCode::SUCCESS;
493  }
495  log << MSG::FATAL << "start: Invalid state \"" << m_state << "\"" << endmsg;
496  return StatusCode::FAILURE;
497  }
499 
500  //--------------------------------------------------------------------------
501  // Initialize the list of top Services
502  //--------------------------------------------------------------------------
503  sc = svcManager()->start();
504  if ( !sc.isSuccess() ) return sc;
505 
506  sc = algManager()->start();
507  if ( !sc.isSuccess() ) return sc;
508 
509  //--------------------------------------------------------------------------
510  // Final steps: Inform user and change internal state
511  //--------------------------------------------------------------------------
512  log << MSG::INFO << "Application Manager Started successfully" << endmsg;
514 
515  return sc;
516 }
517 
518 //============================================================================
519 // IAppMgrUI implementation: ApplicationMgr::nextEvent(int)
520 //============================================================================
522 {
525  log << MSG::FATAL << "nextEvent: Invalid state \"" << m_state << "\"" << endmsg;
526  return StatusCode::FAILURE;
527  }
528  if ( !m_processingMgr ) {
530  log << MSG::FATAL << "No event processing manager specified. Check option: " << m_eventLoopMgr.name() << endmsg;
531  return StatusCode::FAILURE;
532  }
533  return m_processingMgr->nextEvent( maxevt );
534 }
535 
536 //============================================================================
537 // IAppMgrUI implementation: ApplicationMgr::stop()
538 //============================================================================
540 {
541 
543  StatusCode sc;
544 
546  log << MSG::INFO << "Already Initialized!" << endmsg;
547  return StatusCode::SUCCESS;
548  }
550  log << MSG::FATAL << "stop: Invalid state \"" << m_state << "\"" << endmsg;
551  return StatusCode::FAILURE;
552  }
554 
555  // Stop independently managed Algorithms
556  sc = algManager()->stop();
557  if ( !sc.isSuccess() ) return sc;
558 
559  //--------------------------------------------------------------------------
560  // Stop the list of top Services
561  //--------------------------------------------------------------------------
562  sc = svcManager()->stop();
563  if ( !sc.isSuccess() ) return sc;
564 
565  //--------------------------------------------------------------------------
566  // Final steps: Inform user and change internal state
567  //--------------------------------------------------------------------------
568  log << MSG::INFO << "Application Manager Stopped successfully" << endmsg;
570 
571  return sc;
572 }
573 
574 //============================================================================
575 // IAppMgrUI implementation: ApplicationMgr::finalize()
576 //============================================================================
578 {
581  log << MSG::INFO << "Already Finalized" << endmsg;
582  return StatusCode::SUCCESS;
583  }
585  log << MSG::FATAL << "finalize: Invalid state \"" << m_state << "\"" << endmsg;
586  return StatusCode::FAILURE;
587  }
589 
590  // disable message suppression in finalize
591  m_svcLocator->service<IProperty>( "MessageSvc" )
592  ->setProperty( Gaudi::Property<bool>( "enableSuppression", false ) )
593  .ignore();
594 
595  // Finalize independently managed Algorithms
596  StatusCode sc = algManager()->finalize();
597  if ( sc.isFailure() ) {
598  log << MSG::WARNING << "Failed to finalize an algorithm." << endmsg;
600  }
601 
602  // Finalize all Services
603  sc = svcManager()->finalize();
604  if ( sc.isFailure() ) {
605  log << MSG::WARNING << "Failed to finalize a service." << endmsg;
607  }
608 
609  // svcManager()->removeService( (IService*) m_processingMgr.get() );
610  // svcManager()->removeService( (IService*) m_runable.get() );
611 
612  if ( m_codeCheck ) {
614  }
615 
616  if ( sc.isSuccess() ) {
617  log << MSG::INFO << "Application Manager Finalized successfully" << endmsg;
618  } else {
619  log << MSG::ERROR << "Application Manager failed to finalize" << endmsg;
620  }
621 
623  return sc;
624 }
625 
626 //============================================================================
627 // IAppMgrUI implementation: ApplicationMgr::terminate()
628 //============================================================================
630 {
632 
634  log << MSG::INFO << "Already Offline" << endmsg;
635  return StatusCode::SUCCESS;
636  }
638  log << MSG::FATAL << "terminate: Invalid state \"" << m_state << "\"" << endmsg;
639  return StatusCode::FAILURE;
640  }
641  // release all Services
643 
644  if ( m_returnCode.value() == Gaudi::ReturnCode::Success ) {
645  log << MSG::INFO << "Application Manager Terminated successfully" << endmsg;
646  } else if ( m_returnCode.value() == Gaudi::ReturnCode::ScheduledStop ) {
647  log << MSG::INFO << "Application Manager Terminated successfully with a user requested ScheduledStop" << endmsg;
648  } else {
649  log << MSG::ERROR << "Application Manager Terminated with error code " << m_returnCode.value() << endmsg;
650  }
651 
652  { // Force a disable the auditing of finalize for MessageSvc
653  auto prop = m_messageSvc.as<IProperty>();
654  if ( prop ) {
655  prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore();
656  }
657  }
658  { // Force a disable the auditing of finalize for JobOptionsSvc
659  auto prop = m_jobOptionsSvc.as<IProperty>();
660  if ( prop ) {
661  prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore();
662  }
663  }
664 
665  // finalize MessageSvc
666  auto svc = m_messageSvc.as<IService>();
667  if ( !svc ) {
668  log << MSG::ERROR << "Could not get the IService interface of the MessageSvc" << endmsg;
669  } else {
670  svc->sysFinalize().ignore();
671  }
672 
673  // finalize JobOptionsSvc
674  svc = m_jobOptionsSvc.as<IService>();
675  if ( !svc ) {
676  log << MSG::ERROR << "Could not get the IService interface of the JobOptionsSvc" << endmsg;
677  } else {
678  svc->sysFinalize().ignore();
679  }
680 
682  return StatusCode::SUCCESS;
683 }
684 
685 //============================================================================
686 // Reach the required state going through all the needed transitions
687 //============================================================================
689 {
691 
692  switch ( state ) {
693 
695  switch ( m_state ) {
697  return StatusCode::SUCCESS;
698  break;
700  return terminate();
701  break;
702  default: // Gaudi::StateMachine::INITIALIZED or Gaudi::StateMachine::RUNNING
704  if ( sc.isSuccess() ) {
705  return terminate();
706  }
707  break;
708  }
709  break;
710 
712  switch ( m_state ) {
714  return StatusCode::SUCCESS;
715  break;
717  return configure();
718  break;
720  return finalize();
721  break;
722  default: // Gaudi::StateMachine::RUNNING
724  if ( sc.isSuccess() ) {
725  return finalize();
726  }
727  break;
728  }
729  break;
730 
732  switch ( m_state ) {
734  return StatusCode::SUCCESS;
735  break;
737  return initialize();
738  break;
740  return stop();
741  break;
742  default: // Gaudi::StateMachine::OFFLINE
744  if ( sc.isSuccess() ) {
745  return initialize();
746  }
747  break;
748  }
749  break;
750 
752  switch ( m_state ) {
754  return StatusCode::SUCCESS;
755  break;
757  return start();
758  break;
759  default: // Gaudi::StateMachine::OFFLINE or Gaudi::StateMachine::CONFIGURED
761  if ( sc.isSuccess() ) {
762  return start();
763  }
764  break;
765  }
766  break;
767  }
768 
769  // If I get here, there has been a problem in the recursion
770 
771  if ( ignoreFailures ) {
772  // force the new state
773  m_state = state;
774  return StatusCode::SUCCESS;
775  }
776 
777  return sc;
778 }
779 
780 //============================================================================
781 // IAppMgrUI implementation: ApplicationMgr::run()
782 //============================================================================
784 {
786 
788  if ( sc.isSuccess() ) {
790  if ( m_runable != 0 ) { // loop over the events
791  sc = m_runable->run();
792  if ( !sc.isSuccess() ) {
793  log << MSG::FATAL << "Application execution failed. Ending the job." << endmsg;
794  }
795  } else {
796  log << MSG::FATAL << "Application has no runable object. Check option:" << m_runableType.name() << endmsg;
797  }
798  }
799  if ( sc.isSuccess() ) { // try to close cleanly
801  }
802  // either the runable failed of the stut-down
803  if ( sc.isFailure() ) { // try to close anyway (but keep the StatusCode unchanged)
805  }
806  return sc;
807 }
808 
809 //============================================================================
810 // IEventProcessor implementation: executeEvent(void* par)
811 //============================================================================
813 {
816  if ( m_processingMgr ) {
817  return m_processingMgr->executeEvent( par );
818  }
819  }
820  log << MSG::FATAL << "executeEvent: Invalid state \"" << FSMState() << "\"" << endmsg;
821  return StatusCode::FAILURE;
822 }
823 
824 //============================================================================
825 // IEventProcessor implementation: executeRun(int)
826 //============================================================================
828 {
831  if ( m_processingMgr ) {
832  return m_processingMgr->executeRun( evtmax );
833  }
834  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
835  return StatusCode::SUCCESS;
836  }
837  log << MSG::FATAL << "executeRun: Invalid state \"" << FSMState() << "\"" << endmsg;
838  return StatusCode::FAILURE;
839 }
840 
841 //============================================================================
842 // IEventProcessor implementation: stopRun(int)
843 //============================================================================
845 {
848  if ( m_processingMgr ) {
849  return m_processingMgr->stopRun();
850  }
851  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
852  return StatusCode::SUCCESS;
853  }
854  log << MSG::FATAL << "stopRun: Invalid state \"" << FSMState() << "\"" << endmsg;
855  return StatusCode::FAILURE;
856 }
857 // Implementation of IAppMgrUI::name
858 const std::string& ApplicationMgr::name() const { return m_name; }
859 
860 // implementation of IService::state
862 // implementation of IService::state
864 
865 //============================================================================
866 // implementation of IService::reinitilaize
867 //============================================================================
869 {
871  StatusCode sc;
873  throw GaudiException( "Cannot reinitialize application if not INITIALIZED or RUNNING",
874  "ApplicationMgr::reinitialize", StatusCode::FAILURE );
875  }
878  }
879  sc = svcManager()->reinitialize();
880  if ( sc.isFailure() ) retval = sc;
881  sc = algManager()->reinitialize();
882  if ( sc.isFailure() ) retval = sc;
883  return retval;
884 }
885 
886 //============================================================================
887 // implementation of IService::reinitiaize
888 //============================================================================
890 {
892  StatusCode sc;
894  throw GaudiException( "Cannot restart application if not RUNNING", "ApplicationMgr::restart", StatusCode::FAILURE );
895  }
896  sc = svcManager()->restart();
897  if ( sc.isFailure() ) retval = sc;
898  sc = algManager()->restart();
899  if ( sc.isFailure() ) retval = sc;
900  return retval;
901 }
902 
903 //============================================================================
904 // Handle properties of the event loop manager (Top alg/Output stream list)
905 //============================================================================
907 {
908  if ( m_processingMgr ) {
909  auto props = m_processingMgr.as<IProperty>();
910  if ( props ) props->setProperty( p ).ignore();
911  }
912 }
913 
914 //============================================================================
915 // External Service List handler
916 //============================================================================
918 {
919  if ( !( decodeCreateSvcNameList() ).isSuccess() ) {
920  throw GaudiException( "Failed to create ext services", "MinimalEventLoopMgr::createSvcNameListHandler",
922  }
923 }
924 //============================================================================
925 // decodeCreateSvcNameList
926 //============================================================================
928 {
930  const auto& theNames = m_createSvcNameList.value();
931  auto it = theNames.begin();
932  auto et = theNames.end();
933  while ( result.isSuccess() && it != et ) {
934  Gaudi::Utils::TypeNameString item( *it++ );
935  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
937  log << MSG::ERROR << "decodeCreateSvcNameList: Cannot create service " << item.type() << "/" << item.name()
938  << endmsg;
939  } else {
940  ON_DEBUG
941  {
943  log << MSG::DEBUG << "decodeCreateSvcNameList: Created service " << item.type() << "/" << item.name() << endmsg;
944  }
945  }
946  }
947  return result;
948 }
949 
950 //============================================================================
951 // External Service List handler
952 //============================================================================
954 {
955  if ( !( decodeExtSvcNameList() ).isSuccess() ) {
956  throw GaudiException( "Failed to declare ext services", "MinimalEventLoopMgr::extSvcNameListHandler",
958  }
959 }
960 
961 //============================================================================
962 // decodeExtSvcNameList
963 //============================================================================
965 {
967 
968  const auto& theNames = m_extSvcNameList.value();
969 
970  auto it = theNames.begin();
971  auto et = theNames.end();
972  while ( result.isSuccess() && it != et ) {
973  Gaudi::Utils::TypeNameString item( *it++ );
974  if ( m_extSvcCreates ) {
975  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
977  log << MSG::ERROR << "decodeExtSvcNameList: Cannot create service " << item.type() << "/" << item.name()
978  << endmsg;
979  }
980  } else {
981  if ( ( result = svcManager()->declareSvcType( item.name(), item.type() ) ).isFailure() ) {
983  log << MSG::ERROR << "decodeExtSvcNameList: Cannot declare service " << item.type() << "/" << item.name()
984  << endmsg;
985  }
986  }
987  }
988  return result;
989 }
990 
991 //============================================================================
992 // Dll List handler
993 //============================================================================
995 {
996  if ( !( decodeDllNameList() ).isSuccess() ) {
997  throw GaudiException( "Failed to load DLLs.", "MinimalEventLoopMgr::dllNameListHandler", StatusCode::FAILURE );
998  }
999 }
1000 
1001 //============================================================================
1002 // decodeDllNameList
1003 //============================================================================
1005 {
1006 
1009 
1010  // Clean up multiple entries from DLL list
1011  // -------------------------------------------------------------------------
1012  std::vector<std::string> newList;
1013  std::map<std::string, unsigned int> dllInList, duplicateList;
1014  {
1015  for ( const auto it : m_dllNameList ) {
1016  if ( 0 == dllInList[it] ) {
1017  newList.push_back( it ); // first instance of this module
1018  } else {
1019  ++duplicateList[it];
1020  } // module listed multiple times
1021  ++dllInList[it]; // increment count for this module
1022  }
1023  }
1024  // m_dllNameList = newList; // update primary list to new, filtered list (do not use the
1025  // property itself otherwise we get called again infinitely)
1026  // List modules that were in there twice..
1027  ON_DEBUG if ( !duplicateList.empty() )
1028  {
1029  log << MSG::DEBUG << "Removed duplicate entries for modules : ";
1030  for ( auto it = duplicateList.begin(); it != duplicateList.end(); ++it ) {
1031  log << it->first << "(" << 1 + it->second << ")";
1032  if ( it != --duplicateList.end() ) log << ", ";
1033  }
1034  log << endmsg;
1035  }
1036  // -------------------------------------------------------------------------
1037 
1038  const std::vector<std::string>& theNames = newList;
1039 
1040  // only load the new dlls or previously failed dlls
1041  ON_DEBUG log << MSG::DEBUG << "Loading declared DLL's" << endmsg;
1042 
1043  std::vector<std::string> successNames, failNames;
1044  for ( const auto& it : theNames ) {
1045  if ( std::find( m_okDlls.rbegin(), m_okDlls.rend(), it ) == m_okDlls.rend() ) {
1046  // found a new module name
1047  StatusCode status = m_classManager->loadModule( it );
1048  if ( status.isFailure() ) {
1049  failNames.push_back( it );
1050  result = StatusCode::FAILURE;
1051  } else {
1052  successNames.push_back( it );
1053  }
1054  }
1055  }
1056 
1057  // report back to the user and store the names of the succesfully loaded dlls
1058  if ( !successNames.empty() ) {
1059  log << MSG::INFO << "Successfully loaded modules : ";
1060  for ( auto it = successNames.begin(); it != successNames.end(); it++ ) {
1061  log << ( *it );
1062  if ( ( it + 1 ) != successNames.end() ) log << ", ";
1063  // save name
1064  m_okDlls.push_back( *it );
1065  }
1066  log << endmsg;
1067  }
1068 
1069  if ( result == StatusCode::FAILURE ) {
1070  log << MSG::WARNING << "Failed to load modules: ";
1071  for ( auto it = failNames.begin(); it != failNames.end(); it++ ) {
1072  log << ( *it );
1073  if ( ( it + 1 ) != failNames.end() ) log << ", ";
1074  }
1075  log << endmsg;
1076  }
1077  return result;
1078 }
1079 
1081 {
1082  resetMessaging();
1083  for ( auto& mgrItem : m_managers ) {
1084  mgrItem.second->outputLevelUpdate();
1085  }
1086 }
The ServiceManager class is in charge of the creation of concrete instances of Services.
Gaudi::StateMachine::State m_targetState
Internal State.
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition: System.cpp:411
The AlgorithmManager class is in charge of the creation of concrete instances of Algorithms.
StatusCode initialize() override
constexpr int FinalizationFailure
Error codes for operation failures.
Definition: AppReturnCode.h:34
#define UNLIKELY(x)
Definition: Kernel.h:89
virtual StatusCode addService(IService *svc, int prio=DEFAULT_SVC_PRIORITY)=0
Add a service to the "active" list of services of the factory.
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
Gaudi::Property< bool > m_propertiesPrint
virtual StatusCode stopRun()=0
Schedule a stop of the current event processing.
T empty(T...args)
virtual StatusCode run()=0
Run the class implementation.
Define general base for Gaudi exception.
StatusCode decodeDllNameList()
Gaudi::Property< int > m_returnCode
Property to record the error conditions occurring during the running.
GAUDI_API int setEnv(const std::string &name, const std::string &value, int overwrite=1)
Set an environment variables.
Definition: System.cpp:534
Gaudi::Property< bool > m_stopOnSignal
Property to enable/disable the "stop on signal" service.
StatusCode loadModule(const std::string &module, bool fireIncident=true) override
Gaudi::Property< bool > m_codeCheck
SmartIF< IRunable > m_runable
Reference to the runable object.
Implementation of property with value of concrete type.
Definition: Property.h:383
StatusCode setProperty(const Gaudi::Details::PropertyBase &p) override
set the property form another property
const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const override
get all properties
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:332
T rend(T...args)
ManagersMap m_managers
Map of known component managers.
Gaudi::Property< std::string > m_jobOptionsType
bool isSuccess() const
Definition: StatusCode.h:287
const std::string & name() const override
T endl(T...args)
static Time current()
Returns the current time.
Definition: Time.cpp:112
Gaudi::Property< std::map< std::string, std::string > > m_environment
void outputLevelUpdate() override
Function to call to update the outputLevel of the components (after a change in MessageSvc).
virtual StatusCode executeEvent(void *par=0)=0
Process single event.
Gaudi::Property< std::string > m_appVersion
T end(T...args)
static GAUDI_API void enableChecking()
Definition: StatusCode.cpp:40
std::vector< std::string > m_okDlls
names of successfully loaded dlls
State
Allowed states for classes implementing the state machine (ApplicationMgr, Algorithm, Service, AlgTool).
Definition: StateMachine.h:14
StatusCode nextEvent(int maxevt) override
SmartIF< IJobOptionsSvc > m_jobOptionsSvc
Reference to JobOption service.
AlgTypeAliasesMap & typeAliases()
void createSvcNameListHandler(Gaudi::Details::PropertyBase &)
bool isFailure() const
Definition: StatusCode.h:139
SmartIF< IEventProcessor > m_processingMgr
Reference to processing manager object.
StatusCode terminate() override
SmartIF< ISvcManager > & svcManager()
virtual StatusCode start()=0
Start (from INITIALIZED to RUNNING).
constexpr int ScheduledStop
Definition: AppReturnCode.h:27
Gaudi::Property< std::string > m_eventLoopMgr
STL class.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
virtual StatusCode nextEvent(int maxevt)=0
Process the next maxevt events.
void evtLoopPropertyHandler(Gaudi::Details::PropertyBase &theProp)
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:79
T push_back(T...args)
Interface ID class.
Definition: IInterface.h:29
virtual StatusCode setProperty(const Gaudi::Details::PropertyBase &p)=0
Set the property by property.
Gaudi::Property< int > m_outputLevel
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:115
Helper class to parse a string of format "type/name".
StatusCode executeRun(int evtmax) override
implementation of IEventProcessor::executeRun(int)
virtual StatusCode stop()=0
Stop (from RUNNING to INITIALIZED).
virtual StatusCode reinitialize()=0
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
Gaudi::StateMachine::State targetFSMState() const override
void extSvcNameListHandler(Gaudi::Details::PropertyBase &theProp)
General service interface definition.
Definition: IService.h:18
#define ON_DEBUG
SmartIF< ISvcLocator > m_svcLocator
Reference to its own service locator (must be instantiated prior to any service!) ...
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
virtual SmartIF< IService > & createService(const Gaudi::Utils::TypeNameString &nametype)=0
Creates and instance of a service type that has been declared beforehand and assigns it a name...
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, TYPE &value, const std::string &doc="none")
Declare a property (templated)
Definition of the basic interface.
Definition: IInterface.h:277
virtual StatusCode setMyProperties(const std::string &client, IProperty *me)=0
Override default properties of the calling client.
Gaudi::Property< std::vector< std::string > > m_extSvcNameList
#define DECLARE_OBJECT_FACTORY(x)
Definition: ObjectFactory.h:15
void dllNameListHandler(Gaudi::Details::PropertyBase &theProp)
Gaudi::Property< std::string > m_runableType
Gaudi::Property< bool > m_stalledEventMonitoring
Property to enable/disable the monitoring and reporting of stalled events.
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:34
StatusCode GoToState(Gaudi::StateMachine::State state, bool ignoreFailures=false)
Reach a state from current state (whichever it is) going through the correct transitions.
StatusCode finalize() override
Gaudi::Property< std::vector< std::string > > m_svcOptMapping
virtual StatusCode initialize()=0
Initialization (from CONFIGURED to INITIALIZED).
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
Gaudi::Property< std::string > m_jobOptionsPreAction
Gaudi::Property< std::vector< std::string > > m_svcMapping
Gaudi::Property< std::vector< std::string > > m_dllNameList
GAUDI_API bool isEnvSet(const char *var)
Check if an environment variable is set or not.
Definition: System.cpp:433
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
implementation of IInterface::queryInterface
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void*)
The Application Manager class.
Gaudi::Property< bool > m_actHistory
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:62
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
StatusCode decodeExtSvcNameList()
T find(T...args)
GAUDI_API const std::string & hostName()
Host name.
Definition: System.cpp:337
Gaudi::Property< bool > m_extSvcCreates
SmartIF< DLLClassManager > m_classManager
Reference to the class manager.
Gaudi::Property< std::string > m_jobOptionsSvcType
StatusCode start() override
Gaudi::Property< std::vector< std::string > > m_createSvcNameList
StatusCode restart() override
StatusCode configure() override
T begin(T...args)
virtual StatusCode restart()=0
Initialization (from RUNNING to RUNNING, via INITIALIZED).
StatusCode stopRun() override
implementation of IEventProcessor::stopRun()
const std::string & type() const
StatusCode decodeCreateSvcNameList()
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:165
virtual StatusCode finalize()=0
Finalize (from INITIALIZED to CONFIGURED).
Gaudi::Property< std::string > m_jobOptionsPostAction
T c_str(T...args)
StatusCode i_startup()
Internal startup routine.
StatusCode stop() override
std::string m_name
Name.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
static GAUDI_API void disableChecking()
Definition: StatusCode.cpp:42
Gaudi::Property< std::string > m_messageSvcType
#define ON_VERBOSE
StatusCode reinitialize() override
MSG::Level level() const
Retrieve output level.
Definition: MsgStream.h:108
Gaudi::StateMachine::State m_state
Internal State.
Gaudi::Property< std::string > m_appName
Gaudi::StateMachine::State FSMState() const override
const std::string & name() const
SmartIF< ISvcLocator > & serviceLocator() const override
Needed to locate the message service.
virtual StatusCode executeRun(int maxevt)=0
Process the maxevt events as a Run.
int maxevt
Definition: Bootstrap.cpp:276
constexpr int Success
Definition: AppReturnCode.h:18
StatusCode run() override
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:20
SmartIF< IAlgManager > & algManager()
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:287
SmartIF< IMessageSvc > m_messageSvc
Reference to the message service.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
Gaudi::Property< std::string > m_jobOptionsPath
virtual void setOutputLevel(int new_level)=0
Set new global output level threshold.
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:260
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
T rbegin(T...args)