7#include "GaudiKernel/IIncidentSvc.h"
10#include "hltinterface/ContainerFactory.h"
11#include "hltinterface/GenericHLTContainer.h"
12#include "webdaq/webdaq.hpp"
14#include <nlohmann/json.hpp>
25 std::shared_ptr<hltinterface::GenericHLTContainer>
cont;
44 const char* tdaq_partition_cstr = std::getenv(
"TDAQ_PARTITION");
45 if (tdaq_partition_cstr !=
nullptr) {
46 m_partition = std::string(tdaq_partition_cstr);
50 return StatusCode::FAILURE;
52 const char* tdaqWebdaqBase_cstr = std::getenv(
"TDAQ_WEBDAQ_BASE");
53 if (tdaqWebdaqBase_cstr !=
nullptr) {
54 m_tdaqWebdaqBase = std::string(tdaqWebdaqBase_cstr);
55 ATH_MSG_INFO(
"TDAQ_WEBDAQ_BASE value: " << m_tdaqWebdaqBase);
57 ATH_MSG_ERROR(
"TDAQ_WEBDAQ_BASE environment variable not set! "
58 "Is needed for the IS publication through webdaq");
59 return StatusCode::FAILURE;
61 const char* tdaq_is_server = std::getenv(
"TDAQ_IS_SERVER");
62 if (tdaq_is_server !=
nullptr) {
63 m_tdaqIsServerName = std::string(tdaq_is_server);
65 m_tdaqIsServerName = m_isServerName.value();
67 ATH_MSG_INFO(
"TDAQ_IS_SERVER value: " << m_tdaqIsServerName);
70 hltinterface::IInfoRegister::setInstance(
this,
true);
71 ATH_MSG_INFO(
"Installed WebdaqInfoSvc as the hltinterface::IInfoRegister singleton");
74 m_factory = hltinterface::ContainerFactory::getInstance();
76 ATH_MSG_INFO(
"Reusing the hltinterface::ContainerFactory installed by another component");
79 m_factory = std::make_shared<hltinterface::ContainerFactory>();
80 hltinterface::ContainerFactory::setInstance(m_factory);
81 ATH_MSG_INFO(
"Installed the default hltinterface::ContainerFactory");
88 return StatusCode::SUCCESS;
96 ATH_MSG_INFO(
"Going to initialize the IS publishing thread (interval: "
113 catch (
const std::exception& e) {
114 ATH_MSG_ERROR(
"Failed to join the IS publishing thread: " << e.what());
115 return StatusCode::FAILURE;
123 return StatusCode::SUCCESS;
133 if (hltinterface::IInfoRegister::instance() ==
this) {
134 hltinterface::IInfoRegister::setInstance(
nullptr,
true);
139 return StatusCode::SUCCESS;
146 std::shared_ptr<hltinterface::GenericHLTContainer> obj)
155 const std::string full = publishPath + obj->getObjName();
163 auto h = std::make_shared<Holder>();
166 h->typeName = obj->getTypeName();
167 m_objs.emplace(full, std::move(
h));
170 <<
" (type=" << obj->getTypeName() <<
")"
182 auto it =
m_objs.find(fullName);
184 ATH_MSG_WARNING(
"releaseObject: " << fullName <<
" is not registered");
196 std::vector<std::shared_ptr<Holder>> all;
198 all.reserve(
m_objs.size());
199 for (
const auto& [_,
h] :
m_objs) {
216 std::scoped_lock hlk(
h->mtx);
217 h->snapshot = std::move(j);
219 h->dirty.store(
true, std::memory_order_release);
221 catch (
const std::exception& e) {
222 ATH_MSG_WARNING(
"Failed to serialise IS object " <<
h->fullName <<
": " << e.what());
237 std::vector<std::shared_ptr<Holder>> dirtyObjs;
239 if (
h->dirty.exchange(
false, std::memory_order_acq_rel)) {
240 dirtyObjs.push_back(
h);
243 for (
const auto&
h : dirtyObjs) {
246 h->dirty.store(
true, std::memory_order_release);
260 using GHC = hltinterface::GenericHLTContainer;
265 auto names = cont.getFieldNames(GHC::INT);
266 for (
size_t i = 0; i < names.size(); ++i) j[names[i]] = cont.getIntField(i);
268 names = cont.getFieldNames(GHC::FLOAT);
269 for (
size_t i = 0; i < names.size(); ++i) j[names[i]] = cont.getFloatField(i);
271 names = cont.getFieldNames(GHC::INTVEC);
272 for (
size_t i = 0; i < names.size(); ++i) j[names[i]] = cont.getIntVecField(i);
274 names = cont.getFieldNames(GHC::FLOATVEC);
275 for (
size_t i = 0; i < names.size(); ++i) j[names[i]] = cont.getFloatVecField(i);
286 std::scoped_lock lk(
h.mtx);
292 ATH_MSG_DEBUG(
"No snapshot available for IS object " <<
h.fullName <<
", skipping publication");
297 <<
" (type=" <<
h.typeName <<
") to "
307 catch (
const std::exception& e) {
308 ATH_MSG_WARNING(
"webdaq::is::put threw for " <<
h.fullName <<
": " << e.what());
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
StatusCode WebdaqInfoSvc::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
Header file for AthHistogramAlgorithm.
static const std::string & type()
Incident type.
std::thread m_thread
Background publishing thread + stop flag.
virtual StatusCode finalize() override
bool publishOne(Holder &h) const
Send the pre-built snapshot via webdaq::is::put.
virtual bool endEvent(const boost::property_tree::ptree &) override
virtual bool registerObject(const std::string publishPath, std::shared_ptr< hltinterface::GenericHLTContainer > obj) override
std::unordered_map< std::string, std::shared_ptr< Holder > > m_objs
Registered IS objects, keyed by full IS name (publishPath + object name).
std::atomic< bool > m_stopFlag
virtual bool releaseObject(const std::string fullName) override
De-register an object.
std::string m_tdaqIsServerName
virtual void handle(const Incident &incident) override
void publishingTask() const
Background loop that periodically publishes containers.
virtual StatusCode stop() override
std::vector< std::shared_ptr< Holder > > holders() const
Copy of the registered holders, taken under m_objsMtx.
static nlohmann::json serializeContainer(hltinterface::GenericHLTContainer &cont)
Serialise all supported fields into a JSON object.
Gaudi::Property< unsigned int > m_intervalSeconds
void conditionedSleep(std::chrono::milliseconds duration, const std::atomic< bool > &stopFlag)
Sleep for duration or until stopFlag is set, whichever comes first.
One entry per registered IS object.
std::string fullName
Name to publish under: publish path + container object name.
std::string typeName
IS type name.
std::mutex mtx
Protects snapshot only. It is written by the event thread in endEvent() and read by the publishing th...
std::shared_ptr< hltinterface::GenericHLTContainer > cont
The producer container. The service only ever reads it.
std::atomic< bool > dirty
Set when a new snapshot is stored, and claimed by the publishing thread so a snapshot is published on...
nlohmann::json snapshot
JSON image of the container, rebuilt on every endEvent() and shipped by the publishing thread.