Line data Source code
1 : #ifndef artdaq_DAQrate_detail_RoutingPacket_hh
2 : #define artdaq_DAQrate_detail_RoutingPacket_hh
3 :
4 : #include "TRACE/tracemf.h" // Pre-empt TRACE/trace.h from Fragment.hh.
5 : #include "artdaq-core/Data/Fragment.hh"
6 :
7 : #include <string>
8 : #include <vector>
9 :
10 : namespace artdaq {
11 : namespace detail {
12 : struct RoutingPacketEntry;
13 : /**
14 : * \brief A RoutingPacket is simply a vector of RoutingPacketEntry objects.
15 : * It is not suitable for network transmission, rather a RoutingPacketHeader
16 : * should be sent, followed by &RoutingPacket.at(0) (the physical storage of the vector)
17 : */
18 : using RoutingPacket = std::vector<RoutingPacketEntry>;
19 : struct RoutingPacketHeader;
20 : struct RoutingConnectHeader;
21 : struct RoutingRequest;
22 : struct RoutingToken;
23 :
24 : /**
25 : * \brief Mode indicating whether the RoutingManager is routing events by Sequence ID or by Send Count
26 : */
27 : enum class RoutingManagerMode : uint8_t
28 : {
29 : EventBuilding, ///< Multiple sources sending to a single destination. RoutingManager pushes table updates to all senders
30 : RequestBasedEventBuilding, ///< Multiple sources sending to a single destination. Table updates are triggered by senders requesting routing information
31 : DataFlow, ///< One source sending to one destination (i.e. moving around completed events). Uses request-based routing
32 : INVALID
33 : };
34 : /**
35 : * @brief Convert RoutingManagerMode to/from strings
36 : */
37 : class RoutingManagerModeConverter
38 : {
39 : public:
40 : /**
41 : * @brief Convert String to RoutingManagerMode
42 : * @param modeString String to convert
43 : * @return Resultant RoutingManagerMode, RoutingManagerMode::INVALID if no match
44 : */
45 21 : static RoutingManagerMode stringToRoutingManagerMode(std::string const& modeString)
46 : {
47 21 : if (modeString == "EventBuilding" || modeString == "eventbuilding") return RoutingManagerMode::EventBuilding;
48 8 : if (modeString == "RequestBasedEventBuilding" || modeString == "requestbasedeventbuilding" || modeString == "RequestBased" || modeString == "requestbased") return RoutingManagerMode::RequestBasedEventBuilding;
49 4 : if (modeString == "DataFlow" || modeString == "dataflow") return RoutingManagerMode::DataFlow;
50 0 : return RoutingManagerMode::INVALID;
51 : }
52 : /**
53 : * @brief Convert RoutingManagerMode to string
54 : * @param mode Mode to convert
55 : * @return String representation of mode
56 : */
57 : static std::string routingManagerModeToString(RoutingManagerMode mode)
58 : {
59 : switch (mode)
60 : {
61 : case RoutingManagerMode::EventBuilding:
62 : return "EventBuilding";
63 : case RoutingManagerMode::RequestBasedEventBuilding:
64 : return "RequestBasedEventBuilding";
65 : case RoutingManagerMode::DataFlow:
66 : return "DataFlow";
67 : case RoutingManagerMode::INVALID:
68 : return "INVALID";
69 : }
70 : return "Unknown Mode";
71 : }
72 : };
73 : } // namespace detail
74 : } // namespace artdaq
75 : /**
76 : * \brief A row of the Routing Table
77 : */
78 : struct artdaq::detail::RoutingPacketEntry
79 : {
80 : /**
81 : * \brief Default Constructor
82 : */
83 0 : RoutingPacketEntry() {}
84 : /**
85 : * \brief Construct a RoutingPacketEntry with the given sequence ID and destination rank
86 : * \param seq The sequence ID of the RoutingPacketEntry
87 : * \param rank The destination rank for this sequence ID
88 : */
89 44 : RoutingPacketEntry(Fragment::sequence_id_t seq, int rank)
90 44 : : sequence_id(seq), destination_rank(rank) {}
91 :
92 : Fragment::sequence_id_t sequence_id{Fragment::InvalidSequenceID}; ///< The sequence ID of the RoutingPacketEntry
93 : int32_t destination_rank{-1}; ///< The destination rank for this sequence ID
94 : };
95 :
96 : /**
97 : * \brief Magic bytes expected in every RoutingPacketHeader
98 : */
99 : #define ROUTING_MAGIC 0x1337beef
100 :
101 : /**
102 : * \brief The header of the Routing Table, containing the magic bytes and the number of entries
103 : */
104 : struct artdaq::detail::RoutingPacketHeader
105 : {
106 : uint32_t header{0}; ///< Magic bytes to make sure the packet wasn't garbled
107 : uint64_t nEntries{0}; ///< The number of RoutingPacketEntries in the RoutingPacket
108 :
109 : /**
110 : * \brief Construct a RoutingPacketHeader declaring a given number of entries
111 : * \param n The number of RoutingPacketEntries in the associated RoutingPacket
112 : */
113 0 : explicit RoutingPacketHeader(size_t n)
114 0 : : header(ROUTING_MAGIC), nEntries(n) {}
115 : /**
116 : * \brief Default Constructor
117 : */
118 0 : RoutingPacketHeader() {}
119 : };
120 :
121 : /**
122 : * @brief Represents a request sent to the RoutingManager for routing information
123 : */
124 : struct artdaq::detail::RoutingRequest
125 : {
126 : /**
127 : * @brief The mode of this request, whether Request or Connect/Disconnect control messages
128 : */
129 : enum class RequestMode : uint8_t
130 : {
131 : Connect = 0,
132 : Disconnect = 1,
133 : Request = 2,
134 : Invalid = 255,
135 : };
136 :
137 : /**
138 : * @brief Convert a RequestMode enumeration value to string
139 : * @param m RequestMode to convert
140 : * @return String representation of RequestMode
141 : */
142 0 : static std::string RequestModeToString(RequestMode m)
143 : {
144 0 : switch (m)
145 : {
146 0 : case RequestMode::Connect:
147 0 : return "Connect";
148 0 : case RequestMode::Disconnect:
149 0 : return "Disconnect";
150 0 : case RequestMode::Request:
151 0 : return "Request";
152 0 : case RequestMode::Invalid:
153 0 : return "Invalid";
154 : }
155 0 : return "UNKNOWN";
156 : }
157 :
158 : uint32_t header{0}; ///< Magic bytes for identifying message type on wire
159 : int32_t rank{-1}; ///< The rank of the request sender
160 : Fragment::sequence_id_t sequence_id{artdaq::Fragment::InvalidSequenceID}; ///< The sequence ID being requested in Request mode
161 : RequestMode mode{RequestMode::Invalid}; ///< Mode of the request
162 :
163 : /**
164 : * @brief Create a request using the given rank and mode
165 : * @param r Rank of the requestor
166 : * @param m Mode of this request
167 : *
168 : * This constructor is primarily used to sed RequestMode::Connect and RequestMode::Disconnect control messages
169 : */
170 0 : RoutingRequest(int r, RequestMode m = RequestMode::Connect)
171 0 : : header(ROUTING_MAGIC), rank(r), mode(m) {}
172 :
173 : /**
174 : * @brief Create a RoutingRequest using the given rank and sequence ID
175 : * @param r Rank of the requestor
176 : * @param seq Sequence ID of request
177 : */
178 0 : RoutingRequest(int r, Fragment::sequence_id_t seq)
179 0 : : header(ROUTING_MAGIC), rank(r), sequence_id(seq), mode(RequestMode::Request) {}
180 :
181 0 : RoutingRequest() {} ///< Default constructor
182 : };
183 :
184 : /**
185 : * \brief Magic bytes expected in every RoutingToken
186 : */
187 : #define TOKEN_MAGIC 0xbeefcafe
188 :
189 : /**
190 : * \brief The RoutingToken contains the magic bytes, the rank of the token sender, and the number of slots free. This is
191 : * a TCP message, so additional verification is not necessary.
192 : */
193 : struct artdaq::detail::RoutingToken
194 : {
195 : uint32_t header; ///< The magic bytes that help validate the RoutingToken
196 : int rank; ///< The rank from which the RoutingToken came
197 : unsigned new_slots_free; ///< The number of slots free in the token sender (usually 1)
198 : unsigned run_number; ///< The Run with which this token should be associated
199 : };
200 :
201 : #endif // artdaq_Application_Routing_RoutingPacket_hh
|