20#include <fmt/format.h>
30 std::string sanitize( std::string_view input ) {
31 std::string
output{ input };
32 std::replace(
begin( output ),
end( output ),
':',
'_' );
38 std::mutex s_watchdogReportMutex;
46 class EventWatchdogAlg :
public Gaudi::Functional::Transformer<PeriodicAction( EventContext const& )> {
49 : Transformer( name, pSvcLocator, KeyValue{
"TimerLocation", fmt::
format(
".{}-timer", sanitize( name ) ) } ) {
55 using namespace std::chrono_literals;
59 const bool doStackTrace;
60 const bool abortOnTimeout;
61 const unsigned int timeout;
64 const std::vector<IScheduler*> schedulers;
68 const std::chrono::steady_clock::time_point eventStart{ std::chrono::steady_clock::now() };
73 log <<
MSG::WARNING << fmt::format(
"More than {}s since the beginning of the event ({})", timeout, ctx )
76 log <<
MSG::WARNING << fmt::format(
"Another {}s passed since last timeout ({})", timeout, ctx ) <<
endmsg;
80 << fmt::format(
"Current memory usage is virtual size = {} MB, resident set size = {} MB",
85 std::scoped_lock protectReport( s_watchdogReportMutex );
87 for (
auto scheduler : schedulers ) { scheduler->dumpState(); }
90 fmt::print( stderr,
"=== Stalled event: current stack trace ({}) ===\n", ctx );
91 gSystem->StackTrace();
94 if ( abortOnTimeout ) {
95 log <<
MSG::FATAL << fmt::format(
"too much time on a single event ({}): aborting process", ctx ) <<
endmsg;
96 std::raise( SIGQUIT );
102 const std::chrono::duration<float, std::chrono::seconds::period> duration =
103 std::chrono::steady_clock::now() - eventStart;
104 log <<
MSG::INFO << fmt::format(
"An event ({}) took {:.3f}s", ctx, duration.count() ) <<
endmsg;
109 std::vector<IScheduler*> schedulers;
112 std::ranges::copy( svcLoc()->getServices() |
114 std::views::filter( [](
auto* p ) {
return p !=
nullptr; } ),
115 std::back_inserter( schedulers ) );
120 EventContext{ ctx.evt(), ctx.slot(), ctx.subSlot() }, std::move( schedulers ) };
126 "Number of seconds allowed to process a single event." };
128 "If set to true, the application is killed when we reach the timeout." };
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
This class represents an entry point to all the event specific data.
EventWatchdogAlg(const std::string &name, ISvcLocator *pSvcLocator)
PeriodicAction operator()(EventContext const &ctx) const override
Gaudi::CheckedProperty< unsigned int > m_eventTimeout
Gaudi::Property< bool > m_abortOnTimeout
Gaudi::Property< bool > m_stackTrace
Implementation of property with value of concrete type.
Helper to periodically run asynchronous tasks.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition of the MsgStream class used to transmit messages.
AttribStringParser::Iterator begin(const AttribStringParser &parser)
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
TARGET * Cast(IInterface *i)
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'.
GAUDI_API long virtualMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: priority boost.