The Gaudi Framework  v33r1 (b1225454)
ApplicationMgr.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // Include files
12 #include "ApplicationMgr.h"
13 
14 #include "AlgorithmManager.h"
15 #include "DLLClassManager.h"
16 #include "ServiceManager.h"
17 
20 #include "GaudiKernel/IRunable.h"
21 #include "GaudiKernel/IService.h"
23 
24 #include "GaudiKernel/MsgStream.h"
26 #include "GaudiKernel/SmartIF.h"
27 
29 
30 #include "GaudiKernel/StatusCode.h"
31 #include "GaudiKernel/System.h"
32 #include "GaudiKernel/Time.h"
33 
34 #include "GaudiCoreSvcVersion.h"
35 
36 using System::getEnv;
37 using System::isEnvSet;
38 
39 #include <algorithm>
40 #include <cassert>
41 #include <ctime>
42 #include <limits>
43 #include <sstream>
44 
45 #define ON_DEBUG if ( UNLIKELY( m_outputLevel <= MSG::DEBUG ) )
46 #define ON_VERBOSE if ( UNLIKELY( m_outputLevel <= MSG::VERBOSE ) )
47 
49 
50 // Implementation class for the Application Manager. In this way the
51 // ApplicationMgr class is a fully insulated concrete class. Clients
52 // (main programs) will not need to re-compile if there are changes
53 // in the implementation
54 
55 //=======================================================================
56 // Constructor
57 //=======================================================================
59  // IInterface initialization
60  addRef(); // Initial count set to 1
61 
62  // Instantiate component managers
63  m_managers[IService::interfaceID().id()] = new ServiceManager( this );
64 
65  m_svcLocator = svcManager();
66 
67  // Instantiate internal services
68  // SvcLocator/Factory HAS to be already instantiated
69  m_classManager = new DLLClassManager( this );
70 
71  AlgorithmManager* algMgr = new AlgorithmManager( this );
72  m_managers[IAlgorithm::interfaceID().id()] = algMgr;
73  // m_managers[IAlgorithm::interfaceID().id()] = new HiveAlgorithmManager(this);
74 
75  // This property is not hosted in the ApplicationMgr instance
76  declareProperty( "AlgTypeAliases", algMgr->typeAliases(),
77  "Aliases of algorithm types, to replace an algorithm type for every instance" );
78 
79  // ServiceMgr Initialization loop checking
80  svcManager()->setLoopCheckEnabled( m_loopCheck );
81 
82  m_svcMapping = {"EvtDataSvc/EventDataSvc",
83  "DetDataSvc/DetectorDataSvc",
84  "HistogramSvc/HistogramDataSvc",
85  "HbookCnv::PersSvc/HbookHistSvc",
86  "RootHistCnv::PersSvc/RootHistSvc",
87  "EvtPersistencySvc/EventPersistencySvc",
88  "DetPersistencySvc/DetectorPersistencySvc",
89  "HistogramPersistencySvc/HistogramPersistencySvc"};
90 }
91 
92 //============================================================================
93 // IInterface implementation: queryInterface::addRef()
94 //============================================================================
96  if ( !ppvi ) { return StatusCode::FAILURE; }
97 
98  // try to find own/direct interfaces:
99  StatusCode sc = base_class::queryInterface( iid, ppvi );
100  if ( sc.isSuccess() ) return sc;
101 
102  // find indirect interfaces :
103  if ( ISvcLocator::interfaceID().versionMatch( iid ) ) { return serviceLocator()->queryInterface( iid, ppvi ); }
104  if ( ISvcManager::interfaceID().versionMatch( iid ) ) { return svcManager()->queryInterface( iid, ppvi ); }
105  if ( IAlgManager::interfaceID().versionMatch( iid ) ) { return algManager()->queryInterface( iid, ppvi ); }
106  if ( IClassManager::interfaceID().versionMatch( iid ) ) { return m_classManager->queryInterface( iid, ppvi ); }
107  if ( IMessageSvc::interfaceID().versionMatch( iid ) ) {
108  *ppvi = m_messageSvc.get();
109  if ( m_messageSvc ) m_messageSvc->addRef();
110  // Note that 0 can be a valid IMessageSvc pointer value (when used for
111  // MsgStream).
112  return StatusCode::SUCCESS;
113  }
114  *ppvi = nullptr;
115  return StatusCode::FAILURE;
116 }
117 
118 //============================================================================
119 // ApplicationMgr::i_startup()
120 //============================================================================
122 
123  StatusCode sc;
124 
125  // declare factories in current module
127 
128  // Note: we cannot use CommonMessaging methods here because MessageSvc is not there yet
129  MsgStream log( nullptr, name() );
130 
131  // Create the Message service
132  auto msgsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "MessageSvc", m_messageSvcType ) );
133  if ( !msgsvc ) {
134  log << MSG::FATAL << "Error creating MessageSvc of type " << m_messageSvcType << endmsg;
135  return StatusCode::FAILURE;
136  }
137  // Get the useful interface from Message services
138  m_messageSvc = m_svcLocator->service( "MessageSvc" );
139  if ( !m_messageSvc ) {
140  log << MSG::FATAL << "Error retrieving MessageSvc." << endmsg;
141  return StatusCode::FAILURE;
142  }
143 
144  auto jobsvc = svcManager()->createService( Gaudi::Utils::TypeNameString( "JobOptionsSvc", m_jobOptionsSvcType ) );
145  // Create the Job Options service
146  if ( !jobsvc ) {
147  log << MSG::FATAL << "Error creating JobOptionsSvc" << endmsg;
148  return StatusCode::FAILURE;
149  }
150  // Get the useful interface from Message services
151  m_jobOptionsSvc = m_svcLocator->service( "JobOptionsSvc" );
152  if ( !m_jobOptionsSvc ) {
153  log << MSG::FATAL << "Error retrieving JobOptionsSvc." << endmsg;
154  return StatusCode::FAILURE;
155  }
156 
157  auto jobOptsIProp = jobsvc.as<IProperty>();
158  if ( !jobOptsIProp ) {
159  log << MSG::FATAL << "Error locating JobOptionsSvc" << endmsg;
160  return StatusCode::FAILURE;
161  }
162  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "TYPE", m_jobOptionsType ) );
163  if ( !sc.isSuccess() ) {
164  log << MSG::FATAL << "Error setting TYPE option in JobOptionsSvc" << endmsg;
165  return sc;
166  }
167 
168  if ( !m_jobOptionsPreAction.empty() ) {
169  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONPARAMS", m_jobOptionsPreAction ) );
170  if ( !sc.isSuccess() ) {
171  log << MSG::FATAL << "Error setting JobOptionsPreAction option in JobOptionsSvc" << endmsg;
172  return sc;
173  }
174  }
175 
176  if ( !m_jobOptionsPostAction.empty() ) {
177  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PYTHONACTION", m_jobOptionsPostAction ) );
178  if ( !sc.isSuccess() ) {
179  log << MSG::FATAL << "Error setting JobOptionsPostAction option in JobOptionsSvc" << endmsg;
180  return sc;
181  }
182  }
183 
184  if ( !m_jobOptionsPath.empty() ) { // The command line takes precedence
185  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", m_jobOptionsPath ) );
186  if ( !sc.isSuccess() ) {
187  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc" << endmsg;
188  return sc;
189  }
190  } else if ( isEnvSet( "JOBOPTPATH" ) ) { // Otherwise the Environment JOBOPTPATH
191  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", getEnv( "JOBOPTPATH" ) ) );
192  if ( !sc.isSuccess() ) {
193  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc from env" << endmsg;
194  return sc;
195  }
196  } else { // Otherwise the default
197  sc = jobOptsIProp->setProperty( Gaudi::Property<std::string>( "PATH", "../options/job.opts" ) );
198  if ( !sc.isSuccess() ) {
199  log << MSG::FATAL << "Error setting PATH option in JobOptionsSvc to default" << endmsg;
200  return sc;
201  }
202  }
203  jobOptsIProp.reset();
204 
205  // Sets my default the Output Level of the Message service to be
206  // the same as this
207  auto msgSvcIProp = msgsvc.as<IProperty>();
208  msgSvcIProp->setProperty( Gaudi::Property<int>( "OutputLevel", m_outputLevel ) ).ignore();
209  msgSvcIProp.reset();
210 
211  sc = jobsvc->sysInitialize();
212  if ( !sc.isSuccess() ) {
213  log << MSG::FATAL << "Error initializing JobOptionsSvc" << endmsg;
214  return sc;
215  }
216  sc = msgsvc->sysInitialize();
217  if ( !sc.isSuccess() ) {
218  log << MSG::FATAL << "Error initializing MessageSvc" << endmsg;
219  return sc;
220  }
221 
222  // Make sure output level caches are up to date.
224 
225  return sc;
226 }
227 
228 //============================================================================
229 // IAppMgrUI implementation: ApplicationMgr::configure()
230 //============================================================================
232 
233  // Check if the state is compatible with the transition
234  MsgStream tlog( m_messageSvc, name() );
236  tlog << MSG::INFO << "Already Configured" << endmsg;
237  return StatusCode::SUCCESS;
238  }
240  tlog << MSG::FATAL << "configure: Invalid state \"" << m_state << "\"" << endmsg;
241  return StatusCode::FAILURE;
242  }
244 
245  // Reset application return code.
247 
248  StatusCode sc;
249  sc = i_startup();
250  if ( !sc.isSuccess() ) { return sc; }
251 
252  {
254  // Get my own options using the Job options service
255  if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
256  sc = m_jobOptionsSvc->setMyProperties( name(), this );
257  if ( !sc.isSuccess() ) {
258  log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
259  return sc;
260  }
261  }
262 
263  // Make sure that the OutputLevel is in sync
266 
267  // Check current outputLevel to eventually inform the MessageSvc
268  if ( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
269  // Print a welcome message
271  << "=================================================================="
272  << "==================================================================" << std::endl
273  << " "
274  << " Welcome to " << m_appName.value();
275 
276  if ( !m_appVersion.empty() ) {
277  log << MSG::ALWAYS << " version " << m_appVersion.value();
278  } else {
279  log << MSG::ALWAYS << " (GaudiCoreSvc "
280  << "v" << GAUDICORESVC_MAJOR_VERSION << "r" << GAUDICORESVC_MINOR_VERSION
281 #if GAUDICORESVC_PATCH_VERSION
282  << "p" << GAUDICORESVC_PATCH_VERSION
283 #endif
284  << ")";
285  }
286 
287  // Add the host name and current time to the message
289  << " "
290  << " running on " << System::hostName() << " on " << Gaudi::Time::current().format( true ) << std::endl
291  << "=================================================================="
292  << "==================================================================" << endmsg;
293  }
294 
295  // print all own properties if the options "PropertiesPrint" is set to true
296  if ( m_propertiesPrint ) {
297  const auto& properties = getProperties();
298  log << MSG::ALWAYS << "List of ALL properties of " << System::typeinfoName( typeid( *this ) ) << "/" << this->name()
299  << " #properties = " << properties.size() << endmsg;
300  for ( const auto& property : properties ) { log << "Property ['Name': Value] = " << *property << endmsg; }
301  }
302 
303  // Check if StatusCode need to be checked
304  if ( m_codeCheck ) {
306  sc = svcManager()->addService( "StatusCodeSvc", -9999 );
307  if ( sc.isFailure() ) {
308  log << MSG::FATAL << "Error adding StatusCodeSvc" << endmsg;
309  return StatusCode::FAILURE;
310  } else {
311  ON_VERBOSE
312  log << MSG::VERBOSE << "added service StatusCodeSvc" << endmsg;
313  }
314  } else {
316  }
317 
318  // set the requested environment variables
319  for ( auto& var : m_environment ) {
320  const std::string& name = var.first;
321  const std::string& value = var.second;
323  const MSG::Level lvl = ( !old.empty() && ( old != "UNKNOWN" ) ) ? MSG::WARNING : MSG::DEBUG;
324  if ( UNLIKELY( m_outputLevel <= lvl ) ) log << lvl << "Setting " << name << " = " << value << endmsg;
325  System::setEnv( name, value );
326  }
327 
328  // Declare Service Types
329  for ( auto& j : m_svcMapping ) {
331  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
332  log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
333  return StatusCode::FAILURE;
334  } else {
335  ON_VERBOSE
336  log << MSG::VERBOSE << "declared service " << j << endmsg;
337  }
338  }
339  for ( auto& j : m_svcOptMapping ) {
341  if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
342  log << MSG::ERROR << "declaring svc type:'" << j << "' failed." << endmsg;
343  return StatusCode::FAILURE;
344  }
345  }
346 
347  //--------------------------------------------------------------------------
348  // Declare other Services and Algorithms by loading DLL's
349  sc = decodeDllNameList();
350  if ( sc.isFailure() ) {
351  log << MSG::ERROR << "Failure loading declared DLL's" << endmsg;
352  return sc;
353  }
354 
355  //--------------------------------------------------------------------------
356  // Deal with the services explicitly declared by the user.
357  sc = decodeExtSvcNameList();
358  if ( sc.isFailure() ) {
359  log << MSG::ERROR << "Failure during external service association" << endmsg;
360  return sc;
361  }
362 
364  if ( sc.isFailure() ) {
365  log << MSG::ERROR << "Failure during external service creation" << endmsg;
366  return sc;
367  }
368 
369  //--------------------------------------------------------------------------
370  // Retrieve intrinsic services. If needed configure them.
371  //--------------------------------------------------------------------------
372  const Gaudi::Utils::TypeNameString evtloop_item( m_eventLoopMgr );
373  sc = svcManager()->addService( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
374  if ( !sc.isSuccess() ) {
375  log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endmsg;
376  return sc;
377  } else {
378  ON_VERBOSE
379  log << MSG::VERBOSE << "added service " << evtloop_item << endmsg;
380  }
381 
383  if ( !m_runable ) {
384  log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
385  << m_runableType.name() << endmsg;
386  return sc;
387  }
388  m_processingMgr = m_svcLocator->service( evtloop_item );
389  if ( !m_processingMgr ) {
390  log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
391  << "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
392  return sc;
393  }
394  // The IEventProcessor might also be an IQueueingEventProcessor
396 
397  // Establish Update Handlers for ExtSvc and DLLs Properties
398  m_extSvcNameList.declareUpdateHandler( &ApplicationMgr::extSvcNameListHandler, this );
399  m_createSvcNameList.declareUpdateHandler( &ApplicationMgr::createSvcNameListHandler, this );
400  m_dllNameList.declareUpdateHandler( &ApplicationMgr::dllNameListHandler, this );
401 
402  if ( m_actHistory ) {
403  // Create HistorySvc with a priority to ensure it's initialized last, finalized first
404  sc = svcManager()->addService( "HistorySvc", std::numeric_limits<int>::max() );
405  if ( sc.isFailure() ) {
406  log << MSG::FATAL << "Error adding HistorySvc" << endmsg;
407  return StatusCode::FAILURE;
408  }
409  }
410 
411  log << MSG::INFO << "Application Manager Configured successfully" << endmsg;
413  return StatusCode::SUCCESS;
414 }
415 
416 //============================================================================
417 // IAppMgrUI implementation: ApplicationMgr::initialize()
418 //============================================================================
420  StatusCode sc;
421 
423 
424  // Make sure output level caches are up to date.
426 
427  // I cannot add these services in configure() because they are coming from GaudiUtils
428  // and it messes up genconf when rebuilding it.
429  if ( m_stopOnSignal ) {
430  // Instantiate the service that schedules a stop when a signal is received
431  std::string svcname( "Gaudi::Utils::StopSignalHandler" );
432  sc = svcManager()->addService( svcname );
433  if ( sc.isFailure() ) {
434  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
435  }
436  }
437 
438  if ( m_stalledEventMonitoring ) {
439  // Instantiate the service that schedules a stop when a signal is received
440  std::string svcname( "StalledEventMonitor" );
441  sc = svcManager()->addService( svcname );
442  if ( sc.isFailure() ) {
443  log << MSG::INFO << "Cannot instantiate " << svcname << "signals will be ignored" << endmsg;
444  }
445  }
446 
448  log << MSG::INFO << "Already Initialized!" << endmsg;
449  return StatusCode::SUCCESS;
450  }
452  log << MSG::FATAL << "initialize: Invalid state \"" << m_state << "\"" << endmsg;
453  return StatusCode::FAILURE;
454  }
456 
457  //--------------------------------------------------------------------------
458  // Initialize the list of top Services
459  //--------------------------------------------------------------------------
460  sc = svcManager()->initialize();
461  if ( !sc.isSuccess() ) return sc;
462 
463  sc = algManager()->initialize();
464  if ( !sc.isSuccess() ) return sc;
465 
466  //--------------------------------------------------------------------------
467  // Final steps: Inform user and change internal state
468  //--------------------------------------------------------------------------
469  log << MSG::INFO << "Application Manager Initialized successfully" << endmsg;
471 
473 
474  return sc;
475 }
476 
477 //============================================================================
478 // IAppMgrUI implementation: ApplicationMgr::start()
479 //============================================================================
481 
483  StatusCode sc;
484 
486  log << MSG::INFO << "Already Initialized!" << endmsg;
487  return StatusCode::SUCCESS;
488  }
490  log << MSG::FATAL << "start: Invalid state \"" << m_state << "\"" << endmsg;
491  return StatusCode::FAILURE;
492  }
494 
495  //--------------------------------------------------------------------------
496  // Initialize the list of top Services
497  //--------------------------------------------------------------------------
498  sc = m_jobOptionsSvc.as<IService>()->sysStart();
499  if ( !sc.isSuccess() ) return sc;
500 
501  sc = m_messageSvc.as<IService>()->sysStart();
502  if ( !sc.isSuccess() ) return sc;
503 
504  sc = svcManager()->start();
505  if ( !sc.isSuccess() ) return sc;
506 
507  sc = algManager()->start();
508  if ( !sc.isSuccess() ) return sc;
509 
510  //--------------------------------------------------------------------------
511  // Final steps: Inform user and change internal state
512  //--------------------------------------------------------------------------
513  log << MSG::INFO << "Application Manager Started successfully" << endmsg;
515 
516  return sc;
517 }
518 
519 //============================================================================
520 // IAppMgrUI implementation: ApplicationMgr::nextEvent(int)
521 //============================================================================
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 
542  StatusCode sc;
543 
545  log << MSG::INFO << "Already Initialized!" << endmsg;
546  return StatusCode::SUCCESS;
547  }
549  log << MSG::FATAL << "stop: Invalid state \"" << m_state << "\"" << endmsg;
550  return StatusCode::FAILURE;
551  }
553 
554  // Stop independently managed Algorithms
555  sc = algManager()->stop();
556  if ( !sc.isSuccess() ) return sc;
557 
558  //--------------------------------------------------------------------------
559  // Stop the list of top Services
560  //--------------------------------------------------------------------------
561  sc = svcManager()->stop();
562  if ( !sc.isSuccess() ) return sc;
563 
564  sc = m_messageSvc.as<IService>()->sysStop();
565  if ( !sc.isSuccess() ) return sc;
566 
567  sc = m_jobOptionsSvc.as<IService>()->sysStop();
568  if ( !sc.isSuccess() ) return sc;
569 
570  //--------------------------------------------------------------------------
571  // Final steps: Inform user and change internal state
572  //--------------------------------------------------------------------------
573  log << MSG::INFO << "Application Manager Stopped successfully" << endmsg;
575 
576  return sc;
577 }
578 
579 //============================================================================
580 // IAppMgrUI implementation: ApplicationMgr::finalize()
581 //============================================================================
585  log << MSG::INFO << "Already Finalized" << endmsg;
586  return StatusCode::SUCCESS;
587  }
589  log << MSG::FATAL << "finalize: Invalid state \"" << m_state << "\"" << endmsg;
590  return StatusCode::FAILURE;
591  }
593 
594  // disable message suppression in finalize
595  m_svcLocator->service<IProperty>( "MessageSvc" )
596  ->setProperty( Gaudi::Property<bool>( "enableSuppression", false ) )
597  .ignore();
598 
599  // Finalize independently managed Algorithms
600  StatusCode sc = algManager()->finalize();
601  if ( sc.isFailure() ) {
602  log << MSG::WARNING << "Failed to finalize an algorithm." << endmsg;
604  }
605 
606  // Finalize all Services
607  sc = svcManager()->finalize();
608  if ( sc.isFailure() ) {
609  log << MSG::WARNING << "Failed to finalize a service." << endmsg;
611  }
612 
613  // svcManager()->removeService( (IService*) m_processingMgr.get() );
614  // svcManager()->removeService( (IService*) m_runable.get() );
615 
617 
618  if ( sc.isSuccess() ) {
619  log << MSG::INFO << "Application Manager Finalized successfully" << endmsg;
620  } else {
621  log << MSG::ERROR << "Application Manager failed to finalize" << endmsg;
622  }
623 
625  return sc;
626 }
627 
628 //============================================================================
629 // IAppMgrUI implementation: ApplicationMgr::terminate()
630 //============================================================================
633 
635  log << MSG::INFO << "Already Offline" << endmsg;
636  return StatusCode::SUCCESS;
637  }
639  log << MSG::FATAL << "terminate: Invalid state \"" << m_state << "\"" << endmsg;
640  return StatusCode::FAILURE;
641  }
642  // release all Services
644 
645  if ( m_returnCode.value() == Gaudi::ReturnCode::Success ) {
646  log << MSG::INFO << "Application Manager Terminated successfully" << endmsg;
647  } else if ( m_returnCode.value() == Gaudi::ReturnCode::ScheduledStop ) {
648  log << MSG::INFO << "Application Manager Terminated successfully with a user requested ScheduledStop" << endmsg;
649  } else {
650  log << MSG::ERROR << "Application Manager Terminated with error code " << m_returnCode.value() << endmsg;
651  }
652 
653  { // Force a disable the auditing of finalize for MessageSvc
654  auto prop = m_messageSvc.as<IProperty>();
655  if ( prop ) { prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore(); }
656  }
657  { // Force a disable the auditing of finalize for JobOptionsSvc
658  auto prop = m_jobOptionsSvc.as<IProperty>();
659  if ( prop ) { prop->setProperty( Gaudi::Property<bool>( "AuditFinalize", false ) ).ignore(); }
660  }
661 
662  // finalize MessageSvc
663  auto svc = m_messageSvc.as<IService>();
664  if ( !svc ) {
665  log << MSG::ERROR << "Could not get the IService interface of the MessageSvc" << endmsg;
666  } else {
667  svc->sysFinalize().ignore();
668  }
669 
670  // finalize JobOptionsSvc
671  svc = m_jobOptionsSvc.as<IService>();
672  if ( !svc ) {
673  log << MSG::ERROR << "Could not get the IService interface of the JobOptionsSvc" << endmsg;
674  } else {
675  svc->sysFinalize().ignore();
676  }
677 
679  return StatusCode::SUCCESS;
680 }
681 
682 //============================================================================
683 // Reach the required state going through all the needed transitions
684 //============================================================================
687 
688  switch ( state ) {
689 
691  switch ( m_state ) {
693  return StatusCode::SUCCESS;
694  break;
696  return terminate();
697  break;
698  default: // Gaudi::StateMachine::INITIALIZED or Gaudi::StateMachine::RUNNING
700  if ( sc.isSuccess() ) { return terminate(); }
701  break;
702  }
703  break;
704 
706  switch ( m_state ) {
708  return StatusCode::SUCCESS;
709  break;
711  return configure();
712  break;
714  return finalize();
715  break;
716  default: // Gaudi::StateMachine::RUNNING
718  if ( sc.isSuccess() ) { return finalize(); }
719  break;
720  }
721  break;
722 
724  switch ( m_state ) {
726  return StatusCode::SUCCESS;
727  break;
729  return initialize();
730  break;
732  return stop();
733  break;
734  default: // Gaudi::StateMachine::OFFLINE
736  if ( sc.isSuccess() ) { return initialize(); }
737  break;
738  }
739  break;
740 
742  switch ( m_state ) {
744  return StatusCode::SUCCESS;
745  break;
747  return start();
748  break;
749  default: // Gaudi::StateMachine::OFFLINE or Gaudi::StateMachine::CONFIGURED
751  if ( sc.isSuccess() ) { return start(); }
752  break;
753  }
754  break;
755  }
756 
757  // If I get here, there has been a problem in the recursion
758 
759  if ( ignoreFailures ) {
760  // force the new state
761  m_state = state;
762  return StatusCode::SUCCESS;
763  }
764 
765  return sc;
766 }
767 
768 //============================================================================
769 // IAppMgrUI implementation: ApplicationMgr::run()
770 //============================================================================
773 
775  if ( sc.isSuccess() ) {
777  if ( m_runable != 0 ) { // loop over the events
778  sc = m_runable->run();
779  if ( !sc.isSuccess() ) { log << MSG::FATAL << "Application execution failed. Ending the job." << endmsg; }
780  } else {
781  log << MSG::FATAL << "Application has no runable object. Check option:" << m_runableType.name() << endmsg;
782  }
783  }
784  if ( sc.isSuccess() ) { // try to close cleanly
786  }
787  // either the runable failed of the stut-down
788  if ( sc.isFailure() ) { // try to close anyway (but keep the StatusCode unchanged)
790  }
791  return sc;
792 }
793 
794 //============================================================================
795 // IEventProcessor implementation: executeEvent(EventContext&&)
796 //============================================================================
799  if ( m_processingMgr ) { return m_processingMgr->executeEvent( std::move( ctx ) ); }
800  }
802  log << MSG::FATAL << "executeEvent: Invalid state \"" << FSMState() << "\"" << endmsg;
803  return StatusCode::FAILURE;
804 }
805 
808  std::move( ctx ) );
809 }
810 
811 bool ApplicationMgr::empty() const {
813 }
814 
815 std::optional<Gaudi::Interfaces::IQueueingEventProcessor::ResultType> ApplicationMgr::pop() {
817 }
818 
822  }
824  ss << "createEventContext: Invalid state \"" << FSMState() << '"';
825  throw GaudiException( ss.str(), name(), StatusCode::FAILURE );
826 }
827 //============================================================================
828 // IEventProcessor implementation: executeRun(int)
829 //============================================================================
833  if ( m_processingMgr ) { return m_processingMgr->executeRun( evtmax ); }
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 //============================================================================
847  if ( m_processingMgr ) { return m_processingMgr->stopRun(); }
848  log << MSG::WARNING << "No EventLoop Manager specified " << endmsg;
849  return StatusCode::SUCCESS;
850  }
851  log << MSG::FATAL << "stopRun: Invalid state \"" << FSMState() << "\"" << endmsg;
852  return StatusCode::FAILURE;
853 }
854 // Implementation of IAppMgrUI::name
855 const std::string& ApplicationMgr::name() const { return m_name; }
856 
857 // implementation of IService::state
859 // implementation of IService::state
861 
862 //============================================================================
863 // implementation of IService::reinitilaize
864 //============================================================================
868  StatusCode sc;
870  throw GaudiException( "Cannot reinitialize application if not INITIALIZED or RUNNING",
871  "ApplicationMgr::reinitialize", StatusCode::FAILURE );
872  }
874  sc = svcManager()->reinitialize();
875  if ( sc.isFailure() ) retval = sc;
876  sc = algManager()->reinitialize();
877  if ( sc.isFailure() ) retval = sc;
878 
880  if ( sc.isFailure() ) retval = sc;
882  if ( sc.isFailure() ) retval = sc;
883 
884  log << MSG::INFO << "Application Manager Reinitialized successfully" << endmsg;
885 
886  return retval;
887 }
888 
889 //============================================================================
890 // implementation of IService::reinitiaize
891 //============================================================================
894  StatusCode sc;
896  throw GaudiException( "Cannot restart application if not RUNNING", "ApplicationMgr::restart", StatusCode::FAILURE );
897  }
898 
899  sc = svcManager()->restart();
900  if ( sc.isFailure() ) retval = sc;
901  sc = algManager()->restart();
902  if ( sc.isFailure() ) retval = sc;
903 
904  sc = m_messageSvc.as<IService>()->sysRestart();
905  if ( sc.isFailure() ) retval = sc;
907  if ( sc.isFailure() ) retval = sc;
908 
909  return retval;
910 }
911 
912 //============================================================================
913 // Handle properties of the event loop manager (Top alg/Output stream list)
914 //============================================================================
916  if ( m_processingMgr ) {
917  auto props = m_processingMgr.as<IProperty>();
918  if ( props ) props->setProperty( p ).ignore();
919  }
920 }
921 
922 //============================================================================
923 // External Service List handler
924 //============================================================================
926  if ( !( decodeCreateSvcNameList() ).isSuccess() ) {
927  throw GaudiException( "Failed to create ext services", "MinimalEventLoopMgr::createSvcNameListHandler",
929  }
930 }
931 //============================================================================
932 // decodeCreateSvcNameList
933 //============================================================================
936  const auto& theNames = m_createSvcNameList.value();
937  auto it = theNames.begin();
938  auto et = theNames.end();
939  while ( result.isSuccess() && it != et ) {
940  Gaudi::Utils::TypeNameString item( *it++ );
941  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
943  log << MSG::ERROR << "decodeCreateSvcNameList: Cannot create service " << item.type() << "/" << item.name()
944  << endmsg;
945  } else {
946  ON_DEBUG {
948  log << MSG::DEBUG << "decodeCreateSvcNameList: Created service " << item.type() << "/" << item.name() << endmsg;
949  }
950  }
951  }
952  return result;
953 }
954 
955 //============================================================================
956 // External Service List handler
957 //============================================================================
959  if ( !( decodeExtSvcNameList() ).isSuccess() ) {
960  throw GaudiException( "Failed to declare ext services", "MinimalEventLoopMgr::extSvcNameListHandler",
962  }
963 }
964 
965 //============================================================================
966 // decodeExtSvcNameList
967 //============================================================================
970 
971  const auto& theNames = m_extSvcNameList.value();
972 
973  auto it = theNames.begin();
974  auto et = theNames.end();
975  while ( result.isSuccess() && it != et ) {
976  Gaudi::Utils::TypeNameString item( *it++ );
977  if ( m_extSvcCreates ) {
978  if ( ( result = svcManager()->addService( item, ServiceManager::DEFAULT_SVC_PRIORITY ) ).isFailure() ) {
980  log << MSG::ERROR << "decodeExtSvcNameList: Cannot create service " << item.type() << "/" << item.name()
981  << endmsg;
982  }
983  } else {
984  if ( ( result = svcManager()->declareSvcType( item.name(), item.type() ) ).isFailure() ) {
986  log << MSG::ERROR << "decodeExtSvcNameList: Cannot declare service " << item.type() << "/" << item.name()
987  << endmsg;
988  }
989  }
990  }
991  return result;
992 }
993 
994 //============================================================================
995 // Dll List handler
996 //============================================================================
998  if ( !( decodeDllNameList() ).isSuccess() ) {
999  throw GaudiException( "Failed to load DLLs.", "MinimalEventLoopMgr::dllNameListHandler", StatusCode::FAILURE );
1000  }
1001 }
1002 
1003 //============================================================================
1004 // decodeDllNameList
1005 //============================================================================
1007 
1010 
1011  // Clean up multiple entries from DLL list
1012  // -------------------------------------------------------------------------
1013  std::vector<std::string> newList;
1014  std::map<std::string, unsigned int> dllInList, duplicateList;
1015  {
1016  for ( const auto it : m_dllNameList ) {
1017  if ( 0 == dllInList[it] ) {
1018  newList.push_back( it ); // first instance of this module
1019  } else {
1020  ++duplicateList[it];
1021  } // module listed multiple times
1022  ++dllInList[it]; // increment count for this module
1023  }
1024  }
1025  // m_dllNameList = newList; // update primary list to new, filtered list (do not use the
1026  // property itself otherwise we get called again infinitely)
1027  // List modules that were in there twice..
1028  ON_DEBUG if ( !duplicateList.empty() ) {
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  resetMessaging();
1082  for ( auto& mgrItem : m_managers ) { mgrItem.second->outputLevelUpdate(); }
1083 }
1084 
1085 namespace {
1087  void printAlgsSequencesHelper( SmartIF<IAlgManager>& algmgr, const std::string& algname, MsgStream& log,
1088  int indent ) {
1090  log << MSG::ALWAYS;
1091  for ( int i = 0; i < indent; ++i ) log << " ";
1092  log << algname << endmsg;
1093  auto prop = algmgr->algorithm<IProperty>( algname, false );
1094  if ( prop ) {
1095  // Try to get the property Members
1096  Gaudi::Property<std::vector<std::string>> p( "Members", {} );
1097  if ( prop->getProperty( &p ).isSuccess() ) {
1098  for ( auto& subalgname : p.value() ) { printAlgsSequencesHelper( algmgr, subalgname, log, indent + 1 ); }
1099  }
1100  } else {
1101  log << MSG::WARNING << "Cannot get properties of " << algname << endmsg;
1102  }
1103  }
1104 } // namespace
1105 
1108  log << MSG::ALWAYS << "****************************** Algorithm Sequence ****************************" << endmsg;
1109  for ( auto& algname : m_topAlgNameList ) { printAlgsSequencesHelper( algManager(), algname, log, 0 ); }
1110  log << MSG::ALWAYS << "******************************************************************************" << endmsg;
1111 }
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:379
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:42
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:106
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:34
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:492
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:370
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:308
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:119
Gaudi::Property< std::map< std::string, std::string > > m_environment
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:117
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:53
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:22
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:86
This class represents an entry point to all the event specific data.
Definition: EventContext.h:34
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:35
Gaudi::Property< std::string > m_eventLoopMgr
STL class.
constexpr bool versionMatch(const InterfaceID &iid) const
check compatibility.
Definition: IInterface.h:65
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:86
T push_back(T... args)
Interface ID class.
Definition: IInterface.h:39
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:28
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:61
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:254
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:25
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:42
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:365
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:399
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:313
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:168
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:262
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:101
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:55
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:145
Gaudi::Property< std::string > m_appName
virtual StatusCode executeRun(int maxevt)=0
Process the maxevt events as a Run.
int maxevt
Definition: Bootstrap.cpp:270
constexpr int Success
Definition: AppReturnCode.h:26
StatusCode run() override
The IProperty is the basic interface for all components which have properties that can be set or get.
Definition: IProperty.h:30
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:263
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:202
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)