The Gaudi Framework  v37r1 (a7f61348)
MonitoringHub.h
Go to the documentation of this file.
1 /*****************************************************************************\
2 * (c) Copyright 2020-2022 CERN for the benefit of the LHCb Collaboration *
3 * *
4 * This software is distributed under the terms of the GNU General Public *
5 * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
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 #pragma once
12 
13 #include "GaudiKernel/detected.h"
14 
15 #include <deque>
16 #include <functional>
17 #include <nlohmann/json.hpp>
18 #include <string>
19 #include <typeindex>
20 #include <typeinfo>
21 
22 namespace Gaudi::Monitoring {
23 
24  namespace details {
25 
26  template <typename T>
27  using has_merge_and_reset_ = decltype( std::declval<T>().mergeAndReset( std::declval<T&&>() ) );
28  template <typename T>
29  inline constexpr bool has_merge_and_reset_v = Gaudi::cpp17::is_detected_v<has_merge_and_reset_, T>;
30  template <typename T>
31  using has_merge_from_json_ = decltype( std::declval<T>().mergeAndReset( nlohmann::json{} ) );
32  template <typename T>
33  inline constexpr bool has_merge_from_json_v = Gaudi::cpp17::is_detected_v<has_merge_from_json_, T>;
34  template <typename T>
35  using has_from_json_ = decltype( T::fromJSON( nlohmann::json{} ) );
36  template <typename T>
37  inline constexpr bool has_from_json_v = Gaudi::cpp17::is_detected_v<has_from_json_, T>;
38 
39  using MergeAndReset_t = void ( * )( void*, void* );
40 
41  template <typename T>
43  if constexpr ( has_merge_and_reset_v<T> ) {
44  return []( void* ptr, void* other ) {
45  reinterpret_cast<T*>( ptr )->mergeAndReset( std::move( *reinterpret_cast<T*>( other ) ) );
46  };
47  } else {
48  return []( void*, void* ) {};
49  }
50  }
51 
52  using MergeAndResetFromJSON_t = void ( * )( void*, const nlohmann::json& );
53 
54  template <typename T>
56  if constexpr ( has_merge_from_json_v<T> ) {
57  return []( void* ptr, const nlohmann::json& other ) { reinterpret_cast<T*>( ptr )->mergeAndReset( other ); };
58  } else if constexpr ( has_merge_and_reset_v<T> && has_from_json_v<T> ) {
59  return []( void* ptr, const nlohmann::json& other ) {
60  reinterpret_cast<T*>( ptr )->mergeAndReset( T::fromJSON( other ) );
61  };
62  } else {
63  return nullptr;
64  }
65  }
66 
67  } // namespace details
68 
70  using logic_error::logic_error;
71  };
72 
74  template <typename T>
75  void reset( T& ) {}
76 
78  template <typename T>
79  void mergeAndReset( T&, T& ) {}
80 
85  struct Hub {
100  class Entity {
101  public:
102  template <typename T>
105  , name{ std::move( name ) }
106  , type{ std::move( type ) }
107  , m_ptr{ &ent }
108  , m_typeIndex{ []( const void* ptr ) {
109  return std::type_index( typeid( *reinterpret_cast<const T*>( ptr ) ) );
110  } }
111  , m_getJSON{ []( Entity const& e ) -> nlohmann::json { return *reinterpret_cast<const T*>( e.m_ptr ); } }
112  , m_reset{ []( Entity& e ) { reset( *reinterpret_cast<T*>( e.m_ptr ) ); } }
113  , m_mergeAndReset{ []( Entity& e, Entity& o ) {
114  mergeAndReset( *reinterpret_cast<T*>( e.m_ptr ), *reinterpret_cast<T*>( o.m_ptr ) );
115  } } {}
123  std::type_index typeIndex() const { return ( *m_typeIndex )( m_ptr ); }
125  friend void to_json( nlohmann::json& j, Gaudi::Monitoring::Hub::Entity const& e ) { j = ( *e.m_getJSON )( e ); }
127  friend void reset( Entity& e ) { ( *e.m_reset )( e ); }
134  friend void mergeAndReset( Entity& ent, Entity& other ) {
135  if ( ent.typeIndex() != other.typeIndex() ) {
136  throw std::runtime_error( std::string( "Entity: mergeAndReset called on different types: " ) +
137  ent.typeIndex().name() + " and " + other.typeIndex().name() );
138  }
139  ( *ent.m_mergeAndReset )( ent, other );
140  }
142  bool operator==( void* ent ) { return m_ptr == ent; }
144  bool operator==( Entity const& ent ) { return m_ptr == ent.m_ptr; }
146  void* id() const { return m_ptr; }
147 
148  private:
150  void* m_ptr{ nullptr };
151  // The next 4 members are needed for type erasure
152  // indeed, their implementation is internal type dependant
153  // (see Constructor above and the usage of T in the reinterpret_cast)
155  std::type_index ( *m_typeIndex )( const void* );
159  void ( *m_reset )( Entity& );
161  void ( *m_mergeAndReset )( Entity&, Entity& );
162  };
163 
165  struct Sink {
166  virtual void registerEntity( Entity ent ) = 0;
167  virtual void removeEntity( Entity const& ent ) = 0;
168  virtual ~Sink() = default;
169  };
170 
171  Hub() { m_sinks.reserve( 5 ); }
172 
173  template <typename T>
175  registerEntity( { std::move( c ), std::move( n ), std::move( t ), ent } );
176  }
177  void registerEntity( Entity ent ) {
178  std::for_each( begin( m_sinks ), end( m_sinks ), [ent]( auto sink ) { sink->registerEntity( ent ); } );
179  m_entities.emplace( ent.id(), std::move( ent ) );
180  }
181  template <typename T>
182  void removeEntity( T& ent ) {
183  auto it = m_entities.find( &ent );
184  if ( it != m_entities.end() ) {
185  std::for_each( begin( m_sinks ), end( m_sinks ), [&it]( auto sink ) { sink->removeEntity( it->second ); } );
186  m_entities.erase( it );
187  }
188  }
189 
190  void addSink( Sink* sink ) {
192  [sink]( auto ent ) { sink->registerEntity( ent.second ); } );
193  m_sinks.push_back( sink );
194  }
195  void removeSink( Sink* sink ) {
196  auto it = std::find( begin( m_sinks ), end( m_sinks ), sink );
197  if ( it != m_sinks.end() ) m_sinks.erase( it );
198  }
199 
200  private:
203  };
204 } // namespace Gaudi::Monitoring
Gaudi::Monitoring::Hub::Sink
Interface reporting services must implement.
Definition: MonitoringHub.h:165
std::for_each
T for_each(T... args)
Gaudi::Monitoring::Hub::Entity::name
std::string name
name of the entity
Definition: MonitoringHub.h:119
Gaudi::Monitoring::Hub::Entity::operator==
bool operator==(Entity const &ent)
operator== for comparison with an entity
Definition: MonitoringHub.h:144
Gaudi::Monitoring::Hub::Entity::operator==
bool operator==(void *ent)
operator== for comparison with raw pointer
Definition: MonitoringHub.h:142
std::string
STL class.
Gaudi::Monitoring::Hub::m_sinks
std::vector< Sink * > m_sinks
Definition: MonitoringHub.h:201
std::move
T move(T... args)
std::vector
STL class.
std::find
T find(T... args)
std::type_index::name
T name(T... args)
jsonFromLHCbLog.json
json
Definition: jsonFromLHCbLog.py:87
Gaudi::Monitoring::ClashingEntityName
Definition: MonitoringHub.h:69
std::type_index
Gaudi::Monitoring
Definition: JSONSink.cpp:19
gaudirun.c
c
Definition: gaudirun.py:527
Gaudi::Monitoring::Hub::Entity::to_json
friend void to_json(nlohmann::json &j, Gaudi::Monitoring::Hub::Entity const &e)
conversion to json via nlohmann library
Definition: MonitoringHub.h:125
Gaudi::Monitoring::Hub::addSink
void addSink(Sink *sink)
Definition: MonitoringHub.h:190
Gaudi::Monitoring::Hub::Sink::removeEntity
virtual void removeEntity(Entity const &ent)=0
Gaudi::Monitoring::details::has_from_json_v
constexpr bool has_from_json_v
Definition: MonitoringHub.h:37
Gaudi::Monitoring::details::has_from_json_
decltype(T::fromJSON(nlohmann::json{})) has_from_json_
Definition: MonitoringHub.h:35
bug_34121.t
t
Definition: bug_34121.py:30
Gaudi::Monitoring::details::has_merge_and_reset_
decltype(std::declval< T >().mergeAndReset(std::declval< T && >())) has_merge_and_reset_
Definition: MonitoringHub.h:27
Gaudi::Monitoring::Hub::Sink::registerEntity
virtual void registerEntity(Entity ent)=0
details
Definition: AnyDataWrapper.h:18
Gaudi::Monitoring::reset
void reset(T &)
default (empty) implementation of reset method for types stored into an entity
Definition: MonitoringHub.h:75
Gaudi::Monitoring::Hub::Entity::m_typeIndex
std::type_index(* m_typeIndex)(const void *)
function to get internal type.
Definition: MonitoringHub.h:155
ProduceConsume.j
j
Definition: ProduceConsume.py:101
CLHEP::begin
double * begin(CLHEP::HepVector &v)
Definition: TupleAlg.cpp:45
Gaudi::Monitoring::Hub::removeSink
void removeSink(Sink *sink)
Definition: MonitoringHub.h:195
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(std::string c, std::string n, std::string t, T &ent)
Definition: MonitoringHub.h:174
std::runtime_error
STL class.
Gaudi::Monitoring::Hub::Entity::typeIndex
std::type_index typeIndex() const
function to get internal type
Definition: MonitoringHub.h:123
std::logic_error
STL class.
Gaudi::Monitoring::Hub::Entity::m_reset
void(* m_reset)(Entity &)
function reseting internal data.
Definition: MonitoringHub.h:159
Gaudi::Monitoring::details::makeMergeAndResetFromJSONFor
MergeAndResetFromJSON_t makeMergeAndResetFromJSONFor()
Definition: MonitoringHub.h:55
Gaudi::Monitoring::Hub::removeEntity
void removeEntity(T &ent)
Definition: MonitoringHub.h:182
std::map
STL class.
Gaudi::Monitoring::details::has_merge_and_reset_v
constexpr bool has_merge_and_reset_v
Definition: MonitoringHub.h:29
Gaudi::Monitoring::Hub::Entity::id
void * id() const
unique identifier, actually mapped to internal pointer
Definition: MonitoringHub.h:146
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:235
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(Entity ent)
Definition: MonitoringHub.h:177
Gaudi::Monitoring::Hub::Entity::mergeAndReset
friend void mergeAndReset(Entity &ent, Entity &other)
function calling merge and reset on internal data with the internal data of another entity
Definition: MonitoringHub.h:134
Gaudi::Monitoring::details::has_merge_from_json_
decltype(std::declval< T >().mergeAndReset(nlohmann::json{})) has_merge_from_json_
Definition: MonitoringHub.h:31
Gaudi::Monitoring::Hub::Entity::m_ptr
void * m_ptr
pointer to the actual data inside this Entity
Definition: MonitoringHub.h:150
Gaudi::Monitoring::Hub::Entity::m_getJSON
nlohmann::json(* m_getJSON)(Entity const &)
function converting the internal data to json.
Definition: MonitoringHub.h:157
Gaudi::Monitoring::details::MergeAndResetFromJSON_t
void(*)(void *, const nlohmann::json &) MergeAndResetFromJSON_t
Definition: MonitoringHub.h:52
Gaudi::Monitoring::details::has_merge_from_json_v
constexpr bool has_merge_from_json_v
Definition: MonitoringHub.h:33
Gaudi::Monitoring::Hub::Entity::Entity
Entity(std::string component, std::string name, std::string type, T &ent)
Definition: MonitoringHub.h:103
detected.h
Gaudi::Monitoring::details::makeMergeAndResetFor
MergeAndReset_t makeMergeAndResetFor()
Definition: MonitoringHub.h:42
Gaudi::Monitoring::Hub::m_entities
std::map< void *, Entity > m_entities
Definition: MonitoringHub.h:202
IOTest.end
end
Definition: IOTest.py:123
Gaudi::Monitoring::Hub
Central entity in a Gaudi application that manages monitoring objects (i.e.
Definition: MonitoringHub.h:85
Gaudi::Monitoring::Hub::Entity::reset
friend void reset(Entity &e)
function resetting internal data
Definition: MonitoringHub.h:127
Gaudi::Monitoring::Hub::Entity
Wrapper class for arbitrary monitoring objects.
Definition: MonitoringHub.h:100
Gaudi::Monitoring::Hub::Entity::m_mergeAndReset
void(* m_mergeAndReset)(Entity &, Entity &)
function calling merge and reset on internal data with the internal data of another entity
Definition: MonitoringHub.h:161
Gaudi::Monitoring::mergeAndReset
void mergeAndReset(T &, T &)
default (empty) implementation of mergeAndReset method for types stored into an entity
Definition: MonitoringHub.h:79
Gaudi::Monitoring::Hub::Hub
Hub()
Definition: MonitoringHub.h:171
Gaudi::Monitoring::Hub::Sink::~Sink
virtual ~Sink()=default
Gaudi::Monitoring::details::MergeAndReset_t
void(*)(void *, void *) MergeAndReset_t
Definition: MonitoringHub.h:39
Gaudi::Monitoring::Hub::Entity::type
std::string type
type of the entity, see comment above concerning its format and usage
Definition: MonitoringHub.h:121
Gaudi::Monitoring::Hub::Entity::component
std::string component
name of the component owning the Entity
Definition: MonitoringHub.h:117