9 #ifndef FAIRMQDEVICE_H_ 10 #define FAIRMQDEVICE_H_ 12 #include <FairMQStateMachine.h> 13 #include <FairMQTransportFactory.h> 14 #include <fairmq/Transports.h> 16 #include <FairMQSocket.h> 17 #include <FairMQChannel.h> 18 #include <FairMQMessage.h> 19 #include <FairMQParts.h> 20 #include <FairMQUnmanagedRegion.h> 21 #include <FairMQLogger.h> 22 #include <options/FairMQProgOptions.h> 29 #include <unordered_map> 32 #include <type_traits> 35 #include <condition_variable> 37 #include <fairmq/Tools.h> 39 using FairMQChannelMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
41 using InputMsgCallback = std::function<bool(FairMQMessagePtr&, int)>;
42 using InputMultipartCallback = std::function<bool(FairMQParts&, int)>;
70 void SortChannel(
const std::string& name,
const bool reindex =
true);
76 template<
typename Serializer,
typename DataType,
typename... Args>
77 void Serialize(
FairMQMessage& msg, DataType&& data, Args&&... args)
const 79 Serializer().Serialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
82 template<
typename Deserializer,
typename DataType,
typename... Args>
83 void Deserialize(
FairMQMessage& msg, DataType&& data, Args&&... args)
const 85 Deserializer().Deserialize(msg, std::forward<DataType>(data), std::forward<Args>(args)...);
88 int Send(FairMQMessagePtr& msg,
const std::string& chan,
const int i = 0)
const 90 return fChannels.at(chan).at(i).Send(msg);
93 int Receive(FairMQMessagePtr& msg,
const std::string& chan,
const int i = 0)
const 95 return fChannels.at(chan).at(i).Receive(msg);
104 int Send(FairMQMessagePtr& msg,
const std::string& chan,
const int i,
int sndTimeoutInMs)
const 106 return fChannels.at(chan).at(i).Send(msg, sndTimeoutInMs);
115 int Receive(FairMQMessagePtr& msg,
const std::string& chan,
const int i,
int rcvTimeoutInMs)
const 117 return fChannels.at(chan).at(i).Receive(msg, rcvTimeoutInMs);
126 int SendAsync(FairMQMessagePtr& msg,
const std::string& chan,
const int i = 0)
const 128 return fChannels.at(chan).at(i).SendAsync(msg);
137 int ReceiveAsync(FairMQMessagePtr& msg,
const std::string& chan,
const int i = 0)
const 139 return fChannels.at(chan).at(i).ReceiveAsync(msg);
142 int64_t Send(
FairMQParts& parts,
const std::string& chan,
const int i = 0)
const 144 return fChannels.at(chan).at(i).Send(parts.fParts);
147 int64_t Receive(
FairMQParts& parts,
const std::string& chan,
const int i = 0)
const 149 return fChannels.at(chan).at(i).Receive(parts.fParts);
158 int64_t
Send(
FairMQParts& parts,
const std::string& chan,
const int i,
int sndTimeoutInMs)
const 160 return fChannels.at(chan).at(i).Send(parts.fParts, sndTimeoutInMs);
171 return fChannels.at(chan).at(i).Receive(parts.fParts, rcvTimeoutInMs);
182 return fChannels.at(chan).at(i).SendAsync(parts.fParts);
193 return fChannels.at(chan).at(i).ReceiveAsync(parts.fParts);
202 template<
typename... Args>
203 FairMQMessagePtr NewMessage(Args&&... args)
const 205 return Transport()->CreateMessage(std::forward<Args>(args)...);
208 template<
typename... Args>
209 FairMQMessagePtr NewMessageFor(
const std::string& channel,
int index, Args&&... args)
const 211 return fChannels.at(channel).at(index).Transport()->CreateMessage(std::forward<Args>(args)...);
215 FairMQMessagePtr NewStaticMessage(
const T& data)
const 217 return Transport()->NewStaticMessage(data);
221 FairMQMessagePtr NewStaticMessageFor(
const std::string& channel,
int index,
const T& data)
const 223 return fChannels.at(channel).at(index).NewStaticMessage(data);
227 FairMQMessagePtr NewSimpleMessage(
const T& data)
const 229 return Transport()->NewSimpleMessage(data);
233 FairMQMessagePtr NewSimpleMessageFor(
const std::string& channel,
int index,
const T& data)
const 235 return fChannels.at(channel).at(index).NewSimpleMessage(data);
238 FairMQUnmanagedRegionPtr NewUnmanagedRegion(
const size_t size)
240 return Transport()->CreateUnmanagedRegion(size);
243 FairMQUnmanagedRegionPtr NewUnmanagedRegionFor(
const std::string& channel,
int index,
const size_t size, FairMQRegionCallback callback =
nullptr)
245 return fChannels.at(channel).at(index).Transport()->CreateUnmanagedRegion(size, callback);
248 template<
typename ...Ts>
249 FairMQPollerPtr NewPoller(
const Ts&... inputs)
251 std::vector<std::string> chans{inputs...};
254 if (chans.size() > 1)
256 fair::mq::Transport type =
fChannels.at(chans.at(0)).at(0).Transport()->GetType();
258 for (
unsigned int i = 1; i < chans.size(); ++i)
260 if (type !=
fChannels.at(chans.at(i)).at(0).Transport()->GetType())
262 LOG(error) <<
"poller failed: different transports within same poller are not yet supported. Going to ERROR state.";
263 ChangeState(ERROR_FOUND);
271 FairMQPollerPtr NewPoller(
const std::vector<const FairMQChannel*>& channels)
274 if (channels.size() > 1)
276 fair::mq::Transport type = channels.at(0)->Transport()->GetType();
278 for (
unsigned int i = 1; i < channels.size(); ++i)
280 if (type != channels.at(i)->Transport()->GetType())
282 LOG(error) <<
"poller failed: different transports within same poller are not yet supported. Going to ERROR state.";
283 ChangeState(ERROR_FOUND);
288 return channels.at(0)->Transport()->CreatePoller(channels);
296 std::shared_ptr<FairMQTransportFactory>
AddTransport(
const fair::mq::Transport transport);
299 void SetTransport(
const std::string& transport =
"zeromq");
313 void OnData(
const std::string& channelName,
bool (T::* memberFunction)(FairMQMessagePtr& msg,
int index))
315 fDataCallbacks =
true;
316 fMsgInputs.insert(std::make_pair(channelName, [
this, memberFunction](FairMQMessagePtr& msg,
int index)
318 return (static_cast<T*>(
this)->*memberFunction)(msg, index);
321 if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
323 fInputChannelKeys.push_back(channelName);
327 void OnData(
const std::string& channelName, InputMsgCallback callback)
329 fDataCallbacks =
true;
330 fMsgInputs.insert(make_pair(channelName, callback));
332 if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
334 fInputChannelKeys.push_back(channelName);
339 void OnData(
const std::string& channelName,
bool (T::* memberFunction)(
FairMQParts& parts,
int index))
341 fDataCallbacks =
true;
342 fMultipartInputs.insert(std::make_pair(channelName, [
this, memberFunction](
FairMQParts& parts,
int index)
344 return (static_cast<T*>(
this)->*memberFunction)(parts, index);
347 if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
349 fInputChannelKeys.push_back(channelName);
353 void OnData(
const std::string& channelName, InputMultipartCallback callback)
355 fDataCallbacks =
true;
356 fMultipartInputs.insert(make_pair(channelName, callback));
358 if (find(fInputChannelKeys.begin(), fInputChannelKeys.end(), channelName) == fInputChannelKeys.end())
360 fInputChannelKeys.push_back(channelName);
364 const FairMQChannel& GetChannel(
const std::string& channelName,
const int index = 0)
const;
366 virtual void RegisterChannelEndpoints() {}
368 bool RegisterChannelEndpoint(
const std::string& channelName, uint16_t minNumSubChannels = 1, uint16_t maxNumSubChannels = 1)
370 bool ok = fChannelRegistry.insert(std::make_pair(channelName, std::make_pair(minNumSubChannels, maxNumSubChannels))).second;
373 LOG(warn) <<
"Registering channel: name already registered: \"" << channelName <<
"\"";
378 void PrintRegisteredChannels()
380 if (fChannelRegistry.size() < 1)
382 std::cout <<
"no channels registered." << std::endl;
386 for (
const auto& c : fChannelRegistry)
388 std::cout << c.first <<
":" << c.second.first <<
":" << c.second.second << std::endl;
393 void SetId(
const std::string&
id) {
fId = id; }
394 std::string GetId() {
return fId; }
398 void SetNumIoThreads(
int numIoThreads) {
fNumIoThreads = numIoThreads; }
401 void SetPortRangeMin(
int portRangeMin) { fPortRangeMin = portRangeMin; }
402 int GetPortRangeMin()
const {
return fPortRangeMin; }
404 void SetPortRangeMax(
int portRangeMax) { fPortRangeMax = portRangeMax; }
405 int GetPortRangeMax()
const {
return fPortRangeMax; }
407 void SetNetworkInterface(
const std::string& networkInterface) { fNetworkInterface = networkInterface; }
408 std::string GetNetworkInterface()
const {
return fNetworkInterface; }
410 void SetDefaultTransport(
const std::string& name) { fDefaultTransportType = fair::mq::TransportTypes.at(name); }
411 std::string GetDefaultTransport()
const {
return fair::mq::TransportNames.at(fDefaultTransportType); }
413 void SetInitializationTimeoutInS(
int initializationTimeoutInS) { fInitializationTimeoutInS = initializationTimeoutInS; }
414 int GetInitializationTimeoutInS()
const {
return fInitializationTimeoutInS; }
418 std::unordered_map<fair::mq::Transport, std::shared_ptr<FairMQTransportFactory>>
fTransports;
421 std::unordered_map<std::string, std::vector<FairMQChannel>>
fChannels;
455 virtual void Pause();
463 virtual void Reset();
467 bool fInitialValidationFinished;
468 std::condition_variable fInitialValidationCondition;
469 std::mutex fInitialValidationMutex;
474 std::string fNetworkInterface;
475 fair::mq::Transport fDefaultTransportType;
477 int fInitializationTimeoutInS;
482 void InitTaskWrapper();
488 void ResetTaskWrapper();
499 void AttachChannels(std::vector<FairMQChannel*>& chans);
504 bool ConnectEndpoint(
FairMQSocket& socket, std::string& endpoint);
505 bool BindEndpoint(
FairMQSocket& socket, std::string& endpoint);
511 void HandleSingleChannelInput();
512 void HandleMultipleChannelInput();
513 void HandleMultipleTransportInput();
514 void PollForTransport(
const FairMQTransportFactory* factory,
const std::vector<std::string>& channelKeys);
516 bool HandleMsgInput(
const std::string& chName,
const InputMsgCallback& callback,
int i)
const;
517 bool HandleMultipartInput(
const std::string& chName,
const InputMultipartCallback& callback,
int i)
const;
519 void CreateOwnConfig();
522 std::unordered_map<std::string, InputMsgCallback> fMsgInputs;
523 std::unordered_map<std::string, InputMultipartCallback> fMultipartInputs;
524 std::unordered_map<fair::mq::Transport, std::vector<std::string>> fMultitransportInputs;
525 std::unordered_map<std::string, std::pair<uint16_t, uint16_t>> fChannelRegistry;
526 std::vector<std::string> fInputChannelKeys;
527 std::mutex fMultitransportMutex;
528 std::atomic<bool> fMultitransportProceed;
530 bool fExternalConfig;
virtual void Pause()
Definition: FairMQDevice.cxx:754
std::unordered_map< fair::mq::Transport, std::shared_ptr< FairMQTransportFactory > > fTransports
Container for transports.
Definition: FairMQDevice.h:418
virtual void Run()
Definition: FairMQDevice.cxx:730
int64_t ReceiveAsync(FairMQParts &parts, const std::string &chan, const int i=0) const
Definition: FairMQDevice.h:191
int ReceiveAsync(FairMQMessagePtr &msg, const std::string &chan, const int i=0) const
Definition: FairMQDevice.h:137
virtual bool ConditionalRun()
Definition: FairMQDevice.cxx:738
FairMQProgOptions * fConfig
Program options configuration.
Definition: FairMQDevice.h:422
Definition: FairMQTransportFactory.h:27
auto Transport() const -> const FairMQTransportFactory *
Getter for default transport factory.
Definition: FairMQDevice.h:197
Definition: FairMQChannel.h:24
Definition: FairMQProgOptions.h:41
virtual void PreRun()
Definition: FairMQDevice.cxx:734
virtual void ResetTask()
Definition: FairMQDevice.cxx:983
std::string fId
Device ID.
Definition: FairMQDevice.h:425
void CatchSignals()
Catches interrupt signals (SIGINT, SIGTERM)
std::shared_ptr< FairMQTransportFactory > AddTransport(const fair::mq::Transport transport)
Definition: FairMQDevice.cxx:764
virtual ~FairMQDevice()
Default destructor.
Definition: FairMQDevice.cxx:1023
void SortChannel(const std::string &name, const bool reindex=true)
Definition: FairMQDevice.cxx:421
void PrintChannel(const std::string &name)
Definition: FairMQDevice.cxx:442
int64_t Receive(FairMQParts &parts, const std::string &chan, const int i, int rcvTimeoutInMs) const
Definition: FairMQDevice.h:169
virtual void PostRun()
Definition: FairMQDevice.cxx:743
Definition: FairMQSocket.h:18
std::unordered_map< std::string, std::vector< FairMQChannel > > fChannels
Device channels.
Definition: FairMQDevice.h:421
Definition: FairMQStateMachine.h:27
int Receive(FairMQMessagePtr &msg, const std::string &chan, const int i, int rcvTimeoutInMs) const
Definition: FairMQDevice.h:115
void SetTransport(const std::string &transport="zeromq")
Definition: FairMQDevice.cxx:815
int fNumIoThreads
Number of ZeroMQ I/O threads.
Definition: FairMQDevice.h:427
int Send(FairMQMessagePtr &msg, const std::string &chan, const int i, int sndTimeoutInMs) const
Definition: FairMQDevice.h:104
FairMQParts is a lightweight convenience wrapper around a vector of unique pointers to FairMQMessage...
Definition: FairMQParts.h:20
std::shared_ptr< FairMQTransportFactory > fTransportFactory
Default transport factory.
Definition: FairMQDevice.h:417
virtual void Reset()
Definition: FairMQDevice.cxx:996
static bool SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs)
Definition: FairMQDevice.cxx:416
int64_t SendAsync(FairMQParts &parts, const std::string &chan, const int i=0) const
Definition: FairMQDevice.h:180
Definition: FairMQDevice.h:44
int SendAsync(FairMQMessagePtr &msg, const std::string &chan, const int i=0) const
Definition: FairMQDevice.h:126
virtual void Init()
Definition: FairMQDevice.cxx:216
Definition: FairMQMessage.h:19
void WaitForInitialValidation()
Waits for the first initialization run to finish.
Definition: FairMQDevice.cxx:210
virtual void InitTask()
Definition: FairMQDevice.cxx:412
FairMQDevice operator=(const FairMQDevice &)=delete
Assignment operator (disabled)
virtual void LogSocketRates()
Outputs the socket transfer rates.
Definition: FairMQDevice.cxx:860
FairMQDevice()
Default constructor.
Definition: FairMQDevice.cxx:33
int64_t Send(FairMQParts &parts, const std::string &chan, const int i, int sndTimeoutInMs) const
Definition: FairMQDevice.h:158