Line data Source code
1 : /**
2 : * @file ReversedListValidator.hpp
3 : *
4 : * ReversedListValidator is a DAQModule implementation that reads lists
5 : * of integers from two queues and verifies that the order of the elements
6 : * in the lists from the first queue are opposite from the order of the
7 : * elements in the lists from the second queue.
8 : *
9 : * This is part of the DUNE DAQ Software Suite, copyright 2020.
10 : * Licensing/copyright details are in the COPYING file that you should have
11 : * received with this code.
12 : */
13 :
14 : #ifndef LISTREV_PLUGINS_REVERSEDLISTVALIDATOR_HPP_
15 : #define LISTREV_PLUGINS_REVERSEDLISTVALIDATOR_HPP_
16 :
17 : #include "ListCreator.hpp"
18 : #include "ListStorage.hpp"
19 : #include "ListWrapper.hpp"
20 :
21 : #include "appfwk/DAQModule.hpp"
22 : #include "iomanager/Receiver.hpp"
23 : #include "iomanager/Sender.hpp"
24 : #include "utilities/WorkerThread.hpp"
25 :
26 : #include "ers/Issue.hpp"
27 : #include "logging/Logging.hpp" // NOTE: if ISSUES ARE DECLARED BEFORE include logging/Logging.hpp, TLOG_DEBUG<<issue wont work.
28 :
29 : #include <map>
30 : #include <memory>
31 : #include <string>
32 : #include <vector>
33 :
34 : namespace dunedaq {
35 : namespace listrev {
36 :
37 : /**
38 : * @brief ReversedListValidator reads lists of integers from two queues
39 : * and verifies that the lists have the same data, but stored in reverse order.
40 : */
41 : class ReversedListValidator : public dunedaq::appfwk::DAQModule
42 : {
43 : public:
44 : /**
45 : * @brief ReversedListValidator Constructor
46 : * @param name Instance name for this ReversedListValidator instance
47 : */
48 : explicit ReversedListValidator(const std::string& name);
49 :
50 : ReversedListValidator(const ReversedListValidator&) = delete; ///< ReversedListValidator is not copy-constructible
51 : ReversedListValidator& operator=(const ReversedListValidator&) =
52 : delete; ///< ReversedListValidator is not copy-assignable
53 : ReversedListValidator(ReversedListValidator&&) = delete; ///< ReversedListValidator is not move-constructible
54 : ReversedListValidator& operator=(ReversedListValidator&&) = delete; ///< ReversedListValidator is not move-assignable
55 :
56 : void init(std::shared_ptr<appfwk::ConfigurationManager> mcfg) override;
57 :
58 : protected:
59 : void generate_opmon_data() override;
60 :
61 : private:
62 : // Commands
63 : void do_start(const CommandData_t& obj);
64 : void do_stop(const CommandData_t& obj);
65 :
66 : // Threading
67 : dunedaq::utilities::WorkerThread m_work_thread;
68 : void do_work(std::atomic<bool>&);
69 :
70 : // Callbacks
71 : void process_list(const ReversedList& list);
72 :
73 : // Methods
74 : void send_request(int id);
75 :
76 : // Data
77 : struct OutstandingList
78 : {
79 : std::chrono::steady_clock::time_point time;
80 : size_t size{ 0 };
81 :
82 37 : OutstandingList() = default;
83 37 : explicit OutstandingList(size_t sz)
84 37 : : time(std::chrono::steady_clock::now())
85 37 : , size(sz)
86 : {
87 37 : }
88 : };
89 : std::map<int, OutstandingList> m_outstanding_ids;
90 : int m_next_id{ 0 };
91 : std::chrono::steady_clock::time_point m_request_start;
92 : mutable std::mutex m_outstanding_id_mutex;
93 : ListCreator m_list_creator;
94 :
95 : // Init
96 : std::string m_list_connection;
97 : std::string m_create_connection;
98 :
99 : // Configuration
100 : std::chrono::milliseconds m_send_timeout{ 100 };
101 : std::chrono::milliseconds m_request_timeout{ 1000 };
102 : size_t m_max_outstanding_requests{ 100 };
103 : size_t m_num_generators{ 0 };
104 : size_t m_num_reversers{ 0 };
105 : size_t m_request_rate_hz{ 100 };
106 :
107 : std::vector<uint32_t> m_generatorIds; // NOLINT(build/unsigned)
108 : std::vector<std::string> m_reveserIds;
109 :
110 : // Monitoring
111 : std::atomic<uint64_t> m_requests_total{ 0 }; // NOLINT(build/unsigned)
112 : std::atomic<uint64_t> m_new_requests{ 0 }; // NOLINT(build/unsigned)
113 : std::atomic<uint64_t> m_total_lists{ 0 }; // NOLINT(build/unsigned)
114 : std::atomic<uint64_t> m_new_lists{ 0 }; // NOLINT(build/unsigned)
115 : std::atomic<uint64_t> m_total_reversed{ 0 }; // NOLINT(build/unsigned)
116 : std::atomic<uint64_t> m_new_reversed{ 0 }; // NOLINT(build/unsigned)
117 : std::atomic<uint64_t> m_total_valid_pairs{ 0 }; // NOLINT(build/unsigned)
118 : std::atomic<uint64_t> m_valid_list_pairs{ 0 }; // NOLINT(build/unsigned)
119 : std::atomic<uint64_t> m_total_invalid_pairs{ 0 }; // NOLINT(build/unsigned)
120 : std::atomic<uint64_t> m_invalid_list_pairs{ 0 }; // NOLINT(build/unsigned)
121 : };
122 : } // namespace listrev
123 :
124 : // Disable coverage collection LCOV_EXCL_START
125 : ERS_DECLARE_ISSUE_BASE(listrev,
126 : MissingListError,
127 : appfwk::GeneralDAQModuleIssue,
128 : "Missing lists detected, for list set " << id << " expected " << n_gen
129 : << " lists, but received only " << n_lists,
130 : ((std::string)name),
131 : ((int)id)((int)n_gen)((int)n_lists)) // NOLINT(readability/casting)
132 :
133 : ERS_DECLARE_ISSUE_BASE(listrev,
134 : ListSizeError,
135 : appfwk::GeneralDAQModuleIssue,
136 : "List size error when validating list" << id << ": Expected " << expected_size << " entries"
137 : << ", original list is " << original_size << " entries"
138 : << ", and reversed list is " << reversed_size
139 : << " entries.", ((std::string)name),
140 : ((int)id)((int)expected_size)((int)original_size)((int)reversed_size)) // NOLINT(readability/casting)
141 :
142 : ERS_DECLARE_ISSUE_BASE(listrev,
143 : DataMismatchError,
144 : appfwk::GeneralDAQModuleIssue,
145 : "Data mismatch when validating list" << id << ": doubly-reversed list contents = " << revContents
146 : << ", original list contents = " << origContents,
147 : ((std::string)name),
148 : ((int)id)((std::string)revContents)((std::string)origContents)) // NOLINT(readability/casting)
149 : // Re-enable coverage collection LCOV_EXCL_STOP
150 :
151 : } // namespace dunedaq
152 :
153 : #endif // LISTREV_PLUGINS_REVERSEDLISTVALIDATOR_HPP_
154 :
155 : // Local Variables:
156 : // c-basic-offset: 2
157 : // End:
|