A simplified API for passing messages between DAQModules
Sender
/Receiver
instances using ConnectionRef
s or uid
(defined below)Queue
s and NetworkManager
automatically in configure
dunedaq::get_iomanager()
will return a pointer to the IOManager singletonIOManager::get_sender<DataType>(std::string uid)
and IOManager::get_receiver<DataType>(std::string uid)
should be used to get Sender and Receiver objects connected to the appropriate connections. Note that ConnectionId
objects are not required, as they will be constructed from the provided DataType and uid arguments.".*"
) to a specific connection UID, depending on the desired scope of the subscription. Topics are now automatically assigned by IOManager as the string representation of DataType.topic
argument has been removed from SenderConcept<T>::send
appfwk
will give DAQModules a list of appfwk::app::ConnectionReference
objects, which associate a "name" to connection UIDs. Methods in DAQModuleHelper.hpp
take DAQModule configuration objects and extract specific UIDs for given names.
auto mandatory_connections =
appfwk::connection_index(init_data, { "token_connection", "td_connection", "busy_connection" });
m_token_connection = mandatory_connections["token_connection"];
m_td_connection = mandatory_connections["td_connection"];
auto busy_connection = mandatory_connections["busy_connection"];
m_busy_sender = iom->get_sender<dfmessages::TriggerInhibit>(busy_connection);
serialization
library provides a new macro DUNE_DAQ_TYPESTRING(Type, string)
which is included in the standard DUNE_DAQ_SERIALIZABLE
and DUNE_DAQ_SERIALIZE_NON_INTRUSIVE
macros (called from the dunedaq
namespace only). These macros define the function datatype_to_string<T>
which is used by IOManager to translate a datatype to the appropriate string. This template function must be visible in every compilation unit sending or receiving a given type!
daqconf
, all connections and queues must have a declared data type that matches a call to DUNE_DAQ_TYPESTRING
. add_endpoint
and connect_modules
have changed their API to accomodate this.ConnectionId
uniquely identifies a network connection or queue
uid
: String identifier for connectiondata_type
: String representation of data typeConnection
defines a network connection, with required initialization
id
: ConnectionId
connection_type
: Describes what kind of connection (kSendReceive, kPubSub)uri
: Field is used by lower-level code to configure the connectiontcp://localhost:1234
(name translation is provided by IPM)QueueConfig
represents an app-internal queue
id
: ConectionId
queue_type
: Type of the queue implementation (e.g. kStdDeQueue, kFollySPSCQueue, kFollyMPMCQueue)capacity
: Capacity of the queueReceiver
is base type without template (for use in IOManager::m_receiver
s)ReceiverConcept
introduces template and serves as class given by IOManager::get_receiver
QueueReceiverModel
and NetworkReceiverModel
implement receives and callback loop for queues and network
NetworkReceiverModel::read_network
determines if type is serializable using template metaprogrammingReceiver
sQueueSenderModel
and NetworkSenderModel
implement sends for queues and networkNetworkReceiverModel::write_network
determines if type is serializable using template metaprogramming // Int sender
std::string uid = "bar";
int msg = 5;
std::chrono::milliseconds timeout(100);
auto isender = IOManager::get()->get_sender<int>(uid);
isender->send(msg, timeout);
isender->send(msg, timeout);
// One line send
IOManager::get()->get_sender<int>(uid)->send(msg, timeout);
// Send when timeouts may occur
bool sent = isender->try_send(msg, timeout);
// String receiver
std::string uid = "bar";
auto receiver = IOManager::get()->get_receiver<std::string>(uid);
std::string got;
try {
got = receiver->receive(timeout);
} catch (dunedaq::appfwk::QueueTimeoutExpired&) {
// Deal with exception
}
// Alternate API for when timeouts may be allowed
std::optional<std::string> ret = receiver->try_receive(timeout);
if(ret) TLOG() << "Received " << *ret;
// Callback receiver
std::string uid = "zyx";
// CB function
std::function<void(std::string)> str_receiver_cb = [&](std::string data) {
std::cout << "Str receiver callback called with data: " << data << '\n';
};
auto cbrec = IOManager::get()->get_receiver<std::string>(uid);
cbrec->add_callback(str_receiver_cb);
try {
got = cbrec->receive(timeout);
} catch (dunedaq::iomanager::ReceiveCallbackConflict&) {
// This is expected
}
IOManager::get()->remove_callback(uid);
The standard send()
and receive()
methods will throw an ERS exception if they time out. This is ideal for cases where timeouts are an exceptional condition (this applies to most, if not all send calls, for example). In cases where the timeout condition can be safely ignored (such as the callback-driving methods which are retrying the receive in a tight loop), the try_send
and try_receive
methods may be used. Note that these methods are not noexcept
, any non-timeout issues will result in an ERS exception.
Please see this page for information about updating your code to use IOManager. Also, if you are interested in using dynamic connection names, look at this page
The API used for queues is documented here. Network connections use IPM and NetworkManager