RTC Toolkit 5.1.0
Loading...
Searching...
No Matches
eventRecordingUnit.hpp
Go to the documentation of this file.
1
12#ifndef RTCTK_COMPONENTFRAMEWORK_EVENTRECORDINGUNIT_HPP
13#define RTCTK_COMPONENTFRAMEWORK_EVENTRECORDINGUNIT_HPP
14
24
25#include <fmt/format.h>
26#include <numapp/numapolicies.hpp>
27#include <numapp/thread.hpp>
28#include <taiclock/taiClock.hpp>
29
30#include <cstdint>
31#include <exception>
32#include <string>
33#include <string_view>
34#include <thread>
35
37
45template <>
46struct [[deprecated]] RecordingInfo<ComputationEvent> {
47 using sv = std::string_view;
49 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
50 std::string,
51 std::string,
52 std::string,
53 std::string>;
54
55 static constexpr Recorder::ColumnDescription COLUMNS =
56 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
57 {sv("source_timestamp"), sv("")},
58 {sv("origin"), sv("")},
59 {sv("item"), sv("")},
60 {sv("state"), sv("")}}};
61
62 static Recorder::TupleType AsTuple(const DataType& data) {
63 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
64 return std::make_tuple(ts, data.time, data.origin, data.item, data.state);
65 }
66};
67
75template <>
77 using sv = std::string_view;
79 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
80 std::string,
81 std::string,
82 std::string,
83 std::string>;
84
85 static constexpr Recorder::ColumnDescription COLUMNS =
86 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
87 {sv("source_timestamp"), sv("")},
88 {sv("origin"), sv("")},
89 {sv("item"), sv("")},
90 {sv("result"), sv("")}}};
91
92 static Recorder::TupleType AsTuple(const DataType& data) {
93 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
94 return std::make_tuple(ts, data.time, data.origin, data.item, data.result.dump());
95 }
96};
97
105template <>
107 using sv = std::string_view;
109 using Recorder =
111
112 static constexpr Recorder::ColumnDescription COLUMNS =
113 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
114 {sv("source_timestamp"), sv("")},
115 {sv("origin"), sv("")},
116 {sv("item"), sv("")}}};
117
119 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
120 return std::make_tuple(ts, data.time, data.origin, data.item);
121 }
122};
123
131template <>
132struct [[deprecated]] RecordingInfo<ConfigurationEvent> {
133 using sv = std::string_view;
135 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
136 std::string,
137 std::string,
138 std::string,
139 std::string>;
140
141 static constexpr Recorder::ColumnDescription COLUMNS =
142 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
143 {sv("source_timestamp"), sv("")},
144 {sv("origin"), sv("")},
145 {sv("items"), sv("")},
146 {sv("state"), sv("")}}};
147
149 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
150 std::string items;
151 bool is_first = true;
152 for (const auto& item : data.items) {
153 if (is_first == false) {
154 items += ";";
155 }
156 items += item.name;
157 is_first = false;
158 }
159 return std::make_tuple(ts, data.time, data.origin, items, data.state);
160 }
161};
162
170template <>
172 using sv = std::string_view;
174 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
175 std::string,
176 std::string,
177 std::string,
178 std::string>;
179
180 static constexpr Recorder::ColumnDescription COLUMNS =
181 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
182 {sv("source_timestamp"), sv("")},
183 {sv("origin"), sv("")},
184 {sv("items"), sv("")},
185 {sv("state"), sv("")}}};
186
188 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
189 std::string items;
190 bool is_first = true;
191 for (const auto& item : data.items) {
192 if (is_first == false) {
193 items += ";";
194 }
195 items += item.name;
196 is_first = false;
197 }
198 return std::make_tuple(ts, data.time, data.origin, items, data.state);
199 }
200};
201
209template <>
211 using sv = std::string_view;
213 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
214 std::string,
215 std::string,
216 std::string,
217 std::string>;
218
219 static constexpr Recorder::ColumnDescription COLUMNS =
220 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
221 {sv("source_timestamp"), sv("")},
222 {sv("origin"), sv("")},
223 {sv("items"), sv("")},
224 {sv("state"), sv("")}}};
225
227 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
228 std::string items;
229 bool is_first = true;
230 for (const auto& item : data.items) {
231 if (is_first == false) {
232 items += ";";
233 }
234 items += item.name;
235 is_first = false;
236 }
237 return std::make_tuple(ts, data.time, data.origin, items, data.state);
238 }
239};
240
248template <>
250 using sv = std::string_view;
252 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
253 std::string,
254 std::string,
255 std::string,
256 std::string,
257 std::string,
258 std::string,
259 uint64_t>;
260
261 static constexpr Recorder::ColumnDescription COLUMNS =
262 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
263 {sv("source_timestamp"), sv("")},
264 {sv("origin"), sv("")},
265 {sv("items"), sv("")},
266 {sv("state"), sv("")},
267 {sv("hrtc_origin"), sv("")},
268 {sv("hrtc_timestamp"), sv("")},
269 {sv("hrtc_sample_id"), sv("")}}};
270
272 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
273 std::string items;
274 bool is_first = true;
275 for (const auto& item : data.items) {
276 if (is_first == false) {
277 items += ";";
278 }
279 items += item.name;
280 is_first = false;
281 }
282 return std::make_tuple(ts,
283 data.time,
284 data.origin,
285 items,
286 data.state,
287 data.hrtc_origin,
288 data.hrtc_timestamp,
289 data.hrtc_sample_id);
290 }
291};
292
300template <>
302 using sv = std::string_view;
304 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
305 std::string,
306 std::string,
307 std::string,
308 std::string,
309 std::string,
310 std::string,
311 uint64_t>;
312
313 static constexpr Recorder::ColumnDescription COLUMNS =
314 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
315 {sv("source_timestamp"), sv("")},
316 {sv("origin"), sv("")},
317 {sv("items"), sv("")},
318 {sv("state"), sv("")},
319 {sv("hrtc_origin"), sv("")},
320 {sv("hrtc_timestamp"), sv("")},
321 {sv("hrtc_sample_id"), sv("")}}};
322
324 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
325 std::string items;
326 bool is_first = true;
327 for (const auto& item : data.items) {
328 if (is_first == false) {
329 items += ";";
330 }
331 items += item.name;
332 is_first = false;
333 }
334 return std::make_tuple(ts,
335 data.time,
336 data.origin,
337 items,
338 data.state,
339 data.hrtc_origin,
340 data.hrtc_timestamp,
341 data.hrtc_sample_id);
342 }
343};
344
352template <>
353struct [[deprecated]] RecordingInfo<CoordinationEvent> {
354 using sv = std::string_view;
357
359 {{sv("timestamp"), sv("")}, {sv("source_timestamp"), sv("")}, {sv("origin"), sv("")}}};
360
362 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
363 return std::make_tuple(ts, data.time, data.origin);
364 }
365};
366
374template <>
375struct [[deprecated]] RecordingInfo<StateChangedEvent> {
376 using sv = std::string_view;
378 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
379 std::string,
380 std::string,
381 std::string,
382 std::string>;
383
384 static constexpr Recorder::ColumnDescription COLUMNS =
385 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
386 {sv("source_timestamp"), sv("")},
387 {sv("origin"), sv("")},
388 {sv("entity"), sv("")},
389 {sv("state"), sv("")}}};
390
392 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
393 return std::make_tuple(ts, data.time, data.origin, data.entity, data.state);
394 }
395};
396
404template <>
405struct [[deprecated]] RecordingInfo<HrtcStateChangedEvent> {
406 using sv = std::string_view;
408 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
409 std::string,
410 std::string,
411 std::string,
412 std::string,
413 std::string,
414 uint64_t>;
415
416 static constexpr Recorder::ColumnDescription COLUMNS =
417 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
418 {sv("source_timestamp"), sv("")},
419 {sv("origin"), sv("")},
420 {sv("entity"), sv("")},
421 {sv("state"), sv("")},
422 {sv("hrtc_timestamp"), sv("")},
423 {sv("hrtc_sample_id"), sv("")}}};
424
426 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
427 return std::make_tuple(ts,
428 data.time,
429 data.origin,
430 data.entity,
431 data.state,
432 data.hrtc_timestamp,
433 data.hrtc_sample_id);
434 }
435};
436
444template <>
445struct [[deprecated]] RecordingInfo<AlertStatusEvent> {
446 using sv = std::string_view;
448 using Recorder = CsvDataRecorder<taiclock::TaiClock::time_point::rep,
449 std::string,
450 std::string,
451 bool,
452 std::string>;
453
454 static constexpr Recorder::ColumnDescription COLUMNS =
455 Recorder::ColumnDescription{{{sv("timestamp"), sv("")},
456 {sv("source_timestamp"), sv("")},
457 {sv("origin"), sv("")},
458 {sv("status"), sv("")},
459 {sv("active_alerts"), sv("")}}};
460
462 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
463
464 JsonPayload json_active;
465 for (auto&& alert : data.active_alerts) {
466 json_active.push_back(JsonPayload{{"origin", alert.origin},
467 {"id", alert.id},
468 {"description", alert.description},
469 {"since", alert.since}});
470 }
471
472 return std::make_tuple(
473 ts, data.time, data.origin, data.status, json_active.dump());
474 }
475};
476
485class [[deprecated("Use EventRecordingUnit")]] TypedEventRecordingUnit : public RecordingUnit {
486public:
487 using FilterMethod = std::function<bool(const EventType&)>;
488
496 TypedEventRecordingUnit(const std::string& comp_id,
497 const std::string& unit_id,
498 ServiceContainer& services,
499 FilterMethod input_filter = nullptr)
500 : RecordingUnit(comp_id, unit_id, "TypedEvent", services)
501 , m_event_service(services.Get<EventServiceIf>())
502 , m_subscriber(m_event_service.MakeSubscriber<EventType>())
503 , m_input_filter(input_filter)
504 , m_output(RecordingInfo<EventType>::COLUMNS) {
505 auto topic_path = DataPointPath(fmt::format(OLDB_PATH_TOPIC_NAME, comp_id, unit_id));
506 m_oldb.CreateDataPoint<std::string>(topic_path);
507 m_oldb.SetDataPoint<std::string>(topic_path, EventType::TOPIC_NAME);
508
509 m_samples_written_reg = m_metrics.AddCounter(
510 &m_samples_written, CounterMetricInfo(unit_id + "/samples_written", "Samples written"));
511 Update();
512 }
513
515 m_stop = true;
516 if (m_process_thread.joinable()) {
517 m_process_thread.join();
518 }
519 SetStopped();
520 }
521
526 void Prepare(const std::filesystem::path& file_path) override {
527 SetState(
528 State::PREPARING, State::STOPPED, "tried to prepare a non-stopped EventRecordingUnit");
529
530 m_file_path = file_path / (GetId() + m_output.DefaultFileExtension());
531
532 auto policies = numapp::NumaPolicies();
533 m_process_thread =
534 numapp::MakeThread(m_unit_id.substr(0, 15), policies, [&]() { return Process(); });
535 }
539 void Start() override {
540 m_start = true;
541 }
546 std::vector<std::filesystem::path> Stop() override {
547 m_stop = true;
548 if (m_process_thread.joinable()) {
549 m_process_thread.join();
550 }
551
552 std::vector<std::filesystem::path> files;
553 if (m_file_path) {
554 files.push_back(*m_file_path);
555 }
556 m_file_path.reset();
557 SetStopped();
558 return files;
559 }
560
561private:
562 void Process() {
563 using namespace std::chrono_literals;
564
565 try {
566 m_output.Open(*m_file_path);
567 m_samples_written.Store(0);
568
569 m_subscriber->Subscribe([&](const EventType& ev) {
570 if (GetState() == State::RUNNING) {
571 try {
572 if (m_input_filter) {
573 if (m_input_filter(ev)) {
574 m_output.Write(RecordingInfo<EventType>::AsTuple(ev));
575 m_samples_written++;
576 }
577 } else {
578 m_output.Write(RecordingInfo<EventType>::AsTuple(ev));
579 m_samples_written++;
580 }
581 } catch (...) {
582 SetFailed(std::current_exception());
583 return;
584 }
585 }
586 });
587
588 SetState(State::IDLE,
589 State::PREPARING,
590 "EventRecordingUnit tried to go to IDLE from another state than PREPARING");
591
592 while (m_stop == false) {
593 switch (GetState()) {
594 case State::IDLE:
595 if (m_start) {
596 SetState(State::WAITING,
597 State::IDLE,
598 "EventRecorder illegal state transition, tried going to WAITING "
599 "from another state than IDLE");
600 break;
601 }
602 std::this_thread::sleep_for(1ms);
603 break;
604 case State::WAITING:
605 if (not HasLeaders() or (HasLeaders() and HasFirstLeaderStarted())) {
606 SetState(State::RUNNING,
607 State::WAITING,
608 "EventRecorder illegal state transition, tried going to RUNNING "
609 "from another state than WAITING");
610 break;
611 }
612 std::this_thread::sleep_for(1ms);
613 break;
614 case State::RUNNING:
615 if (HasLeaders() and HasLastLeaderFinished()) {
616 SetState(State::FINISHED,
617 State::RUNNING,
618 "EventRecorder illegal state transition, tried going to FINISHED "
619 "from another state than RUNNING");
620 break;
621 }
622 std::this_thread::sleep_for(1ms);
623 break;
624 default:
625 std::this_thread::sleep_for(1ms);
626 }
627 }
628
629 m_subscriber->Unsubscribe();
630 m_output.Close();
631 // Stopped state will be set by Stop function after join
632 m_start = false;
633 m_stop = false;
634 ResetLeaderStates();
635 } catch (...) {
636 m_subscriber->Unsubscribe();
637 m_output.Close();
638 m_start = false;
639 m_stop = false;
640 SetFailed(std::current_exception());
641 ResetLeaderStates();
642 }
643 }
644
645// we dont need any deprecation warnings in already deprecated code
646#pragma GCC diagnostic push
647#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
648 TypedEventService m_event_service;
649 std::unique_ptr<TypedEventSubscriber<EventType>> m_subscriber;
650#pragma GCC diagnostic pop
651
652 FilterMethod m_input_filter;
653
654 OutputStage m_output;
655
656 std::atomic<bool> m_start = false;
657 std::atomic<bool> m_stop = false;
658 std::thread m_process_thread;
659
660 perfc::CounterI64 m_samples_written;
661 perfc::ScopedRegistration m_samples_written_reg;
662
666 inline static constexpr std::string_view OLDB_PATH_TOPIC_NAME = "/{}/rec_units/{}/topic_name";
667};
668
676template <typename OutputStage = CsvDataRecorder<taiclock::TaiClock::time_point::rep, std::string>>
677class [[deprecated("Use EventRecordingUnit")]] JsonEventRecordingUnit : public RecordingUnit {
678public:
679 using sv = std::string_view;
680 using FilterMethod = std::function<bool(const JsonPayload&)>;
681 using ColumnDescription = typename OutputStage::ColumnDescription;
682 using ColumnMetaData = typename OutputStage::ColumnMetaData;
683
692 JsonEventRecordingUnit(const std::string& comp_id,
693 const std::string& unit_id,
694 ServiceContainer& services,
695 const std::string& topic_name,
696 FilterMethod input_filter = nullptr)
697 : RecordingUnit(comp_id, unit_id, "JsonEvent", services)
698 , m_event_service(services.Get<EventServiceIf>())
699 , m_subscriber(m_event_service.MakeSubscriber(topic_name))
700 , m_input_filter(std::move(input_filter))
701 , m_output(COLUMNS) {
702 auto topic_path = DataPointPath(fmt::format(OLDB_PATH_TOPIC_NAME, comp_id, unit_id));
703 m_oldb.CreateDataPoint<std::string>(topic_path);
704 m_oldb.SetDataPoint<std::string>(topic_path, topic_name);
705
706 m_samples_written_reg = m_metrics.AddCounter(
707 &m_samples_written, CounterMetricInfo(unit_id + "/samples_written", "Samples written"));
708 Update();
709 }
710
712 m_stop = true;
713 if (m_process_thread.joinable()) {
714 m_process_thread.join();
715 }
716 SetStopped();
717 }
718
723 void Prepare(const std::filesystem::path& file_path) override {
724 SetState(State::PREPARING,
725 State::STOPPED,
726 "EventRecorder tried to go from non-STOPPED State to PREPARING");
727
728 m_file_path = file_path / (GetId() + m_output.DefaultFileExtension());
729
730 auto policies = numapp::NumaPolicies();
731 m_process_thread =
732 numapp::MakeThread(m_unit_id.substr(0, 15), policies, [&]() { return Process(); });
733 }
737 void Start() override {
738 m_start = true;
739 }
744 std::vector<std::filesystem::path> Stop() override {
745 m_stop = true;
746 if (m_process_thread.joinable()) {
747 m_process_thread.join();
748 }
749 SetStopped();
750 std::vector<std::filesystem::path> files;
751 if (m_file_path) {
752 files.push_back(*m_file_path);
753 }
754 return files;
755 }
756
757private:
758 void Process() {
759 using namespace std::chrono_literals;
760
761 try {
762 m_output.Open(*m_file_path);
763 m_samples_written.Store(0);
764
765 m_subscriber->Subscribe([&](const JsonPayload& ev) {
766 if (GetState() == State::RUNNING) {
767 try {
768 if (m_input_filter) {
769 if (m_input_filter(ev)) {
770 m_output.Write(AsTuple(ev));
771 m_samples_written++;
772 }
773 } else {
774 m_output.Write(AsTuple(ev));
775 m_samples_written++;
776 }
777 } catch (...) {
778 SetFailed(std::current_exception());
779 return;
780 }
781 }
782 });
783
784 SetState(State::IDLE,
785 State::PREPARING,
786 "Event recorder was not in PREPARING when trying to go to IDLE");
787
788 while (m_stop == false) {
789 switch (GetState()) {
790 case State::IDLE:
791 if (m_start) {
792 SetState(State::WAITING,
793 State::IDLE,
794 "Event recorder was not in IDLE when trying to go to WAITING");
795 break;
796 }
797 std::this_thread::sleep_for(1ms);
798 break;
799 case State::WAITING:
800 if (not HasLeaders() or (HasLeaders() and HasFirstLeaderStarted())) {
801 SetState(State::RUNNING,
802 State::WAITING,
803 "Event recorder was not in WAITING when trying to go to RUNNING");
804 break;
805 }
806 std::this_thread::sleep_for(1ms);
807 break;
808 case State::RUNNING:
809 if (HasLeaders() and HasLastLeaderFinished()) {
810 SetState(State::FINISHED,
811 State::RUNNING,
812 "Event recorder was not running when trying to go to finish");
813 break;
814 }
815 std::this_thread::sleep_for(1ms);
816 break;
817 default:
818 std::this_thread::sleep_for(1ms);
819 }
820 }
821
822 m_subscriber->Unsubscribe();
823 m_output.Close();
824 // the actual STOPPED state will be set by the Stop function
825 m_start = false;
826 m_stop = false;
827 ResetLeaderStates();
828 } catch (...) {
829 m_subscriber->Unsubscribe();
830 m_output.Close();
831 m_start = false;
832 m_stop = false;
833 SetFailed(std::current_exception());
834 ResetLeaderStates();
835 }
836 }
837
838 static typename OutputStage::TupleType AsTuple(const JsonPayload& data) {
839 auto ts = taiclock::TaiClock::now().time_since_epoch().count();
840 return std::make_tuple(ts, data.dump());
841 }
842
843 static constexpr ColumnDescription COLUMNS{ColumnMetaData{sv("timestamp"), sv("")},
844 ColumnMetaData{sv("payload"), sv("")}};
845
846 EventServiceIf& m_event_service;
847 std::unique_ptr<EventSubscriberIf> m_subscriber;
848
849 FilterMethod m_input_filter;
850
851 OutputStage m_output;
852
853 std::atomic<bool> m_start = false;
854 std::atomic<bool> m_stop = false;
855 std::thread m_process_thread;
856
857 perfc::CounterI64 m_samples_written;
858 perfc::ScopedRegistration m_samples_written_reg;
859
863 inline static constexpr std::string_view OLDB_PATH_TOPIC_NAME = "/{}/rec_units/{}/topic_name";
864};
865
873template <class OutputStage = std::ofstream>
875public:
876 using FilterMethod = std::function<bool(const JsonPayload&)>;
877
885 EventRecordingUnit(const std::string& comp_id,
886 const std::string& unit_id,
887 ServiceContainer& services,
888 FilterMethod input_filter = nullptr)
889 : RecordingUnit(comp_id, unit_id, "Event", services)
890 , m_event_service(services.Get<EventServiceIf>()) {
891 if (input_filter) {
892 m_input_filter = std::move(input_filter);
893 } else {
894 m_input_filter = [](const JsonPayload&) { return true; };
895 }
896
897 auto rtr_topic_path = DataPointPath(fmt::format(RTR_PATH_TOPIC_NAME, comp_id, unit_id));
898 auto topic_name = m_rtr.GetDataPoint<std::string>(rtr_topic_path);
899
900 auto oldb_topic_path = DataPointPath(fmt::format(OLDB_PATH_TOPIC_NAME, comp_id, unit_id));
902 m_oldb.SetDataPoint<std::string>(oldb_topic_path, topic_name);
903
904 m_subscriber = m_event_service.MakeSubscriber(topic_name);
905
906 m_samples_written_reg = m_metrics.AddCounter(
907 &m_samples_written, CounterMetricInfo(unit_id + "/samples_written", "Samples written"));
908 Update();
909 }
910
912 m_stop = true;
913 if (m_process_thread.joinable()) {
914 m_process_thread.join();
915 }
916 SetStopped();
917 }
918
923 void Prepare(const std::filesystem::path& file_path) override {
926 "EventRecorder tried to go from non-STOPPED State to PREPARING");
927
928 m_file_path = file_path / (GetId() + ".jsonl");
929
930 auto policies = numapp::NumaPolicies();
931 m_process_thread =
932 numapp::MakeThread(m_unit_id.substr(0, 15), policies, [&]() { return Process(); });
933 }
937 void Start() override {
938 m_start = true;
939 }
944 std::vector<std::filesystem::path> Stop() override {
945 m_stop = true;
946 if (m_process_thread.joinable()) {
947 m_process_thread.join();
948 }
949 SetStopped();
950 std::vector<std::filesystem::path> files;
951 if (m_file_path) {
952 files.push_back(*m_file_path);
953 }
954 return files;
955 }
956
957private:
958 void Process() {
959 using namespace std::chrono_literals;
960
961 OutputStage output;
962
963 try {
964 output.open(*m_file_path, std::ios::out);
965 m_samples_written.Store(0);
966
967 m_subscriber->Subscribe([&](const JsonPayload& ev) {
968 if (GetState() == State::RUNNING) {
969 try {
970 if (m_input_filter(ev)) {
971 output << ev << "\n";
972 m_samples_written++;
973 }
974 } catch (...) {
975 SetFailed(std::current_exception());
976 return;
977 }
978 }
979 });
980
983 "Event recorder was not in PREPARING when trying to go to IDLE");
984
985 while (m_stop == false) {
986 switch (GetState()) {
987 case State::IDLE:
988 if (m_start) {
991 "Event recorder was not in IDLE when trying to go to WAITING");
992 break;
993 }
994 std::this_thread::sleep_for(1ms);
995 break;
996 case State::WAITING:
1000 "Event recorder was not in WAITING when trying to go to RUNNING");
1001 break;
1002 }
1003 std::this_thread::sleep_for(1ms);
1004 break;
1005 case State::RUNNING:
1009 "Event recorder was not running when trying to go to finish");
1010 break;
1011 }
1012 std::this_thread::sleep_for(1ms);
1013 break;
1014 default:
1015 std::this_thread::sleep_for(1ms);
1016 }
1017 }
1018
1019 m_subscriber->Unsubscribe();
1020 // the actual STOPPED state will be set by the Stop function
1021 m_start = false;
1022 m_stop = false;
1024 } catch (...) {
1025 m_subscriber->Unsubscribe();
1026 m_start = false;
1027 m_stop = false;
1028 SetFailed(std::current_exception());
1030 }
1031 }
1032
1033 EventServiceIf& m_event_service;
1034 std::unique_ptr<EventSubscriberIf> m_subscriber;
1035
1036 FilterMethod m_input_filter;
1037
1038 std::atomic<bool> m_start = false;
1039 std::atomic<bool> m_stop = false;
1040 std::thread m_process_thread;
1041
1042 perfc::CounterI64 m_samples_written;
1043 perfc::ScopedRegistration m_samples_written_reg;
1044
1048 inline static constexpr std::string_view RTR_PATH_TOPIC_NAME =
1049 "/{}/static/rec_units/{}/topic_name";
1050
1054 inline static constexpr std::string_view OLDB_PATH_TOPIC_NAME = "/{}/rec_units/{}/topic_name";
1055};
1056
1057} // namespace rtctk::componentFramework
1058
1059#endif // RTCTK_COMPONENTFRAMEWORK_EVENTRECORDINGUNIT_HPP
virtual perfc::ScopedRegistration AddCounter(CounterVariant counter, CounterMetricInfo info)=0
Add a counter to be included in component metrics, identified by its address, together with info to t...
Defines auxiliary information associated with each counter registered with ComponentMetricsIf.
Definition componentMetricsIf.hpp:46
Recorder used for writing data to a CSV file.
Definition csvDataRecorder.hpp:33
typename DataRecorder< T... >::ColumnDescription ColumnDescription
Definition csvDataRecorder.hpp:35
This class provides a wrapper for a data point path.
Definition dataPointPath.hpp:74
std::tuple< T... > TupleType
Type of the tuple returned by user-defined method AsTuple.
Definition dataRecorder.hpp:43
Recording Unit that records JSON events in JSON Lines format (.jsonl)
Definition eventRecordingUnit.hpp:874
std::function< bool(const JsonPayload &)> FilterMethod
Definition eventRecordingUnit.hpp:876
EventRecordingUnit(const std::string &comp_id, const std::string &unit_id, ServiceContainer &services, FilterMethod input_filter=nullptr)
Create a new recording unit.
Definition eventRecordingUnit.hpp:885
std::vector< std::filesystem::path > Stop() override
Stop the recording and wait for it's termination.
Definition eventRecordingUnit.hpp:944
void Prepare(const std::filesystem::path &file_path) override
Prepare the recording.
Definition eventRecordingUnit.hpp:923
virtual ~EventRecordingUnit()
Definition eventRecordingUnit.hpp:911
void Start() override
Start the recording.
Definition eventRecordingUnit.hpp:937
Interface class for providing pub/sub facilities for JSON events.
Definition eventServiceIf.hpp:29
virtual std::unique_ptr< EventSubscriberIf > MakeSubscriber(const std::string &topic)=0
Creates a new subscriber for a specified topic.
Recording Unit that can record JSON events.
Definition eventRecordingUnit.hpp:677
typename OutputStage::ColumnMetaData ColumnMetaData
Definition eventRecordingUnit.hpp:682
std::function< bool(const JsonPayload &)> FilterMethod
Definition eventRecordingUnit.hpp:680
void Prepare(const std::filesystem::path &file_path) override
Prepare the recording.
Definition eventRecordingUnit.hpp:723
JsonEventRecordingUnit(const std::string &comp_id, const std::string &unit_id, ServiceContainer &services, const std::string &topic_name, FilterMethod input_filter=nullptr)
Create a new recording unit.
Definition eventRecordingUnit.hpp:692
virtual ~JsonEventRecordingUnit()
Definition eventRecordingUnit.hpp:711
void Start() override
Start the recording.
Definition eventRecordingUnit.hpp:737
std::string_view sv
Definition eventRecordingUnit.hpp:679
typename OutputStage::ColumnDescription ColumnDescription
Definition eventRecordingUnit.hpp:681
std::vector< std::filesystem::path > Stop() override
Stop the recording and wait for it's termination.
Definition eventRecordingUnit.hpp:744
Abstract base class for all sources that can be recorded by the MetadataCollector and TelemetryRecord...
Definition recordingUnit.hpp:51
bool HasLeaders()
Check if this unit is following any leaders.
Definition recordingUnit.cpp:97
OldbIf & m_oldb
Definition recordingUnit.hpp:173
bool HasLastLeaderFinished()
This function is used to determine if this unit should stop recording when waiting for leaders.
Definition recordingUnit.cpp:106
bool HasFirstLeaderStarted()
This function is used to determine if this unit should start recording when waiting for leaders.
Definition recordingUnit.cpp:101
virtual void Update()
Update dynamic settings.
Definition recordingUnit.cpp:166
void SetFailed(const std::exception_ptr &exception)
Set the unit into failed state, with the given exception.
Definition recordingUnit.cpp:142
std::string GetId()
Get the unit_it of this RecordingUnit.
Definition recordingUnit.cpp:120
std::string m_unit_id
Definition recordingUnit.hpp:171
void ResetLeaderStates()
Definition recordingUnit.cpp:111
ComponentMetricsIf & m_metrics
Definition recordingUnit.hpp:174
RuntimeRepoIf & m_rtr
Definition recordingUnit.hpp:172
void SetStopped()
Set the Unit state to STOPPED independent of the current State.
Definition recordingUnit.cpp:149
State GetState()
Get the current state of the Recording Unit.
Definition recordingUnit.cpp:154
bool SetState(State state, State precondition)
Sets the new state, only goes to new state, if expected state matches.
Definition recordingUnit.cpp:124
std::optional< std::filesystem::path > m_file_path
Definition recordingUnit.hpp:175
T GetDataPoint(const DataPointPath &path) const
Fetches a datapoint from the repository.
Definition repositoryIf.ipp:1711
void CreateDataPoint(const DataPointPath &path)
Creates a new datapoint in the repository.
Definition repositoryIf.ipp:1696
void SetDataPoint(const DataPointPath &path, const T &value)
Sets a datapoint in the repository.
Definition repositoryIf.ipp:1720
Container class that holds services of any type.
Definition serviceContainer.hpp:39
Recording Unit that can record typed events.
Definition eventRecordingUnit.hpp:485
std::function< bool(const EventType &)> FilterMethod
Definition eventRecordingUnit.hpp:487
std::vector< std::filesystem::path > Stop() override
Stop the recording and wait for it's termination.
Definition eventRecordingUnit.hpp:546
TypedEventRecordingUnit(const std::string &comp_id, const std::string &unit_id, ServiceContainer &services, FilterMethod input_filter=nullptr)
Create a new recording unit.
Definition eventRecordingUnit.hpp:496
virtual ~TypedEventRecordingUnit()
Definition eventRecordingUnit.hpp:514
void Prepare(const std::filesystem::path &file_path) override
Prepare the recording.
Definition eventRecordingUnit.hpp:526
void Start() override
Start the recording.
Definition eventRecordingUnit.hpp:539
Header file for ComponentMetricsIf.
CSVDataRecorder allows to record as CSV files .
Framework-provided event definitions.
Low-level interface of the event service.
Provides macros and utilities for exception handling.
FitsRecorder allows to write ColumnData to into fits files in a specified directory.
Definition commandReplier.cpp:22
nlohmann::json JsonPayload
Type requirements:
Definition jsonPayload.hpp:25
elt::mal::future< std::string > InjectReqRepEvent(StateMachineEngine &engine)
Definition malEventInjector.hpp:23
FitsRecorder allows to write ColumnData to into fits files in a specified directory.
Abstract base class defining functionality common to all recording units.
TimeString time
Definition eventDefinitions.hpp:94
std::string origin
Definition eventDefinitions.hpp:93
Event published when alert status is changed.
Definition eventDefinitions.hpp:553
bool status
Reduced alert status.
Definition eventDefinitions.hpp:595
std::vector< Alert > active_alerts
List of active alerts.
Definition eventDefinitions.hpp:600
Abstract Event Type that is used as a base for computation events.
Definition eventDefinitions.hpp:111
std::string item
Definition eventDefinitions.hpp:126
std::string state
Definition eventDefinitions.hpp:127
Event Type used to signal that a computation has finished.
Definition eventDefinitions.hpp:164
JsonPayload result
Definition eventDefinitions.hpp:177
Event Type used to signal that a computation has started.
Definition eventDefinitions.hpp:141
Abstract Event Type that is used as a base for configuration events.
Definition eventDefinitions.hpp:191
std::string state
Definition eventDefinitions.hpp:257
ItemList items
Definition eventDefinitions.hpp:256
Event Type used to signal that configuration data items were retrieved from RTR.
Definition eventDefinitions.hpp:312
Event Type used to signal that configuration data items were updated in RTR.
Definition eventDefinitions.hpp:271
Abstract Event Type that is used as a base for coordination events.
Definition eventDefinitions.hpp:464
Event Type used to signal that configuration data items were applied in HRTC.
Definition eventDefinitions.hpp:409
uint64_t hrtc_sample_id
Definition eventDefinitions.hpp:450
TimeString hrtc_timestamp
Definition eventDefinitions.hpp:449
std::string hrtc_origin
Definition eventDefinitions.hpp:448
Event Type used to signal that configuration data items were scheduled to be applied in HRTC.
Definition eventDefinitions.hpp:354
uint64_t hrtc_sample_id
Definition eventDefinitions.hpp:395
TimeString hrtc_timestamp
Definition eventDefinitions.hpp:394
std::string hrtc_origin
Definition eventDefinitions.hpp:393
Event Type used to signal that some entity in HRTC changed its state.
Definition eventDefinitions.hpp:519
TimeString hrtc_timestamp
Definition eventDefinitions.hpp:534
uint64_t hrtc_sample_id
Definition eventDefinitions.hpp:535
std::string_view sv
Definition eventRecordingUnit.hpp:446
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:461
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:62
std::string_view sv
Definition eventRecordingUnit.hpp:47
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:92
std::string_view sv
Definition eventRecordingUnit.hpp:77
std::string_view sv
Definition eventRecordingUnit.hpp:107
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:118
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:148
std::string_view sv
Definition eventRecordingUnit.hpp:133
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:226
std::string_view sv
Definition eventRecordingUnit.hpp:211
std::string_view sv
Definition eventRecordingUnit.hpp:172
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:187
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:361
std::string_view sv
Definition eventRecordingUnit.hpp:354
std::string_view sv
Definition eventRecordingUnit.hpp:302
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:323
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:271
std::string_view sv
Definition eventRecordingUnit.hpp:250
std::string_view sv
Definition eventRecordingUnit.hpp:406
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:425
std::string_view sv
Definition eventRecordingUnit.hpp:376
static Recorder::TupleType AsTuple(const DataType &data)
Definition eventRecordingUnit.hpp:391
Definition recordingInfo.hpp:23
Event Type used to signal that some entity changed its state.
Definition eventDefinitions.hpp:489
std::string entity
Definition eventDefinitions.hpp:504
std::string state
Definition eventDefinitions.hpp:505
High-level API of the event service.