Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v36r11 (bdb84f5f)
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 
73  struct Hub {
75 
89  class Entity {
90  public:
91  template <typename T>
94  , name{ std::move( name ) }
95  , type{ std::move( type ) }
96  , m_ptr{ &ent }
97  , m_typeIndex{ []( const void* ptr ) {
98  return std::type_index( typeid( *reinterpret_cast<const T*>( ptr ) ) );
99  } }
100  , m_reset{ []( void* ptr ) { reinterpret_cast<T*>( ptr )->reset(); } }
101  , m_mergeAndReset{ details::makeMergeAndResetFor<T>() }
102  , m_getJSON{ []( const void* ptr ) { return reinterpret_cast<const T*>( ptr )->toJSON(); } }
103  , m_mergeAndResetFromJSON{ details::makeMergeAndResetFromJSONFor<T>() } {}
111  json toJSON() const { return ( *m_getJSON )( m_ptr ); }
113  std::type_index typeIndex() const { return ( *m_typeIndex )( m_ptr ); }
115  void reset() { return ( *m_reset )( m_ptr ); }
116  // The following function does not protect against usage with entities with different internal types
117  // The user should ensure that entities are compatible before calling this function
119  void mergeAndReset( Entity const& ent ) {
120  if ( typeIndex() != ent.typeIndex() ) {
121  throw std::runtime_error( std::string( "Entity: mergeAndReset called on different types: " ) +
122  typeIndex().name() + " and " + ent.typeIndex().name() );
123  }
124  return ( *m_mergeAndReset )( m_ptr, ent.m_ptr );
125  }
127  bool canMergeFromJSON() const { return m_mergeAndResetFromJSON; }
129  void mergeAndReset( nlohmann::json const& j ) {
130  if ( canMergeFromJSON() ) ( *m_mergeAndResetFromJSON )( m_ptr, j );
131  }
133  bool operator==( void* ent ) { return m_ptr == ent; }
135  bool operator==( Entity const& ent ) { return m_ptr == ent.m_ptr; }
136 
137  private:
139  void* m_ptr{ nullptr };
140  // The next 4 members are needed for type erasure
141  // indeed, their implementation is internal type dependant
142  // (see Constructor above and the usage of T in the reinterpret_cast)
144  std::type_index ( *m_typeIndex )( const void* );
146  void ( *m_reset )( void* );
150  json ( *m_getJSON )( const void* );
153  };
154 
156  struct Sink {
157  virtual void registerEntity( Entity ent ) = 0;
158  virtual void removeEntity( Entity const& ent ) = 0;
159  virtual ~Sink() = default;
160  };
161 
162  template <typename T>
164  registerEntity( { std::move( c ), std::move( n ), std::move( t ), ent } );
165  }
166  void registerEntity( Entity ent ) {
167  std::for_each( begin( m_sinks ), end( m_sinks ), [ent]( auto sink ) { sink->registerEntity( ent ); } );
168  m_entities.emplace_back( std::move( ent ) );
169  }
170  template <typename T>
171  void removeEntity( T& ent ) {
172  auto it = std::find( begin( m_entities ), end( m_entities ), &ent );
173  if ( it != m_entities.end() ) {
174  std::for_each( begin( m_sinks ), end( m_sinks ), [&it]( auto sink ) { sink->removeEntity( *it ); } );
175  m_entities.erase( it );
176  }
177  }
178 
179  void addSink( Sink* sink ) {
181  [sink]( Entity ent ) { sink->registerEntity( std::move( ent ) ); } );
182  m_sinks.push_back( sink );
183  }
184  void removeSink( Sink* sink ) {
185  auto it = std::find( begin( m_sinks ), end( m_sinks ), sink );
186  if ( it != m_sinks.end() ) m_sinks.erase( it );
187  }
188 
189  private:
192  };
193 } // namespace Gaudi::Monitoring
Gaudi::Monitoring::Hub::Sink
Interface reporting services must implement.
Definition: MonitoringHub.h:156
std::for_each
T for_each(T... args)
Gaudi::Monitoring::Hub::Entity::name
std::string name
name of the entity
Definition: MonitoringHub.h:107
Gaudi::Monitoring::Hub::Entity::operator==
bool operator==(Entity const &ent)
operator== for comparison with an entity
Definition: MonitoringHub.h:135
Gaudi::Monitoring::Hub::Entity::operator==
bool operator==(void *ent)
operator== for comparison with raw pointer
Definition: MonitoringHub.h:133
std::string
STL class.
Gaudi::Monitoring::Hub::m_sinks
std::deque< Sink * > m_sinks
Definition: MonitoringHub.h:190
std::move
T move(T... args)
std::find
T find(T... args)
std::type_index::name
T name(T... args)
std::type_index
Gaudi::Monitoring::Hub::m_entities
std::deque< Entity > m_entities
Definition: MonitoringHub.h:191
Gaudi::Monitoring
Definition: JSONSink.cpp:19
gaudirun.c
c
Definition: gaudirun.py:525
Gaudi::Monitoring::Hub::addSink
void addSink(Sink *sink)
Definition: MonitoringHub.h:179
Gaudi::Monitoring::Hub::Sink::removeEntity
virtual void removeEntity(Entity const &ent)=0
jsonFromLHCbLog.json
dictionary json
Definition: jsonFromLHCbLog.py:87
Gaudi::Monitoring::details::has_from_json_v
constexpr bool has_from_json_v
Definition: MonitoringHub.h:37
Gaudi::Monitoring::Hub::Entity::mergeAndReset
void mergeAndReset(nlohmann::json const &j)
allow merging to internal data from JSON input
Definition: MonitoringHub.h:129
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::Hub::Entity::m_typeIndex
std::type_index(* m_typeIndex)(const void *)
function to get internal type.
Definition: MonitoringHub.h:144
CLHEP::begin
double * begin(CLHEP::HepVector &v)
Definition: TupleAlg.cpp:45
Gaudi::Monitoring::Hub::removeSink
void removeSink(Sink *sink)
Definition: MonitoringHub.h:184
Gaudi::Monitoring::Hub::Entity::reset
void reset()
function resetting internal data
Definition: MonitoringHub.h:115
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(std::string c, std::string n, std::string t, T &ent)
Definition: MonitoringHub.h:163
Gaudi::Monitoring::Hub::json
nlohmann::json json
Definition: MonitoringHub.h:74
std::runtime_error
STL class.
std::deque
STL class.
Gaudi::Monitoring::Hub::Entity::typeIndex
std::type_index typeIndex() const
function to get internal type
Definition: MonitoringHub.h:113
Gaudi::Monitoring::details::makeMergeAndResetFromJSONFor
MergeAndResetFromJSON_t makeMergeAndResetFromJSONFor()
Definition: MonitoringHub.h:55
Gaudi::Monitoring::Hub::removeEntity
void removeEntity(T &ent)
Definition: MonitoringHub.h:171
Gaudi::Monitoring::details::has_merge_and_reset_v
constexpr bool has_merge_and_reset_v
Definition: MonitoringHub.h:29
IOTest.end
def end
Definition: IOTest.py:128
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:235
Gaudi::Monitoring::Hub::registerEntity
void registerEntity(Entity ent)
Definition: MonitoringHub.h:166
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_mergeAndReset
details::MergeAndReset_t m_mergeAndReset
function calling merge and reset on internal data with the internal data of another entity
Definition: MonitoringHub.h:148
Gaudi::Monitoring::Hub::Entity::m_getJSON
json(* m_getJSON)(const void *)
function converting the internal data to json.
Definition: MonitoringHub.h:150
Gaudi::Monitoring::Hub::Entity::m_ptr
void * m_ptr
pointer to the actual data inside this Entity
Definition: MonitoringHub.h:139
Gaudi::Monitoring::details::MergeAndResetFromJSON_t
void(*)(void *, const nlohmann::json &) MergeAndResetFromJSON_t
Definition: MonitoringHub.h:52
Gaudi::Monitoring::Hub::Entity::toJSON
json toJSON() const
function giving access to internal data in json format
Definition: MonitoringHub.h:111
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:92
detected.h
Gaudi::Monitoring::details::makeMergeAndResetFor
MergeAndReset_t makeMergeAndResetFor()
Definition: MonitoringHub.h:42
Gaudi::Monitoring::Hub::Entity::mergeAndReset
void mergeAndReset(Entity const &ent)
function calling merge and reset on internal data with the internal data of another entity
Definition: MonitoringHub.h:119
Gaudi::Monitoring::Hub
Central entity in a Gaudi application that manages monitoring objects (i.e.
Definition: MonitoringHub.h:73
Gaudi::Monitoring::Hub::Entity::canMergeFromJSON
bool canMergeFromJSON() const
tell if the Entity data can be updated from JSON input
Definition: MonitoringHub.h:127
Gaudi::Monitoring::Hub::Entity
Wrapper class for arbitrary monitoring objects.
Definition: MonitoringHub.h:89
Gaudi::Monitoring::Hub::Entity::m_mergeAndResetFromJSON
details::MergeAndResetFromJSON_t m_mergeAndResetFromJSON
function calling merge and reset on internal data from JSON input
Definition: MonitoringHub.h:152
Gaudi::Monitoring::Hub::Entity::m_reset
void(* m_reset)(void *)
function reseting internal data.
Definition: MonitoringHub.h:146
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:109
Gaudi::Monitoring::Hub::Entity::component
std::string component
name of the component owning the Entity
Definition: MonitoringHub.h:105