The Gaudi Framework  master (9f3f8895)
Loading...
Searching...
No Matches
Gaudi::EventWatchdogAlg Class Reference

Add to the transient store a tracker that detects events that are taking too long. More...

Inheritance diagram for Gaudi::EventWatchdogAlg:
Collaboration diagram for Gaudi::EventWatchdogAlg:

Public Member Functions

 EventWatchdogAlg (const std::string &name, ISvcLocator *pSvcLocator)
PeriodicAction operator() (EventContext const &ctx) const override

Private Attributes

Gaudi::CheckedProperty< unsigned int > m_eventTimeout
Gaudi::Property< bool > m_abortOnTimeout
Gaudi::Property< bool > m_stackTrace { this, "StackTrace", false, "Whether to print the stack-trace on timeout." }

Detailed Description

Add to the transient store a tracker that detects events that are taking too long.

Definition at line 46 of file EventWatchdogAlg.cpp.

Constructor & Destructor Documentation

◆ EventWatchdogAlg()

Gaudi::EventWatchdogAlg::EventWatchdogAlg ( const std::string & name,
ISvcLocator * pSvcLocator )
inline

Definition at line 48 of file EventWatchdogAlg.cpp.

49 : Transformer( name, pSvcLocator, KeyValue{ "TimerLocation", std::format( ".{}-timer", sanitize( name ) ) } ) {
50 // timeout period cannot be smaller than 1
51 m_eventTimeout.verifier().setLower( 1 );
52 }
Gaudi::CheckedProperty< unsigned int > m_eventTimeout
details::Transformer< Signature, Traits_, details::isLegacy< Traits_ > > Transformer

Member Function Documentation

◆ operator()()

PeriodicAction Gaudi::EventWatchdogAlg::operator() ( EventContext const & ctx) const
inlineoverride

Definition at line 54 of file EventWatchdogAlg.cpp.

54 {
55 using namespace std::chrono_literals;
56 // we use a functor because we cannot pass mutable states to a lambda
57 struct Action {
58 MsgStream log;
59 const bool doStackTrace;
60 const bool abortOnTimeout;
61 const unsigned int timeout;
62 const EventContext ctx;
63
64 const std::vector<IScheduler*> schedulers;
65
66 int counter{ 0 };
67
68 const std::chrono::steady_clock::time_point eventStart{ std::chrono::steady_clock::now() };
69
70 void operator()() {
71 ++counter;
72 if ( counter == 1 ) {
73 log << MSG::WARNING << std::format( "More than {}s since the beginning of the event ({})", timeout, ctx )
74 << endmsg;
75 } else {
76 log << MSG::WARNING << std::format( "Another {}s passed since last timeout ({})", timeout, ctx ) << endmsg;
77 }
78 if ( log.level() <= MSG::INFO ) {
79 log << MSG::INFO
80 << std::format( "Current memory usage is virtual size = {} MB, resident set size = {} MB",
81 System::virtualMemory() / 1024., System::pagedMemory() / 1024. )
82 << endmsg;
83 }
84
85 std::scoped_lock protectReport( s_watchdogReportMutex );
86 if ( doStackTrace ) {
87 for ( auto scheduler : schedulers ) { scheduler->dumpState(); }
88 if ( gSystem ) {
89 // TSystem::StackTrace() prints on the standard error, so we do the same
90 std::cerr << std::format( "=== Stalled event: current stack trace ({}) ===\n", ctx );
91 gSystem->StackTrace();
92 }
93 }
94 if ( abortOnTimeout ) {
95 log << MSG::FATAL << std::format( "too much time on a single event ({}): aborting process", ctx ) << endmsg;
96 std::raise( SIGQUIT );
97 }
98 }
99
100 ~Action() {
101 if ( counter ) {
102 const std::chrono::duration<float, std::chrono::seconds::period> duration =
103 std::chrono::steady_clock::now() - eventStart;
104 log << MSG::INFO << std::format( "An event ({}) took {:.3f}s", ctx, duration.count() ) << endmsg;
105 }
106 }
107 };
108
109 std::vector<IScheduler*> schedulers;
110 if ( m_stackTrace ) {
111 // if we ask for the stack trace we are also interested in the state of the scheduler
112 std::ranges::copy( svcLoc()->getServices() |
113 std::views::transform( []( auto svc ) { return Gaudi::Cast<IScheduler>( svc ); } ) |
114 std::views::filter( []( auto* p ) { return p != nullptr; } ),
115 std::back_inserter( schedulers ) );
116 }
117
118 Action action{ MsgStream{ msgSvc(), "EventWatchdog" }, m_stackTrace, m_abortOnTimeout, m_eventTimeout,
119 // use a partial copy of the context to avoid copying the optional extension
120 EventContext{ ctx.evt(), ctx.slot(), ctx.subSlot() }, std::move( schedulers ) };
121 return PeriodicAction( std::move( action ), std::chrono::seconds{ m_eventTimeout } );
122 }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
Gaudi::Property< bool > m_abortOnTimeout
Gaudi::Property< bool > m_stackTrace
TARGET * Cast(IInterface *i)
Definition IInterface.h:340
Action
Definition IFileMgr.h:263
@ WARNING
Definition IMessageSvc.h:22
@ FATAL
Definition IMessageSvc.h:22
@ INFO
Definition IMessageSvc.h:22
GAUDI_API long pagedMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: Amount of paged memory currently occupied by the process 'pid'.
Definition Memory.cpp:116
GAUDI_API long virtualMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: priority boost.
Definition Memory.cpp:203

Member Data Documentation

◆ m_abortOnTimeout

Gaudi::Property<bool> Gaudi::EventWatchdogAlg::m_abortOnTimeout
private
Initial value:
{ this, "AbortOnTimeout", false,
"If set to true, the application is killed when we reach the timeout." }

Definition at line 127 of file EventWatchdogAlg.cpp.

127 { this, "AbortOnTimeout", false,
128 "If set to true, the application is killed when we reach the timeout." };

◆ m_eventTimeout

Gaudi::CheckedProperty<unsigned int> Gaudi::EventWatchdogAlg::m_eventTimeout
private
Initial value:
{ this, "EventTimeout", 600,
"Number of seconds allowed to process a single event." }

Definition at line 125 of file EventWatchdogAlg.cpp.

125 { this, "EventTimeout", 600,
126 "Number of seconds allowed to process a single event." };

◆ m_stackTrace

Gaudi::Property<bool> Gaudi::EventWatchdogAlg::m_stackTrace { this, "StackTrace", false, "Whether to print the stack-trace on timeout." }
private

Definition at line 129 of file EventWatchdogAlg.cpp.

129{ this, "StackTrace", false, "Whether to print the stack-trace on timeout." };

The documentation for this class was generated from the following file: