The Gaudi Framework  v32r2 (46d42edc)
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 #include <sstream>
34 
35 #define ON_DEBUG if ( UNLIKELY( m_outputLevel <= MSG::DEBUG ) )
36 #define ON_VERBOSE if ( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) )
37 
39 
40 // Implementation class for the Application Manager. In this way the
41 // ApplicationMgr class is a fully insulated concrete class. Clients
42 // (main programs) will not need to re-compile if there are changes
43 // in the implementation
44 
45 //=======================================================================
46 // Constructor
47 //=======================================================================
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  if ( !ppvi ) { return StatusCode::FAILURE; }
87 
88  // try to find own/direct interfaces:
89  StatusCode sc = base_class::queryInterface( iid, ppvi );
90  if ( sc.isSuccess() ) return sc;
91 
92  // find indirect interfaces :
93  if ( ISvcLocator::interfaceID().versionMatch( iid ) ) { return serviceLocator()->queryInterface( iid, ppvi ); }
94  if ( ISvcManager::interfaceID().versionMatch( iid ) ) { return svcManager()->queryInterface( iid, ppvi ); }
95  if ( IAlgManager::interfaceID().versionMatch( iid ) ) { return algManager()->queryInterface( iid, ppvi ); }
96  if ( IClassManager::interfaceID().versionMatch( iid ) ) { return m_classManager->queryInterface( iid, ppvi ); }
97  if ( IMessageSvc::interfaceID().versionMatch( iid ) ) {
98  *ppvi = m_messageSvc.get();
100  // Note that 0 can be a valid IMessageSvc pointer value (when used for
101  // MsgStream).
102  return StatusCode::SUCCESS;
103  }
104  *ppvi = nullptr;
105  return StatusCode::FAILURE;
106 }
107 
108 //============================================================================
109 // ApplicationMgr::i_startup()
110 //============================================================================
112 
113  StatusCode sc;
114 
115  // declare factories in current module
117 
118  // Note: we cannot use CommonMessaging methods here because MessageSvc is not there yet
119  MsgStream log( nullptr, name() );
120 
121  // Create the Message service
122  auto msgsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "MessageSvc", m_messageSvcType ) );
123  if ( !msgsvc ) {
124  log << MSG::FATAL << "Error creating MessageSvc of type " << m_messageSvcType << endmsg;
125  return StatusCode::FAILURE;
126  }
127  // Get the useful interface from Message services
128  m_messageSvc = m_svcLocator->service( "MessageSvc" );
129  if ( !m_messageSvc ) {
130  log << MSG::FATAL << "Error retrieving MessageSvc." << endmsg;
131  return StatusCode::FAILURE;
132  }
133 
134  auto jobsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "JobOptionsSvc", m_jobOptionsSvcType ) );
135  // Create the Job Options service
136  if ( !jobsvc ) {
137  log << MSG::FATAL << "Error creating JobOptionsSvc" << endmsg;
138  return StatusCode::FAILURE;
139  }
140  // Get the useful interface from Message services
141  m_jobOptionsSvc = m_svcLocator->service( "JobOptionsSvc" );
142  if ( !m_jobOptionsSvc ) {
143  log << MSG::FATAL << "Error retrieving JobOptionsSvc." << endmsg;
144  return StatusCode::FAILURE;
145  }
146 
147  auto jobOptsIProp = jobsvc.as<IProperty>();
148  if ( !jobOptsIProp ) {
149  log << MSG::FATAL << "Error locating JobOptionsSvc" << endmsg;
150  return StatusCode::FAILURE;
151  }
152  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "TYPE", m_jobOptionsType ) );
153  if ( !sc.isSuccess() ) {
154  log << MSG::FATAL << "Error setting TYPE option in JobOptionsSvc" << endmsg;
155  return sc;
156  }
157 
158  if ( !m_jobOptionsPreAction.empty() ) {
159  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONPARAMS", m_jobOptionsPreAction ) );
160  if ( !sc.isSuccess() ) {
161  log << MSG::FATAL << "Error setting JobOptionsPreAction option in JobOptionsSvc" << endmsg;
162  return sc;
163  }
164  }
165 
166  if ( !m_jobOptionsPostAction.empty() ) {
167  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONACTION", m_jobOptionsPostAction ) );
168  if ( !sc.isSuccess() ) {
169  log << MSG::FATAL << "Error setting JobOptionsPostAction option in JobOptionsSvc" << endmsg;
170  return sc;
171  }
172  }
173 
174  if ( !m_jobOptionsPath.empty() ) { // The command line takes precedence
175  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", m_jobOptionsPath ) );
176  if ( !sc.isSuccess() ) {
177  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc" << endmsg;
178  return sc;
179  }
180  } else if ( isEnvSet( "JOBOPTPATH" ) ) { // Otherwise the Environment JOBOPTPATH
181  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", getEnv( "JOBOPTPATH" ) ) );
182  if ( !sc.isSuccess() ) {
183  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc from env" << endmsg;
184  return sc;
185  }
186  } else { // Otherwise the default
187  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", "../options/job.opts" ) );
188  if ( !sc.isSuccess() ) {
189  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc to default" << endmsg;
190  return sc;
191  }
192  }
193  jobOptsIProp.reset();
194 
195  // Sets my default the Output Level of the Message service to be
196  // the same as this
197  auto msgSvcIProp = msgsvc.as<IProperty>();
198  msgSvcIProp->setProperty( Gaudi::Property<int>( "OutputLevel", m_outputLevel ) ).ignore();
199  msgSvcIProp.reset();
200 
201  sc = jobsvc->sysInitialize();
202  if ( !sc.isSuccess() ) {
203  log << MSG::FATAL << "Error initializing JobOptionsSvc" << endmsg;
204  return sc;
205  }
206  sc = msgsvc->sysInitialize();
207  if ( !sc.isSuccess() ) {
208  log << MSG::FATAL << "Error initializing MessageSvc" << endmsg;
209  return sc;
210  }
211 
212  // Make sure output level caches are up to date.
214 
215  return sc;
216 }
217 
218 //============================================================================
219 // IAppMgrUI implementation: ApplicationMgr::configure()
220 //============================================================================
222 
223  // Check if the state is compatible with the transition
224  MsgStream tlog( m_messageSvc, name() );
226  tlog << MSG::INFO << "Already Configured" << endmsg;
227  return StatusCode::SUCCESS;
228  }
230  tlog << MSG::FATAL << "configure: Invalid state \"" << m_state << "\"" << endmsg;
231  return StatusCode::FAILURE;
232  }
234 
235  // Reset application return code.
237 
238  StatusCode sc;
239  sc = i_startup();
240  if ( !sc.isSuccess() ) { return sc; }
241 
242  {
244  // Get my own options using the Job options service
245  if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
246  sc = m_jobOptionsSvc->setMyProperties( name(), this );
247  if ( !sc.isSuccess() ) {
248  log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
249  return sc;
250  }
251  }
252 
253  // Make sure that the OutputLevel is in sync
256 
257  // Check current outputLevel to eventually inform the MessageSvc
258  if ( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
259  // Print a welcome message
261  << "=================================================================="
262  << "==================================================================" << std::endl
263  << " "
264  << " Welcome to " << m_appName.value();
265 
266  if ( !m_appVersion.empty() ) {
267  log << MSG::ALWAYS << " version " << m_appVersion.value();
268  } else {
269  log << MSG::ALWAYS << " (GaudiCoreSvc "
270  << "v" << GAUDICORESVC_MAJOR_VERSION << "r" << GAUDICORESVC_MINOR_VERSION
271 #if GAUDICORESVC_PATCH_VERSION
272  << "p" << GAUDICORESVC_PATCH_VERSION
273 #endif
274  << ")";
275  }
276 
277  // Add the host name and current time to the message
279  << " "
280  << " running on " << System::hostName() << " on " << Gaudi::Time::current().format( true ) << std::endl
281  << "=================================================================="
282  << "==================================================================" << endmsg;
283  }
284 
285  // print all own properties if the options "PropertiesPrint" is set to true
286  if ( m_propertiesPrint ) {
287  const auto& properties = getProperties();
288  log << MSG::ALWAYS << "List of ALL properties of " << System::typeinfoName( typeid( *this ) ) << "/" << this->name()
289  << " #properties = " << properties.size() << endmsg;
290  for ( const auto& property : properties ) { log << "Property ['Name': Value] = " << *property << endmsg; }
291  }
292 
293  // Check if StatusCode need to be checked
294  if ( m_codeCheck ) {
296  sc = svcManager()->addService( "StatusCodeSvc", -9999 );
297  if ( sc.isFailure() ) {
298  log << MSG::FATAL << "Error adding StatusCodeSvc" << endmsg;
299  return StatusCode::FAILURE;
300  } else {
301  ON_VERBOSE
302  log << MSG::VERBOSE << "added service StatusCodeSvc" << endmsg;
303  }
304  } else {
306  }
307 
308  // set the requested environment variables
309  for ( auto& var : m_environment ) {
310  const std::string& name = var.first;
311  const std::string& value = var.second;
313  const MSG::Level lvl = ( !old.empty() && ( old != "UNKNOWN" ) ) ? MSG::WARNING : MSG::DEBUG;
314  if ( UNLIKELY( m_outputLevel <= lvl ) ) log << lvl << "Setting " << name << " = " << value << endmsg;
315  System::setEnv( name, value );
316  }
317 
318  // Declare Service Types
319  for ( auto& j : m_svcMapping ) {
321  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
322  log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
323  return StatusCode::FAILURE;
324  } else {
325  ON_VERBOSE
326  log << MSG::VERBOSE << "declared service " << j << endmsg;
327  }
328  }
329  for ( auto& j : m_svcOptMapping ) {
331  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
332  log << MSG::ERROR << "declaring svc type:'" << j << "' failed." << endmsg;
333  return StatusCode::FAILURE;
334  }
335  }
336 
337  //--------------------------------------------------------------------------
338  // Declare other Services and Algorithms by loading DLL's
339  sc = decodeDllNameList();
340  if ( sc.isFailure() ) {
341  log << MSG::ERROR << "Failure loading declared DLL's" << endmsg;
342  return sc;
343  }
344 
345  //--------------------------------------------------------------------------
346  // Deal with the services explicitly declared by the user.
347  sc = decodeExtSvcNameList();
348  if ( sc.isFailure() ) {
349  log << MSG::ERROR << "Failure during external service association" << endmsg;
350  return sc;
351  }
352 
354  if ( sc.isFailure() ) {
355  log << MSG::ERROR << "Failure during external service creation" << endmsg;
356  return sc;
357  }
358 
359  //--------------------------------------------------------------------------
360  // Retrieve intrinsic services. If needed configure them.
361  //--------------------------------------------------------------------------
362  const Gaudi::Utils::TypeNameString evtloop_item( m_eventLoopMgr );
363  sc = svcManager()->addService( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
364  if ( !sc.isSuccess() ) {
365  log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endmsg;
366  return sc;
367  } else {
368  ON_VERBOSE
369  log << MSG::VERBOSE << "added service " << evtloop_item << endmsg;
370  }
371 
373  if ( !m_runable ) {
374  log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
375  << m_runableType.name() << endmsg;
376  return sc;
377  }
378  m_processingMgr = m_svcLocator->service( evtloop_item );
379  if ( !m_processingMgr ) {
380  log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
381  << "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
382  return sc;
383  }
384  // The IEventProcessor might also be an IQueueingEventProcessor
386 
387  // Establish Update Handlers for ExtSvc and DLLs Properties
388  m_extSvcNameList.declareUpdateHandler( &ApplicationMgr::extSvcNameListHandler, this );
389  m_createSvcNameList.declareUpdateHandler( &ApplicationMgr::createSvcNameListHandler, this );
390  m_dllNameList.declareUpdateHandler( &ApplicationMgr::dllNameListHandler, this );
391 
392  if ( m_actHistory ) {
393  // Create HistorySvc with a priority to ensure it's initialized last, finalized first
394  sc = svcManager()->addService( "HistorySvc", std::numeric_limits<int>::max() );
395  if ( sc.isFailure() ) {
396  log << MSG::FATAL << "Error adding HistorySvc" << endmsg;
397  return StatusCode::FAILURE;
398  }
399  }
400 
401  log << MSG::INFO << "Application Manager Configured successfully" << endmsg;
403  return StatusCode::SUCCESS;
404 }
405 
406 //============================================================================
407 // IAppMgrUI implementation: ApplicationMgr::initialize()
408 //============================================================================
410  StatusCode sc;
411 
413 
414  // Make sure output level caches are up to date.
416 
417  // I cannot add these services in configure() because they are coming from GaudiUtils
418  // and it messes up genconf when rebuilding it.
419  if ( m_stopOnSignal ) {
420  // Instantiate the service that schedules a stop when a signal is received
421  std::string svcname( "Gaudi::Utils::StopSignalHandler" );
422  sc = svcManager()->addService( svcname );
423  if ( sc.isFailure() ) {
424  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
425  }
426  }
427 
428  if ( m_stalledEventMonitoring ) {
429  // Instantiate the service that schedules a stop when a signal is received
430  std::string svcname( "StalledEventMonitor" );
431  sc = svcManager()->addService( svcname );
432  if ( sc.isFailure() ) {
433  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
434  }
435  }
436 
438  log << MSG::INFO << "Already Initialized!" << endmsg;
439  return StatusCode::SUCCESS;
440  }
442  log << MSG::FATAL << "initialize: Invalid state \"" << m_state << "\"" << endmsg;
443  return StatusCode::FAILURE;
444  }
446 
447  //--------------------------------------------------------------------------
448  // Initialize the list of top Services
449  //--------------------------------------------------------------------------
450  sc = svcManager()->initialize();
451  if ( !sc.isSuccess() ) return sc;
452 
453  sc = algManager()->initialize();
454  if ( !sc.isSuccess() ) return sc;
455 
456  //--------------------------------------------------------------------------
457  // Final steps: Inform user and change internal state
458  //--------------------------------------------------------------------------
459  log << MSG::INFO << "Application Manager Initialized successfully" << endmsg;
461 
463 
464  return sc;
465 }
466 
467 //============================================================================
468 // IAppMgrUI implementation: ApplicationMgr::start()
469 //============================================================================
471 
473  StatusCode sc;
474 
476  log << MSG::INFO << "Already Initialized!" << endmsg;
477  return StatusCode::SUCCESS;
478  }
480  log << MSG::FATAL << "start: Invalid state \"" << m_state << "\"" << endmsg;
481  return StatusCode::FAILURE;
482  }
484 
485  //--------------------------------------------------------------------------
486  // Initialize the list of top Services
487  //--------------------------------------------------------------------------
488  sc = m_jobOptionsSvc.as<IService>()->sysStart();
489  if ( !sc.isSuccess() ) return sc;
490 
491  sc = m_messageSvc.as<IService>()->sysStart();
492  if ( !sc.isSuccess() ) return sc;
493 
494  sc = svcManager()->start();
495  if ( !sc.isSuccess() ) return sc;
496 
497  sc = algManager()->start();
498  if ( !sc.isSuccess() ) return sc;
499 
500  //--------------------------------------------------------------------------
501  // Final steps: Inform user and change internal state
502  //--------------------------------------------------------------------------
503  log << MSG::INFO << "Application Manager Started successfully" << endmsg;
505 
506  return sc;
507 }
508 
509 //============================================================================
510 // IAppMgrUI implementation: ApplicationMgr::nextEvent(int)
511 //============================================================================
515  log << MSG::FATAL << "nextEvent: Invalid state \"" << m_state << "\"" << endmsg;
516  return StatusCode::FAILURE;
517  }
518  if ( !m_processingMgr ) {
520  log << MSG::FATAL << "No event processing manager specified. Check option: " << m_eventLoopMgr.name() << endmsg;
521  return StatusCode::FAILURE;
522  }
523  return m_processingMgr->nextEvent( maxevt );
524 }
525 
526 //============================================================================
527 // IAppMgrUI implementation: ApplicationMgr::stop()
528 //============================================================================
530 
532  StatusCode sc;
533 
535  log << MSG::INFO << "Already Initialized!" << endmsg;
536  return StatusCode::SUCCESS;
537  }
539  log << MSG::FATAL << "stop: Invalid state \"" << m_state << "\"" << endmsg;
540  return StatusCode::FAILURE;
541  }
543 
544  // Stop independently managed Algorithms
545  sc = algManager()->stop();
546  if ( !sc.isSuccess() ) return sc;
547 
548  //--------------------------------------------------------------------------
549  // Stop the list of top Services
550  //--------------------------------------------------------------------------
551  sc = svcManager()->stop();
552  if ( !sc.isSuccess() ) return sc;
553 
554  sc = m_messageSvc.as<IService>()->sysStop();
555  if ( !sc.isSuccess() ) return sc;
556 
557  sc = m_jobOptionsSvc.as<IService>()->sysStop();
558  if ( !sc.isSuccess() ) return sc;
559 
560  //--------------------------------------------------------------------------
561  // Final steps: Inform user and change internal state
562  //--------------------------------------------------------------------------
563  log << MSG::INFO << "Application Manager Stopped successfully" << endmsg;
565 
566  return sc;
567 }
568 
569 //============================================================================
570 // IAppMgrUI implementation: ApplicationMgr::finalize()
571 //============================================================================
575  log << MSG::INFO << "Already Finalized" << endmsg;
576  return StatusCode::SUCCESS;
577  }
579  log << MSG::FATAL << "finalize: Invalid state \"" << m_state << "\"" << endmsg;
580  return StatusCode::FAILURE;
581  }
583 
584  // disable message suppression in finalize
585  m_svcLocator->service<IProperty>( "MessageSvc" )
586  ->setProperty( Gaudi::Property<bool>( "enableSuppression", false ) )
587  .ignore();
588 
589  // Finalize independently managed Algorithms
590  StatusCode sc = algManager()->finalize();
591  if ( sc.isFailure() ) {
592  log << MSG::WARNING << "Failed to finalize an algorithm." << endmsg;
594  }
595 
596  // Finalize all Services
597  sc = svcManager()->finalize();
598  if ( sc.isFailure() ) {
599  log << MSG::WARNING << "Failed to finalize a service." << endmsg;
601  }
602 
603  // svcManager()->removeService( (IService*) m_processingMgr.get() );
604  // svcManager()->removeService( (IService*) m_runable.get() );
605 
607 
608  if ( sc.isSuccess() ) {
609  log << MSG::INFO << "Application Manager Finalized successfully" << endmsg;
610  } else {
611  log << MSG::ERROR << "Application Manager failed to finalize" << endmsg;
612  }
613 
615  return sc;
616 }
617 
618 //============================================================================
619 // IAppMgrUI implementation: ApplicationMgr::terminate()
620 //============================================================================
623 
625  log << MSG::INFO << "Already Offline" << endmsg;
626  return StatusCode::SUCCESS;
627  }
629  log << MSG::FATAL << "terminate: Invalid state \"" << m_state << "\"" << endmsg;
630  return StatusCode::FAILURE;
631  }
632  // release all Services
634 
635  if ( m_returnCode.value() == Gaudi::ReturnCode::Success ) {
636  log << MSG::INFO << "Application Manager Terminated successfully" << endmsg;
637  } else if ( m_returnCode.value() == Gaudi::ReturnCode::ScheduledStop ) {
638  log << MSG::INFO << "Application Manager Terminated successfully with a user requested ScheduledStop" << endmsg;
639  } else {
640  log << MSG::ERROR << "Application Manager Terminated with error code " << m_returnCode.value() << endmsg;
641  }
642 
643  { // Force a disable the auditing of finalize for MessageSvc
644  auto prop = m_messageSvc.as<IProperty>();
645  if ( prop ) { prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore(); }
646  }
647  { // Force a disable the auditing of finalize for JobOptionsSvc
648  auto prop = m_jobOptionsSvc.as<IProperty>();
649  if ( prop ) { prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore(); }
650  }
651 
652  // finalize MessageSvc
653  auto svc = m_messageSvc.as<IService>();
654  if ( !svc ) {
655  log << MSG::ERROR << "Could not get the IService interface of the MessageSvc" << endmsg;
656  } else {
657  svc->sysFinalize().ignore();
658  }
659 
660  // finalize JobOptionsSvc
661  svc = m_jobOptionsSvc.as<IService>();
662  if ( !svc ) {
663  log << MSG::ERROR << "Could not get the IService interface of the JobOptionsSvc" << endmsg;
664  } else {
665  svc->sysFinalize().ignore();
666  }
667 
669  return StatusCode::SUCCESS;
670 }
671 
672 //============================================================================
673 // Reach the required state going through all the needed transitions
674 //============================================================================
677 
678  switch ( state ) {
679 
681  switch ( m_state ) {
683  return StatusCode::SUCCESS;
684  break;
686  return terminate();
687  break;
688  default: // Gaudi::StateMachine::INITIALIZED or Gaudi::StateMachine::RUNNING
690  if ( sc.isSuccess() ) { return terminate(); }
691  break;
692  }
693  break;
694 
696  switch ( m_state ) {
698  return StatusCode::SUCCESS;
699  break;
701  return configure();
702  break;
704  return finalize();
705  break;
706  default: // Gaudi::StateMachine::RUNNING
708  if ( sc.isSuccess() ) { return finalize(); }
709  break;
710  }
711  break;
712 
714  switch ( m_state ) {
716  return StatusCode::SUCCESS;
717  break;
719  return initialize();
720  break;
722  return stop();
723  break;
724  default: // Gaudi::StateMachine::OFFLINE
726  if ( sc.isSuccess() ) { return initialize(); }
727  break;
728  }
729  break;
730 
732  switch ( m_state ) {
734  return StatusCode::SUCCESS;
735  break;
737  return start();
738  break;
739  default: // Gaudi::StateMachine::OFFLINE or Gaudi::StateMachine::CONFIGURED
741  if ( sc.isSuccess() ) { return start(); }
742  break;
743  }
744  break;
745  }
746 
747  // If I get here, there has been a problem in the recursion
748 
749  if ( ignoreFailures ) {
750  // force the new state
751  m_state = state;
752  return StatusCode::SUCCESS;
753  }
754 
755  return sc;
756 }
757 
758 //============================================================================
759 // IAppMgrUI implementation: ApplicationMgr::run()
760 //============================================================================
763 
765  if ( sc.isSuccess() ) {
767  if ( m_runable != 0 ) { // loop over the events
768  sc = m_runable->run();
769  if ( !sc.isSuccess() ) { log << MSG::FATAL << "Application execution failed. Ending the job." << endmsg; }
770  } else {
771  log << MSG::FATAL << "Application has no runable object. Check option:" << m_runableType.name() << endmsg;
772  }
773  }
774  if ( sc.isSuccess() ) { // try to close cleanly
776  }
777  // either the runable failed of the stut-down
778  if ( sc.isFailure() ) { // try to close anyway (but keep the StatusCode unchanged)
780  }
781  return sc;
782 }
783 
784 //============================================================================
785 // IEventProcessor implementation: executeEvent(EventContext&&)
786 //============================================================================
789  if ( m_processingMgr ) { return m_processingMgr->executeEvent( std::move( ctx ) ); }
790  }
792  log << MSG::FATAL << "executeEvent: Invalid state \"" << FSMState() << "\"" << endmsg;
793  return StatusCode::FAILURE;
794 }
795 
798  std::move( ctx ) );
799 }
800 
801 bool ApplicationMgr::empty() const {
803 }
804 
805 std::optional<Gaudi::Interfaces::IQueueingEventProcessor::ResultType> ApplicationMgr::pop() {
807 }
808 
812  }
814  ss << "createEventContext: Invalid state \"" << FSMState() << '"';
815  throw GaudiException( ss.str(), name(), StatusCode::FAILURE );
816 }
817 //============================================================================
818 // IEventProcessor implementation: executeRun(int)
819 //============================================================================
823  if ( m_processingMgr ) { return m_processingMgr->executeRun( evtmax ); }
824  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
825  return StatusCode::SUCCESS;
826  }
827  log << MSG::FATAL << "executeRun: Invalid state \"" << FSMState() << "\"" << endmsg;
828  return StatusCode::FAILURE;
829 }
830 
831 //============================================================================
832 // IEventProcessor implementation: stopRun(int)
833 //============================================================================
837  if ( m_processingMgr ) { return m_processingMgr->stopRun(); }
838  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
839  return StatusCode::SUCCESS;
840  }
841  log << MSG::FATAL << "stopRun: Invalid state \"" << FSMState() << "\"" << endmsg;
842  return StatusCode::FAILURE;
843 }
844 // Implementation of IAppMgrUI::name
845 const std::string& ApplicationMgr::name() const { return m_name; }
846 
847 // implementation of IService::state
849 // implementation of IService::state
851 
852 //============================================================================
853 // implementation of IService::reinitilaize
854 //============================================================================
858  StatusCode sc;
860  throw GaudiException( "Cannot reinitialize application if not INITIALIZED or RUNNING",
861  "ApplicationMgr::reinitialize", StatusCode::FAILURE );
862  }
864  sc = svcManager()->reinitialize();
865  if ( sc.isFailure() ) retval = sc;
866  sc = algManager()->reinitialize();
867  if ( sc.isFailure() ) retval = sc;
868 
870  if ( sc.isFailure() ) retval = sc;
872  if ( sc.isFailure() ) retval = sc;
873 
874  log << MSG::INFO << "Application Manager Reinitialized successfully" << endmsg;
875 
876  return retval;
877 }
878 
879 //============================================================================
880 // implementation of IService::reinitiaize
881 //============================================================================
884  StatusCode sc;
886  throw GaudiException( "Cannot restart application if not RUNNING", "ApplicationMgr::restart", StatusCode::FAILURE );
887  }
888 
889  sc = svcManager()->restart();
890  if ( sc.isFailure() ) retval = sc;
891  sc = algManager()->restart();
892  if ( sc.isFailure() ) retval = sc;
893 
894  sc = m_messageSvc.as<IService>()->sysRestart();
895  if ( sc.isFailure() ) retval = sc;
897  if ( sc.isFailure() ) retval = sc;
898 
899  return retval;
900 }
901 
902 //============================================================================
903 // Handle properties of the event loop manager (Top alg/Output stream list)
904 //============================================================================
906  if ( m_processingMgr ) {
907  auto props = m_processingMgr.as<IProperty>();
908  if ( props ) props->setProperty( p ).ignore();
909  }
910 }
911 
912 //============================================================================
913 // External Service List handler
914 //============================================================================
916  if ( !( decodeCreateSvcNameList() ).isSuccess() ) {
917  throw GaudiException( "Failed to create ext services", "MinimalEventLoopMgr::createSvcNameListHandler",
919  }
920 }
921 //============================================================================
922 // decodeCreateSvcNameList
923 //============================================================================
926  const auto& theNames = m_createSvcNameList.value();
927  auto it = theNames.begin();
928  auto et = theNames.end();
929  while ( result.isSuccess() && it != et ) {
930  Gaudi::Utils::TypeNameString item( *it++ );
931  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
933  log << MSG::ERROR << "decodeCreateSvcNameList: Cannot create service " << item.type() << "/" << item.name()
934  << endmsg;
935  } else {
936  ON_DEBUG {
938  log << MSG::DEBUG << "decodeCreateSvcNameList: Created service " << item.type() << "/" << item.name() << endmsg;
939  }
940  }
941  }
942  return result;
943 }
944 
945 //============================================================================
946 // External Service List handler
947 //============================================================================
949  if ( !( decodeExtSvcNameList() ).isSuccess() ) {
950  throw GaudiException( "Failed to declare ext services", "MinimalEventLoopMgr::extSvcNameListHandler",
952  }
953 }
954 
955 //============================================================================
956 // decodeExtSvcNameList
957 //============================================================================
960 
961  const auto& theNames = m_extSvcNameList.value();
962 
963  auto it = theNames.begin();
964  auto et = theNames.end();
965  while ( result.isSuccess() && it != et ) {
966  Gaudi::Utils::TypeNameString item( *it++ );
967  if ( m_extSvcCreates ) {
968  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
970  log << MSG::ERROR << "decodeExtSvcNameList: Cannot create service " << item.type() << "/" << item.name()
971  << endmsg;
972  }
973  } else {
974  if ( ( result = svcManager()->declareSvcType( item.name(), item.type() ) ).isFailure() ) {
976  log << MSG::ERROR << "decodeExtSvcNameList: Cannot declare service " << item.type() << "/" << item.name()
977  << endmsg;
978  }
979  }
980  }
981  return result;
982 }
983 
984 //============================================================================
985 // Dll List handler
986 //============================================================================
988  if ( !( decodeDllNameList() ).isSuccess() ) {
989  throw GaudiException( "Failed to load DLLs.", "MinimalEventLoopMgr::dllNameListHandler", StatusCode::FAILURE );
990  }
991 }
992 
993 //============================================================================
994 // decodeDllNameList
995 //============================================================================
997 
1000 
1001  // Clean up multiple entries from DLL list
1002  // -------------------------------------------------------------------------
1003  std::vector<std::string> newList;
1004  std::map<std::string, unsigned int> dllInList, duplicateList;
1005  {
1006  for ( const auto it : m_dllNameList ) {
1007  if ( 0 == dllInList[it] ) {
1008  newList.push_back( it ); // first instance of this module
1009  } else {
1010  ++duplicateList[it];
1011  } // module listed multiple times
1012  ++dllInList[it]; // increment count for this module
1013  }
1014  }
1015  // m_dllNameList = newList; // update primary list to new, filtered list (do not use the
1016  // property itself otherwise we get called again infinitely)
1017  // List modules that were in there twice..
1018  ON_DEBUG if ( !duplicateList.empty() ) {
1019  log << MSG::DEBUG << "Removed duplicate entries for modules : ";
1020  for ( auto it = duplicateList.begin(); it != duplicateList.end(); ++it ) {
1021  log << it->first << "(" << 1 + it->second << ")";
1022  if ( it != --duplicateList.end() ) log << ", ";
1023  }
1024  log << endmsg;
1025  }
1026  // -------------------------------------------------------------------------
1027 
1028  const std::vector<std::string>& theNames = newList;
1029 
1030  // only load the new dlls or previously failed dlls
1031  ON_DEBUG log << MSG::DEBUG << "Loading declared DLL's" << endmsg;
1032 
1033  std::vector<std::string> successNames, failNames;
1034  for ( const auto& it : theNames ) {
1035  if ( std::find( m_okDlls.rbegin(), m_okDlls.rend(), it ) == m_okDlls.rend() ) {
1036  // found a new module name
1037  StatusCode status = m_classManager->loadModule( it );
1038  if ( status.isFailure() ) {
1039  failNames.push_back( it );
1040  result = StatusCode::FAILURE;
1041  } else {
1042  successNames.push_back( it );
1043  }
1044  }
1045  }
1046 
1047  // report back to the user and store the names of the succesfully loaded dlls
1048  if ( !successNames.empty() ) {
1049  log << MSG::INFO << "Successfully loaded modules : ";
1050  for ( auto it = successNames.begin(); it != successNames.end(); it++ ) {
1051  log << ( *it );
1052  if ( ( it + 1 ) != successNames.end() ) log << ", ";
1053  // save name
1054  m_okDlls.push_back( *it );
1055  }
1056  log << endmsg;
1057  }
1058 
1059  if ( result == StatusCode::FAILURE ) {
1060  log << MSG::WARNING << "Failed to load modules: ";
1061  for ( auto it = failNames.begin(); it != failNames.end(); it++ ) {
1062  log << ( *it );
1063  if ( ( it + 1 ) != failNames.end() ) log << ", ";
1064  }
1065  log << endmsg;
1066  }
1067  return result;
1068 }
1069 
1071  resetMessaging();
1072  for ( auto& mgrItem : m_managers ) { mgrItem.second->outputLevelUpdate(); }
1073 }
1074 
1075 namespace {
1077  void printAlgsSequencesHelper( SmartIF<IAlgManager>& algmgr, const std::string& algname, MsgStream& log,
1078  int indent ) {
1080  log << MSG::ALWAYS;
1081  for ( int i = 0; i < indent; ++i ) log << " ";
1082  log << algname << endmsg;
1083  auto prop = algmgr->algorithm<IProperty>( algname, false );
1084  if ( prop ) {
1085  // Try to get the property Members
1086  Gaudi::Property<std::vector<std::string>> p( "Members", {} );
1087  if ( prop->getProperty( &p ).isSuccess() ) {
1088  for ( auto& subalgname : p.value() ) { printAlgsSequencesHelper( algmgr, subalgname, log, indent + 1 ); }
1089  }
1090  } else {
1091  log << MSG::WARNING << "Cannot get properties of " << algname << endmsg;
1092  }
1093  }
1094 } // namespace
1095 
1098  log << MSG::ALWAYS << "****************************** Algorithm Sequence ****************************" << endmsg;
1099  for ( auto& algname : m_topAlgNameList ) { printAlgsSequencesHelper( algManager(), algname, log, 0 ); }
1100  log << MSG::ALWAYS << "******************************************************************************" << endmsg;
1101 }
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:369
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:32
virtual SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
#define UNLIKELY(x)
Definition: Kernel.h:96
virtual StatusCode addService(IService *svc, int prio=DEFAULT_SVC_PRIORITY)=0
Add a service to the "active" list of services of the factory.
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< bool > m_printAlgsSequence
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:482
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:352
bool empty() const override
virtual StatusCode executeEvent(EventContext &&ctx)=0
Process single event.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
T rend(T... args)
ManagersMap m_managers
Map of known component managers.
StatusCode sysStart() override
Gaudi::Property< std::string > m_jobOptionsType
T endl(T... args)
static Time current()
Returns the current time.
Definition: Time.cpp:109
Gaudi::Property< std::map< std::string, std::string > > m_environment
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:107
void outputLevelUpdate() override
Function to call to update the outputLevel of the components (after a change in MessageSvc).
const std::string & type() const
Gaudi::Property< std::string > m_appVersion
T end(T... args)
static GAUDI_API void enableChecking()
Definition: StatusCode.cpp:42
std::vector< std::string > m_okDlls
names of successfully loaded dlls
StatusCode sysRestart() override
State
Allowed states for classes implementing the state machine (ApplicationMgr, Algorithm,...
Definition: StateMachine.h:12
void push(EventContext &&ctx) override
StatusCode nextEvent(int maxevt) override
SmartIF< IJobOptionsSvc > m_jobOptionsSvc
Reference to JobOption service.
AlgTypeAliasesMap & typeAliases()
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
This class represents an entry point to all the event specific data.
Definition: EventContext.h:24
void createSvcNameListHandler(Gaudi::Details::PropertyBase &)
static auto i_delegateToEvtProc(SELF *self, PIMPL &member, std::string_view method_name, METHOD &&method, ARGS &&... args)
Helper to delegate calls to event processor implementation.
SmartIF< IEventProcessor > m_processingMgr
Reference to processing manager object.
StatusCode terminate() override
virtual bool empty() const =0
Tell if the processor has events in the queues.
SmartIF< ISvcManager > & svcManager()
virtual StatusCode start()=0
Start (from INITIALIZED to RUNNING).
constexpr int ScheduledStop
Definition: AppReturnCode.h:25
Gaudi::Property< std::string > m_eventLoopMgr
STL class.
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:55
StatusCode sysReinitialize() override
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:76
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
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).
Gaudi::Property< std::vector< std::string > > m_topAlgNameList
virtual StatusCode reinitialize()=0
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
void extSvcNameListHandler(Gaudi::Details::PropertyBase &theProp)
General service interface definition.
Definition: IService.h:18
std::optional< Gaudi::Interfaces::IQueueingEventProcessor::ResultType > pop() override
const std::string & name() const
#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:50
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.
Definition of the basic interface.
Definition: IInterface.h:244
virtual StatusCode setMyProperties(const std::string &client, IProperty *me)=0
Override default properties of the calling client.
virtual std::optional< ResultType > pop()=0
Get the next available result.
EventContext createEventContext() override
implementation of IEventProcessor::createEventContext()
Gaudi::Property< std::vector< std::string > > m_extSvcNameList
#define DECLARE_OBJECT_FACTORY(x)
Definition: ObjectFactory.h:15
void dllNameListHandler(Gaudi::Details::PropertyBase &theProp)
StatusCode executeEvent(EventContext &&ctx) override
implementation of IEventProcessor::executeEvent(void*)
Gaudi::Property< std::string > m_runableType
StatusCode sysStop() override
SmartIF< ISvcLocator > & serviceLocator() const override
Needed to locate the message service.
T str(T... args)
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:32
StatusCode GoToState(Gaudi::StateMachine::State state, bool ignoreFailures=false)
Reach a state from current state (whichever it is) going through the correct transitions.
bool isSuccess() const
Definition: StatusCode.h:267
StatusCode finalize() override
Gaudi::Property< std::vector< std::string > > m_svcOptMapping
virtual StatusCode initialize()=0
Initialization (from CONFIGURED to INITIALIZED).
T move(T... args)
virtual EventContext createEventContext()=0
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:389
StatusCode queryInterface(const InterfaceID &iid, void **pinterface) override
implementation of IInterface::queryInterface
The Application Manager class.
virtual void push(EventContext &&ctx)=0
Schedule the processing of an event.
Gaudi::Property< bool > m_actHistory
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:303
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:153
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:252
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()
StatusCode decodeCreateSvcNameList()
void printAlgsSequences()
Print the sequence of algorithms that have been loaded.
virtual StatusCode finalize()=0
Finalize (from INITIALIZED to CONFIGURED).
Gaudi::Property< std::string > m_jobOptionsPostAction
T c_str(T... args)
constexpr static const auto FAILURE
Definition: StatusCode.h:86
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:44
Gaudi::Property< std::string > m_messageSvcType
#define ON_VERBOSE
StatusCode reinitialize() override
Gaudi::StateMachine::State m_state
Internal State.
Gaudi::StateMachine::State FSMState() const override
bool isFailure() const
Definition: StatusCode.h:130
Gaudi::Property< std::string > m_appName
virtual StatusCode executeRun(int maxevt)=0
Process the maxevt events as a Run.
int maxevt
Definition: Bootstrap.cpp:260
constexpr int Success
Definition: AppReturnCode.h:16
StatusCode run() 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()
SmartIF< IQueueingEventProcessor > m_queueingProcessor
Reference to a queueing processing manager object.
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:253
const std::string & name() const override
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:192
Gaudi::Property< std::string > m_jobOptionsPath
virtual void setOutputLevel(int new_level)=0
Set new global output level threshold.
Gaudi::StateMachine::State targetFSMState() const override
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)