9 #ifndef FAIR_MQ_PLUGINS_DDS 10 #define FAIR_MQ_PLUGINS_DDS 12 #include <fairmq/Plugin.h> 13 #include <fairmq/StateQueue.h> 14 #include <fairmq/Version.h> 15 #include <fairmq/sdk/commands/Commands.h> 19 #include <boost/asio/executor.hpp> 20 #include <boost/asio/executor_work_guard.hpp> 21 #include <boost/asio/io_context.hpp> 25 #include <condition_variable> 31 #include <unordered_map> 45 unsigned int fNumSubChannels;
47 std::map<uint64_t, std::string> fDDSValues;
53 : fDDSCustomCmd(fService)
54 , fDDSKeyValue(fService)
56 LOG(debug) <<
"$DDS_TASK_PATH: " << dds::env_prop<dds::task_path>();
57 LOG(debug) <<
"$DDS_GROUP_NAME: " << dds::env_prop<dds::group_name>();
58 LOG(debug) <<
"$DDS_COLLECTION_NAME: " << dds::env_prop<dds::collection_name>();
59 LOG(debug) <<
"$DDS_TASK_NAME: " << dds::env_prop<dds::task_name>();
60 LOG(debug) <<
"$DDS_TASK_INDEX: " << dds::env_prop<dds::task_index>();
61 LOG(debug) <<
"$DDS_COLLECTION_INDEX: " << dds::env_prop<dds::collection_index>();
62 LOG(debug) <<
"$DDS_TASK_ID: " << dds::env_prop<dds::task_id>();
63 LOG(debug) <<
"$DDS_LOCATION: " << dds::env_prop<dds::dds_location>();
64 std::string dds_session_id(dds::env_prop<dds::dds_session_id>());
65 LOG(debug) <<
"$DDS_SESSION_ID: " << dds_session_id;
68 fService.subscribeOnError([](
const dds::intercom_api::EErrorCode errorCode,
const std::string& errorMsg) {
69 LOG(error) <<
"DDS Error received: error code: " << errorCode <<
", error message: " << errorMsg;
75 assert(!dds_session_id.empty());
78 auto Start() ->
void {
79 fService.start(dds::env_prop<dds::dds_session_id>());
83 fDDSKeyValue.unsubscribe();
84 fDDSCustomCmd.unsubscribe();
87 template<
typename... Args>
88 auto SubscribeCustomCmd(Args&&... args) ->
void 90 fDDSCustomCmd.subscribe(std::forward<Args>(args)...);
93 template<
typename... Args>
94 auto SubscribeKeyValue(Args&&... args) ->
void 96 fDDSKeyValue.subscribe(std::forward<Args>(args)...);
99 template<
typename... Args>
100 auto Send(Args&&... args) ->
void 102 fDDSCustomCmd.send(std::forward<Args>(args)...);
105 template<
typename... Args>
106 auto PutValue(Args&&... args) ->
void 108 fDDSKeyValue.putValue(std::forward<Args>(args)...);
112 dds::intercom_api::CIntercomService fService;
113 dds::intercom_api::CCustomCmd fDDSCustomCmd;
114 dds::intercom_api::CKeyValue fDDSKeyValue;
126 std::vector<std::string> fEntries;
137 auto WaitForExitingAck() -> void;
138 auto StartWorkerThread() -> void;
140 auto FillChannelContainers() -> void;
141 auto EmptyChannelContainers() -> void;
143 auto SubscribeForConnectingChannels() -> void;
144 auto PublishBoundChannels() -> void;
145 auto SubscribeForCustomCommands() -> void;
146 auto HandleCmd(
const std::string&
id,
sdk::cmd::Cmd& cmd,
const std::string& cond, uint64_t senderId) -> void;
151 std::unordered_map<std::string, std::vector<std::string>> fBindingChans;
152 std::unordered_map<std::string, DDSConfig> fConnectingChans;
154 std::unordered_map<std::string, int> fI;
155 std::unordered_map<std::string, IofN> fIofN;
157 std::thread fControllerThread;
158 DeviceState fCurrentState, fLastState;
160 std::atomic<bool> fDeviceTerminationRequested;
162 std::unordered_map<uint64_t, std::pair<std::chrono::steady_clock::time_point, int64_t>> fStateChangeSubscribers;
163 uint64_t fLastExternalController;
164 bool fExitingAckedByLastExternalController;
165 std::condition_variable fExitingAcked;
166 std::mutex fStateChangeSubscriberMutex;
168 bool fUpdatesAllowed;
169 std::mutex fUpdateMutex;
170 std::condition_variable fUpdateCondition;
172 std::thread fWorkerThread;
173 boost::asio::io_context fWorkerQueue;
174 boost::asio::executor_work_guard<boost::asio::executor> fWorkGuard;
177 Plugin::ProgOptions DDSProgramOptions()
179 boost::program_options::options_description options{
"DDS Plugin"};
180 options.add_options()
181 (
"dds-i", boost::program_options::value<std::vector<std::string>>()->multitoken()->composing(),
"Task index for chosing connection target (single channel n to m). When all values come via same update.")
182 (
"dds-i-n", boost::program_options::value<std::vector<std::string>>()->multitoken()->composing(),
"Task index for chosing connection target (one out of n values to take). When values come as independent updates.")
183 (
"wait-for-exiting-ack-timeout", boost::program_options::value<unsigned int>()->default_value(1000),
"Wait timeout for EXITING state-change acknowledgement by external controller in milliseconds.");
188 REGISTER_FAIRMQ_PLUGIN(
192 FAIRMQ_VERSION_MINOR,
193 FAIRMQ_VERSION_PATCH}),
194 "FairRootGroup <fairroot@gsi.de>",
195 "https://github.com/FairRootGroup/FairMQ",
Facilitates communication between devices and plugins.
Definition: PluginServices.h:40
Base class for FairMQ plugins.
Definition: Plugin.h:39
Definition: Commands.h:62
Tools for interfacing containers to the transport via polymorphic allocators.
Definition: DeviceRunner.h:23