CatapultServer  v0.5.0.1 (Elephant)
ServiceLocator.h
Go to the documentation of this file.
1 
21 #pragma once
23 #include "catapult/exceptions.h"
24 #include <memory>
25 #include <unordered_map>
26 #include <vector>
27 
28 namespace catapult { namespace crypto { class KeyPair; } }
29 
30 namespace catapult { namespace extensions {
31 
34  public:
36  static constexpr uint64_t Sentinel_Counter_Value = static_cast<uint64_t>(-1);
37 
38  public:
41  {}
42 
45  CATAPULT_LOG(info) << "destroying " << m_rootedServices.size() << " rooted services";
46 
47  // destroy rooted services in reverse order of registration
48  auto i = 1u;
49  while (!m_rootedServices.empty()) {
50  CATAPULT_LOG(debug) << i << ": destroying rooted service " << m_rootedServices.back().first;
51  m_rootedServices.pop_back();
52  ++i;
53  }
54  }
55 
56  public:
58  const crypto::KeyPair& keyPair() const {
59  return m_keyPair;
60  }
61 
63  const std::vector<utils::DiagnosticCounter>& counters() const {
64  return m_counters;
65  }
66 
68  size_t numServices() const {
69  return m_services.size();
70  }
71 
73  template<typename TService>
74  std::shared_ptr<TService> service(const std::string& serviceName) const {
75  std::shared_ptr<TService> pService;
76  if (!tryGetService(serviceName, pService))
77  CATAPULT_THROW_INVALID_ARGUMENT_1("requested service is not registered", serviceName);
78 
79  return pService;
80  }
81 
82  public:
84  void registerService(const std::string& serviceName, const std::shared_ptr<void>& pService) {
85  if (!m_services.emplace(serviceName, pService).second)
86  CATAPULT_THROW_INVALID_ARGUMENT_1("service is already registered", serviceName);
87  }
88 
90  void registerRootedService(const std::string& serviceName, const std::shared_ptr<void>& pService) {
91  registerService(serviceName, pService);
92  m_rootedServices.emplace_back(serviceName, pService);
93  }
94 
96  template<typename TService, typename TSupplier>
97  void registerServiceCounter(const std::string& serviceName, const std::string& counterName, TSupplier supplier) {
98  m_counters.emplace_back(utils::DiagnosticCounterId(counterName), [this, serviceName, supplier]() {
99  std::shared_ptr<TService> pService;
100  this->tryGetService(serviceName, pService);
101  return pService ? supplier(*pService) : Sentinel_Counter_Value;
102  });
103  }
104 
105  private:
106  template<typename TService>
107  bool tryGetService(const std::string& serviceName, std::shared_ptr<TService>& pService) const {
108  auto iter = m_services.find(serviceName);
109  if (m_services.cend() == iter)
110  return false;
111 
112  auto pVoidService = iter->second.lock();
113  pService = std::shared_ptr<TService>(pVoidService, reinterpret_cast<TService*>(pVoidService.get()));
114  return true;
115  }
116 
117  private:
119  std::vector<utils::DiagnosticCounter> m_counters;
120  std::unordered_map<std::string, std::weak_ptr<void>> m_services;
121  std::vector<std::pair<std::string, std::shared_ptr<void>>> m_rootedServices;
122  };
123 }}
catapult::extensions::ServiceLocator::m_keyPair
const crypto::KeyPair & m_keyPair
Definition: ServiceLocator.h:118
catapult::extensions::ServiceLocator::m_services
std::unordered_map< std::string, std::weak_ptr< void > > m_services
Definition: ServiceLocator.h:120
catapult::utils::DiagnosticCounterId
A diagnostic counter id.
Definition: DiagnosticCounterId.h:27
CATAPULT_LOG
#define CATAPULT_LOG(SEV)
Writes a log entry to the default logger with SEV severity.
Definition: Logging.h:340
exceptions.h
catapult::extensions::ServiceLocator::tryGetService
bool tryGetService(const std::string &serviceName, std::shared_ptr< TService > &pService) const
Definition: ServiceLocator.h:107
Parser.debug
def debug(*args)
Definition: Parser.py:46
catapult::extensions::ServiceLocator::registerRootedService
void registerRootedService(const std::string &serviceName, const std::shared_ptr< void > &pService)
Adds a rooted service (pService) with serviceName that is kept alive by the service locator.
Definition: ServiceLocator.h:90
DiagnosticCounter.h
catapult::extensions::ServiceLocator::m_counters
std::vector< utils::DiagnosticCounter > m_counters
Definition: ServiceLocator.h:119
catapult::extensions::ServiceLocator::service
std::shared_ptr< TService > service(const std::string &serviceName) const
Gets the service with serviceName.
Definition: ServiceLocator.h:74
catapult::supplier
std::function< T()> supplier
A (stateless) supplier function.
Definition: functions.h:39
catapult::extensions::ServiceLocator::counters
const std::vector< utils::DiagnosticCounter > & counters() const
Gets the diagnostic counters.
Definition: ServiceLocator.h:63
catapult::extensions::ServiceLocator::Sentinel_Counter_Value
static constexpr uint64_t Sentinel_Counter_Value
Value that is returned when a statistics source is nullptr.
Definition: ServiceLocator.h:36
catapult::extensions::ServiceLocator::~ServiceLocator
~ServiceLocator()
Destroys the locator.
Definition: ServiceLocator.h:44
catapult::crypto::KeyPair
Represents a pair of private key with associated public key.
Definition: KeyPair.h:33
forwardsValidation.info
def info(*args)
Definition: forwardsValidation.py:12
CATAPULT_THROW_INVALID_ARGUMENT_1
#define CATAPULT_THROW_INVALID_ARGUMENT_1(MESSAGE, PARAM1)
Macro used to throw a catapult invalid argument with a single parameter.
Definition: exceptions.h:183
catapult::extensions::ServiceLocator::registerService
void registerService(const std::string &serviceName, const std::shared_ptr< void > &pService)
Adds a service (pService) with serviceName.
Definition: ServiceLocator.h:84
catapult::extensions::ServiceLocator::m_rootedServices
std::vector< std::pair< std::string, std::shared_ptr< void > > > m_rootedServices
Definition: ServiceLocator.h:121
catapult::extensions::ServiceLocator::numServices
size_t numServices() const
Gets the number of registered services.
Definition: ServiceLocator.h:68
catapult::extensions::ServiceLocator::ServiceLocator
ServiceLocator(const crypto::KeyPair &keyPair)
Creates a locator around keyPair.
Definition: ServiceLocator.h:40
catapult
Definition: AddressExtractionExtension.cpp:28
catapult::extensions::ServiceLocator::registerServiceCounter
void registerServiceCounter(const std::string &serviceName, const std::string &counterName, TSupplier supplier)
Adds a service-dependent counter with counterName for service serviceName given supplier.
Definition: ServiceLocator.h:97
catapult::extensions::ServiceLocator::keyPair
const crypto::KeyPair & keyPair() const
Gets the local key pair.
Definition: ServiceLocator.h:58
catapult::extensions::ServiceLocator
A service locator for local node services.
Definition: ServiceLocator.h:33