Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v38r0 (2143aa4c)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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{ typeid( T ) }
109  , m_getJSON{ []( void const* ptr ) -> nlohmann::json { return *reinterpret_cast<const T*>( ptr ); } }
110  , m_reset{ []( void* ptr ) { reset( *reinterpret_cast<T*>( ptr ) ); } }
111  , m_mergeAndReset{
112  []( void* e, void* o ) { mergeAndReset( *reinterpret_cast<T*>( e ), *reinterpret_cast<T*>( o ) ); } } {}
123  j = std::invoke( e.m_getJSON, e.m_ptr );
124  }
126  friend void reset( Entity& e ) { std::invoke( e.m_reset, e.m_ptr ); }
133  friend void mergeAndReset( Entity& ent, Entity& other ) {
134  if ( ent.typeIndex() != other.typeIndex() ) {
135  throw std::runtime_error( std::string( "Entity: mergeAndReset called on different types: " ) +
136  ent.typeIndex().name() + " and " + other.typeIndex().name() );
137  }
138  std::invoke( ent.m_mergeAndReset, ent.m_ptr, other.m_ptr );
139  }
141  bool operator==( Entity const& ent ) { return id() == ent.id(); }
143  void* id() const { return m_ptr; }
144 
145  private:
147  void* m_ptr{ nullptr };
148  // The next 4 members are needed for type erasure
149  // indeed, their implementation is internal type dependant
150  // (see Constructor above and the usage of T in the reinterpret_cast)
153  nlohmann::json ( *m_getJSON )( void const* );
155  void ( *m_reset )( void* );
157  void ( *m_mergeAndReset )( void*, void* );
158  };
159 
161  struct Sink {
162  virtual void registerEntity( Entity ent ) = 0;
163  virtual void removeEntity( Entity const& ent ) = 0;
164  virtual ~Sink() = default;
165  };
166 
167  Hub() { m_sinks.reserve( 5 ); }
168 
169  template <typename T>
171  registerEntity( { std::move( c ), std::move( n ), std::move( t ), ent } );
172  }
173  void registerEntity( Entity ent ) {
174  std::for_each( begin( m_sinks ), end( m_sinks ), [ent]( auto sink ) { sink->registerEntity( ent ); } );
175  m_entities.emplace( ent.id(), std::move( ent ) );
176  }
177  template <typename T>
178  void removeEntity( T& ent ) {
179  auto it = m_entities.find( &ent );
180  if ( it != m_entities.end() ) {
181  std::for_each( begin( m_sinks ), end( m_sinks ), [&it]( auto sink ) { sink->removeEntity( it->second ); } );
182  m_entities.erase( it );
183  }
184  }
185 
186  void addSink( Sink* sink ) {
188  [sink]( auto ent ) { sink->registerEntity( ent.second ); } );
189  m_sinks.push_back( sink );
190  }
191  void removeSink( Sink* sink ) {
192  auto it = std::find( begin( m_sinks ), end( m_sinks ), sink );
193  if ( it != m_sinks.end() ) m_sinks.erase( it );
194  }
195 
196  private:
199  };
200 } // namespace Gaudi::Monitoring
Gaudi::Monitoring::Hub::Sink
Interface reporting services must implement.
Definition: MonitoringHub.h:161
std::for_each
T for_each(T... args)
Gaudi::Monitoring::Hub::Entity::m_mergeAndReset
void(* m_mergeAndReset)(void *, void *)
function calling merge and reset on internal data with the internal data of another entity
Definition: MonitoringHub.h:157
Gaudi::Monitoring::Hub::Entity::name
std::string name
name of the entity
Definition: MonitoringHub.h:116
Gaudi::Monitoring::Hub::Entity::operator==
bool operator==(Entity const &ent)
operator== for comparison with an entity
Definition: MonitoringHub.h:141
std::string
STL class.
Gaudi::Monitoring::Hub::m_sinks
std::vector< Sink * > m_sinks
Definition: MonitoringHub.h:197
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:86
Gaudi::Monitoring::ClashingEntityName
Definition: MonitoringHub.h:69
std::type_index
Gaudi::Monitoring
Definition: JSONSink.cpp:19
gaudirun.c
c
Definition: gaudirun.py:525
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:122
Gaudi::Monitoring::Hub::addSink
void addSink(Sink *sink)
Definition: MonitoringHub.h:186
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
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:191
Gaudi::Monitoring::Hub::Entity::m_getJSON
nlohmann::json(* m_getJSON)(void const *)
function converting the internal data to json.
Definition: MonitoringHub.h:153
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(std::string c, std::string n, std::string t, T &ent)
Definition: MonitoringHub.h:170
std::runtime_error
STL class.
Gaudi::Monitoring::Hub::Entity::typeIndex
std::type_index typeIndex() const
function to get internal type
Definition: MonitoringHub.h:120
std::logic_error
STL class.
Gaudi::Monitoring::details::makeMergeAndResetFromJSONFor
MergeAndResetFromJSON_t makeMergeAndResetFromJSONFor()
Definition: MonitoringHub.h:55
Gaudi::Monitoring::Hub::removeEntity
void removeEntity(T &ent)
Definition: MonitoringHub.h:178
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:143
Gaudi::Monitoring::Hub::Entity::m_typeIndex
std::type_index m_typeIndex
Definition: MonitoringHub.h:151
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:234
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(Entity ent)
Definition: MonitoringHub.h:173
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:133
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:147
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:198
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:126
Gaudi::Monitoring::Hub::Entity
Wrapper class for arbitrary monitoring objects.
Definition: MonitoringHub.h:100
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:167
Gaudi::Monitoring::Hub::Entity::m_reset
void(* m_reset)(void *)
function reseting internal data.
Definition: MonitoringHub.h:155
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:118
Gaudi::Monitoring::Hub::Entity::component
std::string component
name of the component owning the Entity
Definition: MonitoringHub.h:114