Enable new callback API

- OnData() channel data handler.
 - ConditionalRun() for devices without incoming data.
 - Header file with common main(), to be extended with getDevice/addCustomOptions.
 - Update examples (MQ/Tutorial3) to use the new API and config.
 - NewSimpleMessage() for simpler creation of small messages (additional copy).
 - Replace SetProperty/GetProperty with fConfig access.
 - Runtime configurable channel names for common devices.
 - Configurable logging interval per channel.
 - FairMQMultiplier for distributing same data to multiple outputs.
 - Cleanup state machine messages.
 - Cmd option to toggle signal handling.
 - Simpler API for send/receive timeouts.
 - Enable --log-to-file.
 - Fix coverity issues, warnings.
 - Various code cleanup and minor tweaks.
This commit is contained in:
Alexey Rybalchenko 2016-08-10 09:47:53 +02:00
parent e0a03242ac
commit 16fd63cd5b
54 changed files with 1730 additions and 1665 deletions

View File

@ -81,10 +81,11 @@ Set(SRCS
"FairMQPoller.cxx" "FairMQPoller.cxx"
"devices/FairMQBenchmarkSampler.cxx" "devices/FairMQBenchmarkSampler.cxx"
"devices/FairMQSink.cxx"
"devices/FairMQProxy.cxx"
"devices/FairMQSplitter.cxx"
"devices/FairMQMerger.cxx" "devices/FairMQMerger.cxx"
"devices/FairMQMultiplier.cxx"
"devices/FairMQProxy.cxx"
"devices/FairMQSink.cxx"
"devices/FairMQSplitter.cxx"
"options/FairProgOptions.cxx" "options/FairProgOptions.cxx"
"options/FairMQProgOptions.cxx" "options/FairMQProgOptions.cxx"
@ -106,6 +107,8 @@ EndIf(NANOMSG_FOUND)
# manual install (globbing add not recommended) # manual install (globbing add not recommended)
Set(FAIRMQHEADERS Set(FAIRMQHEADERS
FairMQParts.h FairMQParts.h
# FairMQPlugin.h
runFairMQDevice.h
options/FairProgOptionsHelper.h options/FairProgOptionsHelper.h
options/FairMQEventManager.h options/FairMQEventManager.h
tools/FairMQTools.h tools/FairMQTools.h
@ -142,7 +145,7 @@ If(DDS_FOUND)
Set(DEPENDENCIES Set(DEPENDENCIES
${DEPENDENCIES} ${DEPENDENCIES}
${DDS_INTERCOM_LIBRARY_SHARED} ${DDS_INTERCOM_LIBRARY_SHARED}
${DDS_PROTOCOL_LIBRARY_SHARED} # also link the two DDS dependency libraries to avoid linking issues on some osx systems ${DDS_PROTOCOL_LIBRARY_SHARED}
${DDS_USER_DEFAULTS_LIBRARY_SHARED} ${DDS_USER_DEFAULTS_LIBRARY_SHARED}
) )
EndIf(DDS_FOUND) EndIf(DDS_FOUND)
@ -153,10 +156,11 @@ GENERATE_LIBRARY()
Set(Exe_Names Set(Exe_Names
bsampler bsampler
merger
multiplier
proxy
sink sink
splitter splitter
merger
proxy
runConfigExample runConfigExample
) )
@ -169,10 +173,11 @@ EndIf(DDS_FOUND)
Set(Exe_Source Set(Exe_Source
run/runBenchmarkSampler.cxx run/runBenchmarkSampler.cxx
run/runMerger.cxx
run/runMultiplier.cxx
run/runProxy.cxx
run/runSink.cxx run/runSink.cxx
run/runSplitter.cxx run/runSplitter.cxx
run/runMerger.cxx
run/runProxy.cxx
options/runConfigEx.cxx options/runConfigEx.cxx
) )
@ -197,4 +202,3 @@ EndForEach(_file RANGE 0 ${_length})
configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/startConfigExample.sh.in configure_file( ${CMAKE_SOURCE_DIR}/fairmq/options/startConfigExample.sh.in
${CMAKE_BINARY_DIR}/bin/startConfigExample.sh ) ${CMAKE_BINARY_DIR}/bin/startConfigExample.sh )

View File

@ -23,6 +23,8 @@ using namespace std;
boost::mutex FairMQChannel::fChannelMutex; boost::mutex FairMQChannel::fChannelMutex;
std::atomic<bool> FairMQChannel::fInterrupted(false);
FairMQChannel::FairMQChannel() FairMQChannel::FairMQChannel()
: fSocket(nullptr) : fSocket(nullptr)
, fType("unspecified") , fType("unspecified")
@ -41,8 +43,6 @@ FairMQChannel::FairMQChannel()
, fTransportFactory(nullptr) , fTransportFactory(nullptr)
, fNoBlockFlag(0) , fNoBlockFlag(0)
, fSndMoreFlag(0) , fSndMoreFlag(0)
, fSndTimeoutInMs(-1)
, fRcvTimeoutInMs(-1)
{ {
} }
@ -64,8 +64,6 @@ FairMQChannel::FairMQChannel(const string& type, const string& method, const str
, fTransportFactory(nullptr) , fTransportFactory(nullptr)
, fNoBlockFlag(0) , fNoBlockFlag(0)
, fSndMoreFlag(0) , fSndMoreFlag(0)
, fSndTimeoutInMs(-1)
, fRcvTimeoutInMs(-1)
{ {
} }
@ -87,8 +85,6 @@ FairMQChannel::FairMQChannel(const FairMQChannel& chan)
, fTransportFactory(nullptr) , fTransportFactory(nullptr)
, fNoBlockFlag(chan.fNoBlockFlag) , fNoBlockFlag(chan.fNoBlockFlag)
, fSndMoreFlag(chan.fSndMoreFlag) , fSndMoreFlag(chan.fSndMoreFlag)
, fSndTimeoutInMs(chan.fSndTimeoutInMs)
, fRcvTimeoutInMs(chan.fRcvTimeoutInMs)
{} {}
FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan) FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
@ -110,8 +106,6 @@ FairMQChannel& FairMQChannel::operator=(const FairMQChannel& chan)
fTransportFactory = nullptr; fTransportFactory = nullptr;
fNoBlockFlag = chan.fNoBlockFlag; fNoBlockFlag = chan.fNoBlockFlag;
fSndMoreFlag = chan.fSndMoreFlag; fSndMoreFlag = chan.fSndMoreFlag;
fSndTimeoutInMs = chan.fSndTimeoutInMs;
fRcvTimeoutInMs = chan.fRcvTimeoutInMs;
return *this; return *this;
} }
@ -425,8 +419,8 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "Invalid channel type: \"" << fType << "\""; LOG(ERROR) << "Invalid channel type: \"" << fType << "\"";
return false; exit(EXIT_FAILURE);
} }
// validate socket method // validate socket method
@ -436,8 +430,8 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "Invalid channel method: \"" << fMethod << "\""; LOG(ERROR) << "Invalid channel method: \"" << fMethod << "\"";
return false; exit(EXIT_FAILURE);
} }
// validate socket address // validate socket address
@ -459,7 +453,7 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\" (missing port?)"; LOG(ERROR) << "invalid channel address: \"" << fAddress << "\" (missing port?)";
return false; return false;
} }
} }
@ -471,7 +465,7 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\" (empty IPC address?)"; LOG(ERROR) << "invalid channel address: \"" << fAddress << "\" (empty IPC address?)";
return false; return false;
} }
} }
@ -480,7 +474,7 @@ bool FairMQChannel::ValidateChannel()
// if neither TCP or IPC is specified, return invalid // if neither TCP or IPC is specified, return invalid
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel address: \"" << fAddress << "\" (missing protocol specifier?)"; LOG(ERROR) << "invalid channel address: \"" << fAddress << "\" (missing protocol specifier?)";
return false; return false;
} }
} }
@ -490,8 +484,8 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel send buffer size: \"" << fSndBufSize << "\""; LOG(ERROR) << "invalid channel send buffer size (cannot be negative): \"" << fSndBufSize << "\"";
return false; exit(EXIT_FAILURE);
} }
// validate socket buffer size for receiving // validate socket buffer size for receiving
@ -499,8 +493,8 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel receive buffer size: \"" << fRcvBufSize << "\""; LOG(ERROR) << "invalid channel receive buffer size (cannot be negative): \"" << fRcvBufSize << "\"";
return false; exit(EXIT_FAILURE);
} }
// validate socket kernel transmit size for sending // validate socket kernel transmit size for sending
@ -508,8 +502,8 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel send kernel transmit size: \"" << fSndKernelSize << "\""; LOG(ERROR) << "invalid channel send kernel transmit size (cannot be negative): \"" << fSndKernelSize << "\"";
return false; exit(EXIT_FAILURE);
} }
// validate socket kernel transmit size for receiving // validate socket kernel transmit size for receiving
@ -517,8 +511,17 @@ bool FairMQChannel::ValidateChannel()
{ {
ss << "INVALID"; ss << "INVALID";
LOG(DEBUG) << ss.str(); LOG(DEBUG) << ss.str();
LOG(DEBUG) << "invalid channel receive kernel transmit size: \"" << fRcvKernelSize << "\""; LOG(ERROR) << "invalid channel receive kernel transmit size (cannot be negative): \"" << fRcvKernelSize << "\"";
return false; exit(EXIT_FAILURE);
}
// validate socket rate logging interval
if (fRateLogging < 0)
{
ss << "INVALID";
LOG(DEBUG) << ss.str();
LOG(ERROR) << "invalid socket rate logging interval (cannot be negative): \"" << fRateLogging << "\"";
exit(EXIT_FAILURE);
} }
fIsValid = true; fIsValid = true;
@ -561,15 +564,18 @@ void FairMQChannel::ResetChannel()
// TODO: implement channel resetting // TODO: implement channel resetting
} }
int FairMQChannel::Send(const unique_ptr<FairMQMessage>& msg) const int FairMQChannel::Send(const unique_ptr<FairMQMessage>& msg, int sndTimeoutInMs) const
{ {
fPoller->Poll(fSndTimeoutInMs); fPoller->Poll(sndTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
} }
}
if (fPoller->CheckOutput(1)) if (fPoller->CheckOutput(1))
{ {
@ -579,15 +585,18 @@ int FairMQChannel::Send(const unique_ptr<FairMQMessage>& msg) const
return -2; return -2;
} }
int FairMQChannel::Receive(const unique_ptr<FairMQMessage>& msg) const int FairMQChannel::Receive(const unique_ptr<FairMQMessage>& msg, int rcvTimeoutInMs) const
{ {
fPoller->Poll(fRcvTimeoutInMs); fPoller->Poll(rcvTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
} }
}
if (fPoller->CheckInput(1)) if (fPoller->CheckInput(1))
{ {
@ -597,15 +606,18 @@ int FairMQChannel::Receive(const unique_ptr<FairMQMessage>& msg) const
return -2; return -2;
} }
int64_t FairMQChannel::Send(const std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const int64_t FairMQChannel::Send(const std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int sndTimeoutInMs) const
{ {
fPoller->Poll(fSndTimeoutInMs); fPoller->Poll(sndTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
} }
}
if (fPoller->CheckOutput(1)) if (fPoller->CheckOutput(1))
{ {
@ -615,15 +627,18 @@ int64_t FairMQChannel::Send(const std::vector<std::unique_ptr<FairMQMessage>>& m
return -2; return -2;
} }
int64_t FairMQChannel::Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const int64_t FairMQChannel::Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int rcvTimeoutInMs) const
{ {
fPoller->Poll(fRcvTimeoutInMs); fPoller->Poll(rcvTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
} }
}
if (fPoller->CheckInput(1)) if (fPoller->CheckInput(1))
{ {
@ -633,16 +648,20 @@ int64_t FairMQChannel::Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgV
return -2; return -2;
} }
int FairMQChannel::Send(FairMQMessage* msg, const string& flag) const int FairMQChannel::Send(FairMQMessage* msg, const string& flag, int sndTimeoutInMs) const
{ {
if (flag == "") if (flag == "")
{ {
fPoller->Poll(fSndTimeoutInMs); fPoller->Poll(sndTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
}
} }
if (fPoller->CheckOutput(1)) if (fPoller->CheckOutput(1))
@ -658,16 +677,20 @@ int FairMQChannel::Send(FairMQMessage* msg, const string& flag) const
} }
} }
int FairMQChannel::Send(FairMQMessage* msg, const int flags) const int FairMQChannel::Send(FairMQMessage* msg, const int flags, int sndTimeoutInMs) const
{ {
if (flags == 0) if (flags == 0)
{ {
fPoller->Poll(fSndTimeoutInMs); fPoller->Poll(sndTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
}
} }
if (fPoller->CheckOutput(1)) if (fPoller->CheckOutput(1))
@ -683,16 +706,20 @@ int FairMQChannel::Send(FairMQMessage* msg, const int flags) const
} }
} }
int FairMQChannel::Receive(FairMQMessage* msg, const string& flag) const int FairMQChannel::Receive(FairMQMessage* msg, const string& flag, int rcvTimeoutInMs) const
{ {
if (flag == "") if (flag == "")
{ {
fPoller->Poll(fRcvTimeoutInMs); fPoller->Poll(rcvTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
}
} }
if (fPoller->CheckInput(1)) if (fPoller->CheckInput(1))
@ -708,16 +735,20 @@ int FairMQChannel::Receive(FairMQMessage* msg, const string& flag) const
} }
} }
int FairMQChannel::Receive(FairMQMessage* msg, const int flags) const int FairMQChannel::Receive(FairMQMessage* msg, const int flags, int rcvTimeoutInMs) const
{ {
if (flags == 0) if (flags == 0)
{ {
fPoller->Poll(fRcvTimeoutInMs); fPoller->Poll(rcvTimeoutInMs);
if (fPoller->CheckInput(0)) if (fPoller->CheckInput(0))
{ {
HandleUnblock(); HandleUnblock();
if (fInterrupted)
{
return -2; return -2;
}
} }
if (fPoller->CheckInput(1)) if (fPoller->CheckInput(1))
@ -761,7 +792,7 @@ inline bool FairMQChannel::HandleUnblock() const
FairMQMessage* cmd = fTransportFactory->CreateMessage(); FairMQMessage* cmd = fTransportFactory->CreateMessage();
if (fCmdSocket->Receive(cmd, 0) >= 0) if (fCmdSocket->Receive(cmd, 0) >= 0)
{ {
LOG(DEBUG) << "unblocked"; // LOG(DEBUG) << "unblocked";
} }
delete cmd; delete cmd;
return true; return true;

View File

@ -17,6 +17,7 @@
#include <string> #include <string>
#include <memory> // unique_ptr #include <memory> // unique_ptr
#include <atomic>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
@ -61,57 +62,73 @@ class FairMQChannel
/// Get socket type /// Get socket type
/// @return Returns socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/) /// @return Returns socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
std::string GetType() const; std::string GetType() const;
/// Get socket method /// Get socket method
/// @return Returns socket method (bind/connect) /// @return Returns socket method (bind/connect)
std::string GetMethod() const; std::string GetMethod() const;
/// Get socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc") /// Get socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
/// @return Returns socket type (e.g. "tcp://127.0.0.1:5555" or "ipc://abc") /// @return Returns socket type (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
std::string GetAddress() const; std::string GetAddress() const;
/// Get channel property (custom property) /// Get channel property (custom property)
/// @return Returns property value /// @return Returns property value
std::string GetProperty() const; std::string GetProperty() const;
/// Get socket send buffer size (in number of messages) /// Get socket send buffer size (in number of messages)
/// @return Returns socket send buffer size (in number of messages) /// @return Returns socket send buffer size (in number of messages)
int GetSndBufSize() const; int GetSndBufSize() const;
/// Get socket receive buffer size (in number of messages) /// Get socket receive buffer size (in number of messages)
/// @return Returns socket receive buffer size (in number of messages) /// @return Returns socket receive buffer size (in number of messages)
int GetRcvBufSize() const; int GetRcvBufSize() const;
/// Get socket kernel transmit send buffer size (in bytes) /// Get socket kernel transmit send buffer size (in bytes)
/// @return Returns socket kernel transmit send buffer size (in bytes) /// @return Returns socket kernel transmit send buffer size (in bytes)
int GetSndKernelSize() const; int GetSndKernelSize() const;
/// Get socket kernel transmit receive buffer size (in bytes) /// Get socket kernel transmit receive buffer size (in bytes)
/// @return Returns socket kernel transmit receive buffer size (in bytes) /// @return Returns socket kernel transmit receive buffer size (in bytes)
int GetRcvKernelSize() const; int GetRcvKernelSize() const;
/// Get socket rate logging setting (1/0)
/// @return Returns socket rate logging setting (1/0) /// Get socket rate logging interval (in seconds)
/// @return Returns socket rate logging interval (in seconds)
int GetRateLogging() const; int GetRateLogging() const;
/// Set socket type /// Set socket type
/// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/) /// @param type Socket type (push/pull/pub/sub/spub/xsub/pair/req/rep/dealer/router/)
void UpdateType(const std::string& type); void UpdateType(const std::string& type);
/// Set socket method /// Set socket method
/// @param method Socket method (bind/connect) /// @param method Socket method (bind/connect)
void UpdateMethod(const std::string& method); void UpdateMethod(const std::string& method);
/// Set socket address /// Set socket address
/// @param address Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc") /// @param address Socket address (e.g. "tcp://127.0.0.1:5555" or "ipc://abc")
void UpdateAddress(const std::string& address); void UpdateAddress(const std::string& address);
/// Set custom channel property /// Set custom channel property
/// @param property Channel property /// @param property Channel property
void UpdateProperty(const std::string& property); void UpdateProperty(const std::string& property);
/// Set socket send buffer size /// Set socket send buffer size
/// @param sndBufSize Socket send buffer size (in number of messages) /// @param sndBufSize Socket send buffer size (in number of messages)
void UpdateSndBufSize(const int sndBufSize); void UpdateSndBufSize(const int sndBufSize);
/// Set socket receive buffer size /// Set socket receive buffer size
/// @param rcvBufSize Socket receive buffer size (in number of messages) /// @param rcvBufSize Socket receive buffer size (in number of messages)
void UpdateRcvBufSize(const int rcvBufSize); void UpdateRcvBufSize(const int rcvBufSize);
/// Set socket kernel transmit send buffer size (in bytes) /// Set socket kernel transmit send buffer size (in bytes)
/// @param sndKernelSize Socket send buffer size (in bytes) /// @param sndKernelSize Socket send buffer size (in bytes)
void UpdateSndKernelSize(const int sndKernelSize); void UpdateSndKernelSize(const int sndKernelSize);
/// Set socket kernel transmit receive buffer size (in bytes) /// Set socket kernel transmit receive buffer size (in bytes)
/// @param rcvKernelSize Socket receive buffer size (in bytes) /// @param rcvKernelSize Socket receive buffer size (in bytes)
void UpdateRcvKernelSize(const int rcvKernelSize); void UpdateRcvKernelSize(const int rcvKernelSize);
/// Set socket rate logging setting
/// @param rateLogging Socket rate logging setting (1/0) /// Set socket rate logging interval (in seconds)
/// @param rateLogging Socket rate logging interval (in seconds)
void UpdateRateLogging(const int rateLogging); void UpdateRateLogging(const int rateLogging);
/// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel())) /// Checks if the configured channel settings are valid (checks the validity parameter, without running full validation (as oposed to ValidateChannel()))
@ -135,7 +152,7 @@ class FairMQChannel
/// @param msg Constant reference of unique_ptr to a FairMQMessage /// @param msg Constant reference of unique_ptr to a FairMQMessage
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. /// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
int Send(const std::unique_ptr<FairMQMessage>& msg) const; int Send(const std::unique_ptr<FairMQMessage>& msg, int sndTimeoutInMs = -1) const;
/// Sends a message in non-blocking mode. /// Sends a message in non-blocking mode.
/// @details SendAsync method attempts to send a message without blocking by /// @details SendAsync method attempts to send a message without blocking by
@ -179,7 +196,7 @@ class FairMQChannel
/// @param msgVec message vector reference /// @param msgVec message vector reference
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. /// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
int64_t Send(const std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const; int64_t Send(const std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int sndTimeoutInMs = -1) const;
/// Sends a vector of message in non-blocking mode. /// Sends a vector of message in non-blocking mode.
/// @details SendAsync method attempts to send a vector of messages without blocking by /// @details SendAsync method attempts to send a vector of messages without blocking by
@ -200,7 +217,7 @@ class FairMQChannel
/// @param msg Constant reference of unique_ptr to a FairMQMessage /// @param msg Constant reference of unique_ptr to a FairMQMessage
/// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out. /// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
int Receive(const std::unique_ptr<FairMQMessage>& msg) const; int Receive(const std::unique_ptr<FairMQMessage>& msg, int rcvTimeoutInMs = -1) const;
/// Receives a message in non-blocking mode. /// Receives a message in non-blocking mode.
/// ///
@ -217,7 +234,7 @@ class FairMQChannel
/// @param msgVec message vector reference /// @param msgVec message vector reference
/// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out. /// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec) const; int64_t Receive(std::vector<std::unique_ptr<FairMQMessage>>& msgVec, int rcvTimeoutInMs = -1) const;
/// Receives a vector of messages in non-blocking mode. /// Receives a vector of messages in non-blocking mode.
/// ///
@ -229,44 +246,16 @@ class FairMQChannel
return fSocket->Receive(msgVec, fNoBlockFlag); return fSocket->Receive(msgVec, fNoBlockFlag);
} }
// DEPRECATED socket method wrappers with raw pointers and flag checks
int Send(FairMQMessage* msg, const std::string& flag = "") const;
int Send(FairMQMessage* msg, const int flags) const;
int Receive(FairMQMessage* msg, const std::string& flag = "") const;
int Receive(FairMQMessage* msg, const int flags) const;
/// Sets a timeout on the (blocking) Send method
/// @param timeout timeout value in milliseconds
inline void SetSendTimeout(const int timeout)
{
fSndTimeoutInMs = timeout;
}
/// Gets the current value of the timeout on the (blocking) Send method
/// @return Timeout value in milliseconds. -1 for no timeout.
inline int GetSendTimeout() const
{
return fSndTimeoutInMs;
}
/// Sets a timeout on the (blocking) Receive method
/// @param timeout timeout value in milliseconds
inline void SetReceiveTimeout(const int timeout)
{
fRcvTimeoutInMs = timeout;
}
/// Gets the current value of the timeout on the (blocking) Receive method
/// @return Timeout value in milliseconds. -1 for no timeout.
inline int GetReceiveTimeout() const
{
return fRcvTimeoutInMs;
}
/// Checks if the socket is expecting to receive another part of a multipart message. /// Checks if the socket is expecting to receive another part of a multipart message.
/// @return Return true if the socket expects another part of a multipart message and false otherwise. /// @return Return true if the socket expects another part of a multipart message and false otherwise.
bool ExpectsAnotherPart() const; bool ExpectsAnotherPart() const;
// DEPRECATED socket method wrappers with raw pointers and flag checks
int Send(FairMQMessage* msg, const std::string& flag = "", int sndTimeoutInMs = -1) const;
int Send(FairMQMessage* msg, const int flags, int sndTimeoutInMs = -1) const;
int Receive(FairMQMessage* msg, const std::string& flag = "", int rcvTimeoutInMs = -1) const;
int Receive(FairMQMessage* msg, const int flags, int rcvTimeoutInMs = -1) const;
private: private:
std::string fType; std::string fType;
std::string fMethod; std::string fMethod;
@ -279,7 +268,7 @@ class FairMQChannel
int fRateLogging; int fRateLogging;
std::string fChannelName; std::string fChannelName;
bool fIsValid; std::atomic<bool> fIsValid;
FairMQPoller* fPoller; FairMQPoller* fPoller;
FairMQSocket* fCmdSocket; FairMQSocket* fCmdSocket;
@ -289,9 +278,6 @@ class FairMQChannel
int fNoBlockFlag; int fNoBlockFlag;
int fSndMoreFlag; int fSndMoreFlag;
int fSndTimeoutInMs;
int fRcvTimeoutInMs;
bool InitCommandInterface(FairMQTransportFactory* factory, int numIoThreads); bool InitCommandInterface(FairMQTransportFactory* factory, int numIoThreads);
bool HandleUnblock() const; bool HandleUnblock() const;
@ -301,6 +287,8 @@ class FairMQChannel
// this does not hurt much, because mutex is used only during initialization with very low contention // this does not hurt much, because mutex is used only during initialization with very low contention
// possible TODO: improve this // possible TODO: improve this
static boost::mutex fChannelMutex; static boost::mutex fChannelMutex;
static std::atomic<bool> fInterrupted;
}; };
#endif /* FAIRMQCHANNEL_H_ */ #endif /* FAIRMQCHANNEL_H_ */

View File

@ -21,6 +21,7 @@
#include <termios.h> // for the InteractiveStateLoop #include <termios.h> // for the InteractiveStateLoop
#include <poll.h> #include <poll.h>
#include <boost/timer/timer.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/random/mersenne_twister.hpp> // for choosing random port in range #include <boost/random/mersenne_twister.hpp> // for choosing random port in range
#include <boost/random/uniform_int_distribution.hpp> // for choosing random port in range #include <boost/random/uniform_int_distribution.hpp> // for choosing random port in range
@ -47,6 +48,7 @@ static void CallSignalHandler(int signal)
FairMQDevice::FairMQDevice() FairMQDevice::FairMQDevice()
: fChannels() : fChannels()
, fConfig(nullptr)
, fId() , fId()
, fNetworkInterface() , fNetworkInterface()
, fMaxInitializationAttempts(120) , fMaxInitializationAttempts(120)
@ -56,13 +58,15 @@ FairMQDevice::FairMQDevice()
, fLogIntervalInMs(1000) , fLogIntervalInMs(1000)
, fCmdSocket(nullptr) , fCmdSocket(nullptr)
, fTransportFactory(nullptr) , fTransportFactory(nullptr)
, fConfig(nullptr)
, fInitialValidationFinished(false) , fInitialValidationFinished(false)
, fInitialValidationCondition() , fInitialValidationCondition()
, fInitialValidationMutex() , fInitialValidationMutex()
, fCatchingSignals(false) , fCatchingSignals(false)
, fTerminated(false) , fTerminationRequested(false)
, fRunning(false) , fInteractiveRunning(false)
, fDataCallbacks(false)
, fMsgInputs()
, fMultipartInputs()
{ {
} }
@ -81,8 +85,10 @@ void FairMQDevice::SignalHandler(int signal)
{ {
LOG(INFO) << "Caught signal " << signal; LOG(INFO) << "Caught signal " << signal;
if (!fTerminated) if (!fTerminationRequested)
{ {
fTerminationRequested = true;
ChangeState(STOP); ChangeState(STOP);
ChangeState(RESET_TASK); ChangeState(RESET_TASK);
@ -94,15 +100,14 @@ void FairMQDevice::SignalHandler(int signal)
ChangeState(END); ChangeState(END);
// exit(EXIT_FAILURE); // exit(EXIT_FAILURE);
fRunning = false; fInteractiveRunning = false;
fTerminated = true;
LOG(INFO) << "Exiting."; LOG(INFO) << "Exiting.";
} }
else else
{ {
LOG(WARN) << "Repeated termination or bad initialization? Aborting."; LOG(WARN) << "Repeated termination or bad initialization? Aborting.";
// std::abort(); std::abort();
exit(EXIT_FAILURE); // exit(EXIT_FAILURE);
} }
} }
@ -224,13 +229,12 @@ void FairMQDevice::InitWrapper()
// go over the list of channels until all are initialized (and removed from the uninitialized list) // go over the list of channels until all are initialized (and removed from the uninitialized list)
int numAttempts = 0; int numAttempts = 0;
int maxAttempts = fMaxInitializationAttempts;
while (!uninitializedConnectingChannels.empty()) while (!uninitializedConnectingChannels.empty())
{ {
ConnectChannels(uninitializedConnectingChannels); ConnectChannels(uninitializedConnectingChannels);
if (++numAttempts > maxAttempts) if (++numAttempts > fMaxInitializationAttempts)
{ {
LOG(ERROR) << "could not connect all channels after " << maxAttempts << " attempts"; LOG(ERROR) << "could not connect all channels after " << fMaxInitializationAttempts << " attempts";
// TODO: goto ERROR state; // TODO: goto ERROR state;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -317,58 +321,6 @@ bool FairMQDevice::ConnectChannel(FairMQChannel& ch)
return true; return true;
} }
// bool FairMQDevice::InitChannel(FairMQChannel& ch)
// {
// LOG(DEBUG) << "Initializing channel " << ch.fChannelName << " (" << ch.fType << ")";
// // initialize the socket
// ch.fSocket = fTransportFactory->CreateSocket(ch.fType, ch.fChannelName, fNumIoThreads, fId);
// // set high water marks
// ch.fSocket->SetOption("snd-hwm", &(ch.fSndBufSize), sizeof(ch.fSndBufSize));
// ch.fSocket->SetOption("rcv-hwm", &(ch.fRcvBufSize), sizeof(ch.fRcvBufSize));
// if (ch.fMethod == "bind")
// {
// // number of attempts when choosing a random port
// int maxAttempts = 1000;
// int numAttempts = 0;
// // initialize random generator
// boost::random::mt19937 gen(getpid());
// boost::random::uniform_int_distribution<> randomPort(fPortRangeMin, fPortRangeMax);
// LOG(DEBUG) << "Binding channel " << ch.fChannelName << " on " << ch.fAddress;
// // try to bind to the saved port. In case of failure, try random one.
// if (!ch.fSocket->Bind(ch.fAddress))
// {
// LOG(DEBUG) << "Could not bind to configured port, trying random port in range " << fPortRangeMin << "-" << fPortRangeMax;
// do {
// ++numAttempts;
// if (numAttempts > maxAttempts)
// {
// LOG(ERROR) << "could not bind to any port in the given range after " << maxAttempts << " attempts";
// return false;
// }
// size_t pos = ch.fAddress.rfind(":");
// stringstream newPort;
// newPort << static_cast<int>(randomPort(gen));
// ch.fAddress = ch.fAddress.substr(0, pos + 1) + newPort.str();
// LOG(DEBUG) << "Binding channel " << ch.fChannelName << " on " << ch.fAddress;
// } while (!ch.fSocket->Bind(ch.fAddress));
// }
// }
// else
// {
// LOG(DEBUG) << "Connecting channel " << ch.fChannelName << " to " << ch.fAddress;
// ch.fSocket->Connect(ch.fAddress);
// }
// return true;
// }
void FairMQDevice::InitTaskWrapper() void FairMQDevice::InitTaskWrapper()
{ {
InitTask(); InitTask();
@ -434,16 +386,120 @@ void FairMQDevice::PrintChannel(const string& name)
} }
} }
void FairMQDevice::OnData(const string& channelName, InputMsgCallback callback)
{
fDataCallbacks = true;
fMsgInputs.insert(make_pair(channelName, callback));
}
void FairMQDevice::OnData(const string& channelName, InputMultipartCallback callback)
{
fDataCallbacks = true;
fMultipartInputs.insert(make_pair(channelName, callback));
}
void FairMQDevice::RunWrapper() void FairMQDevice::RunWrapper()
{ {
LOG(INFO) << "DEVICE: Running..."; LOG(INFO) << "DEVICE: Running...";
boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this));
FairMQChannel::fInterrupted = false;
try try
{ {
PreRun();
if (fDataCallbacks)
{
bool exitingRunningCallback = false;
vector<string> inputChannelKeys;
for (const auto& i: fMsgInputs)
{
inputChannelKeys.push_back(i.first);
}
for (const auto& i: fMultipartInputs)
{
inputChannelKeys.push_back(i.first);
}
unique_ptr<FairMQPoller> poller(fTransportFactory->CreatePoller(fChannels, inputChannelKeys));
while (CheckCurrentState(RUNNING) && !exitingRunningCallback)
{
poller->Poll(200);
for (const auto& mi : fMsgInputs)
{
for (unsigned int i = 0; i < fChannels.at(mi.first).size(); ++i)
{
if (poller->CheckInput(mi.first, i))
{
unique_ptr<FairMQMessage> msg(NewMessage());
if (Receive(msg, mi.first, i) >= 0)
{
if (mi.second(msg, i) == false)
{
exitingRunningCallback = true;
break;
}
}
else
{
exitingRunningCallback = true;
break;
}
}
}
if (exitingRunningCallback)
{
break;
}
}
for (const auto& mi : fMultipartInputs)
{
for (unsigned int i = 0; i < fChannels.at(mi.first).size(); ++i)
{
if (poller->CheckInput(mi.first, i))
{
FairMQParts parts;
if (Receive(parts, mi.first, i) >= 0)
{
if (mi.second(parts, i) == false)
{
exitingRunningCallback = true;
break;
}
}
else
{
exitingRunningCallback = true;
break;
}
}
}
if (exitingRunningCallback)
{
break;
}
}
}
}
else
{
while (CheckCurrentState(RUNNING) && ConditionalRun())
{
}
Run(); Run();
} }
PostRun();
}
catch (const out_of_range& oor) catch (const out_of_range& oor)
{ {
LOG(ERROR) << "Out of Range error: " << oor.what(); LOG(ERROR) << "Out of Range error: " << oor.what();
@ -477,6 +533,19 @@ void FairMQDevice::Run()
{ {
} }
void FairMQDevice::PreRun()
{
}
bool FairMQDevice::ConditionalRun()
{
return false;
}
void FairMQDevice::PostRun()
{
}
void FairMQDevice::Pause() void FairMQDevice::Pause()
{ {
while (true) while (true)
@ -656,18 +725,22 @@ void FairMQDevice::LogSocketRates()
int numFilteredSockets = 0; int numFilteredSockets = 0;
vector<FairMQSocket*> filteredSockets; vector<FairMQSocket*> filteredSockets;
vector<string> filteredChannelNames; vector<string> filteredChannelNames;
vector<int> logIntervals;
vector<int> intervalCounters;
// iterate over the channels map // iterate over the channels map
for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) for (const auto& mi : fChannels)
{ {
// iterate over the channels vector // iterate over the channels vector
for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) for (auto vi = (mi.second).begin(); vi != (mi.second).end(); ++vi)
{ {
if (vi->fRateLogging == 1) if (vi->fRateLogging > 0)
{ {
filteredSockets.push_back(vi->fSocket); filteredSockets.push_back(vi->fSocket);
logIntervals.push_back(vi->fRateLogging);
intervalCounters.push_back(0);
stringstream ss; stringstream ss;
ss << mi->first << "[" << vi - (mi->second).begin() << "]"; ss << mi.first << "[" << vi - (mi.second).begin() << "]";
filteredChannelNames.push_back(ss.str()); filteredChannelNames.push_back(ss.str());
++numFilteredSockets; ++numFilteredSockets;
} }
@ -690,12 +763,12 @@ void FairMQDevice::LogSocketRates()
vector<double> msgPerSecOut(numFilteredSockets); vector<double> msgPerSecOut(numFilteredSockets);
int i = 0; int i = 0;
for (auto itr = filteredSockets.begin(); itr != filteredSockets.end(); ++itr) for (const auto& vi : filteredSockets)
{ {
bytesIn.at(i) = (*itr)->GetBytesRx(); bytesIn.at(i) = vi->GetBytesRx();
bytesOut.at(i) = (*itr)->GetBytesTx(); bytesOut.at(i) = vi->GetBytesTx();
msgIn.at(i) = (*itr)->GetMessagesRx(); msgIn.at(i) = vi->GetMessagesRx();
msgOut.at(i) = (*itr)->GetMessagesTx(); msgOut.at(i) = vi->GetMessagesTx();
++i; ++i;
} }
@ -711,33 +784,40 @@ void FairMQDevice::LogSocketRates()
i = 0; i = 0;
for (auto itr = filteredSockets.begin(); itr != filteredSockets.end(); itr++) for (const auto& vi : filteredSockets)
{ {
bytesInNew.at(i) = (*itr)->GetBytesRx(); intervalCounters.at(i)++;
if (intervalCounters.at(i) == logIntervals.at(i))
{
intervalCounters.at(i) = 0;
bytesInNew.at(i) = vi->GetBytesRx();
mbPerSecIn.at(i) = (static_cast<double>(bytesInNew.at(i) - bytesIn.at(i)) / (1024. * 1024.)) / static_cast<double>(msSinceLastLog) * 1000.; mbPerSecIn.at(i) = (static_cast<double>(bytesInNew.at(i) - bytesIn.at(i)) / (1024. * 1024.)) / static_cast<double>(msSinceLastLog) * 1000.;
bytesIn.at(i) = bytesInNew.at(i); bytesIn.at(i) = bytesInNew.at(i);
msgInNew.at(i) = (*itr)->GetMessagesRx(); msgInNew.at(i) = vi->GetMessagesRx();
msgPerSecIn.at(i) = static_cast<double>(msgInNew.at(i) - msgIn.at(i)) / static_cast<double>(msSinceLastLog) * 1000.; msgPerSecIn.at(i) = static_cast<double>(msgInNew.at(i) - msgIn.at(i)) / static_cast<double>(msSinceLastLog) * 1000.;
msgIn.at(i) = msgInNew.at(i); msgIn.at(i) = msgInNew.at(i);
bytesOutNew.at(i) = (*itr)->GetBytesTx(); bytesOutNew.at(i) = vi->GetBytesTx();
mbPerSecOut.at(i) = (static_cast<double>(bytesOutNew.at(i) - bytesOut.at(i)) / (1024. * 1024.)) / static_cast<double>(msSinceLastLog) * 1000.; mbPerSecOut.at(i) = (static_cast<double>(bytesOutNew.at(i) - bytesOut.at(i)) / (1024. * 1024.)) / static_cast<double>(msSinceLastLog) * 1000.;
bytesOut.at(i) = bytesOutNew.at(i); bytesOut.at(i) = bytesOutNew.at(i);
msgOutNew.at(i) = (*itr)->GetMessagesTx(); msgOutNew.at(i) = vi->GetMessagesTx();
msgPerSecOut.at(i) = static_cast<double>(msgOutNew.at(i) - msgOut.at(i)) / static_cast<double>(msSinceLastLog) * 1000.; msgPerSecOut.at(i) = static_cast<double>(msgOutNew.at(i) - msgOut.at(i)) / static_cast<double>(msSinceLastLog) * 1000.;
msgOut.at(i) = msgOutNew.at(i); msgOut.at(i) = msgOutNew.at(i);
LOG(DEBUG) << filteredChannelNames.at(i) << ": " LOG(DEBUG) << filteredChannelNames.at(i) << ": "
<< "in: " << msgPerSecIn.at(i) << " msg (" << mbPerSecIn.at(i) << " MB), " << "in: " << msgPerSecIn.at(i) << " msg (" << mbPerSecIn.at(i) << " MB), "
<< "out: " << msgPerSecOut.at(i) << " msg (" << mbPerSecOut.at(i) << " MB)"; << "out: " << msgPerSecOut.at(i) << " msg (" << mbPerSecOut.at(i) << " MB)";
}
++i; ++i;
} }
t0 = t1; t0 = t1;
boost::this_thread::sleep(boost::posix_time::milliseconds(fLogIntervalInMs)); boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
} }
catch (boost::thread_interrupted&) catch (boost::thread_interrupted&)
{ {
@ -751,7 +831,7 @@ void FairMQDevice::LogSocketRates()
void FairMQDevice::InteractiveStateLoop() void FairMQDevice::InteractiveStateLoop()
{ {
fRunning = true; fInteractiveRunning = true;
char c; // hold the user console input char c; // hold the user console input
pollfd cinfd[1]; pollfd cinfd[1];
cinfd[0].fd = fileno(stdin); cinfd[0].fd = fileno(stdin);
@ -764,11 +844,11 @@ void FairMQDevice::InteractiveStateLoop()
PrintInteractiveStateLoopHelp(); PrintInteractiveStateLoopHelp();
while (fRunning) while (fInteractiveRunning)
{ {
if (poll(cinfd, 1, 500)) if (poll(cinfd, 1, 500))
{ {
if (!fRunning) if (!fInteractiveRunning)
{ {
break; break;
} }
@ -815,11 +895,23 @@ void FairMQDevice::InteractiveStateLoop()
// break; // break;
case 'q': case 'q':
LOG(INFO) << "[q] end"; LOG(INFO) << "[q] end";
ChangeState(STOP);
ChangeState(RESET_TASK);
WaitForEndOfState(RESET_TASK);
ChangeState(RESET_DEVICE);
WaitForEndOfState(RESET_DEVICE);
ChangeState(END); ChangeState(END);
if (CheckCurrentState("EXITING")) if (CheckCurrentState("EXITING"))
{ {
fRunning = false; fInteractiveRunning = false;
} }
LOG(INFO) << "Exiting.";
break; break;
default: default:
LOG(INFO) << "Invalid input: [" << c << "]"; LOG(INFO) << "Invalid input: [" << c << "]";
@ -836,6 +928,7 @@ void FairMQDevice::InteractiveStateLoop()
void FairMQDevice::Unblock() void FairMQDevice::Unblock()
{ {
FairMQChannel::fInterrupted = true;
FairMQMessage* cmd = fTransportFactory->CreateMessage(); FairMQMessage* cmd = fTransportFactory->CreateMessage();
fCmdSocket->Send(cmd, 0); fCmdSocket->Send(cmd, 0);
delete cmd; delete cmd;
@ -872,21 +965,21 @@ void FairMQDevice::ResetWrapper()
void FairMQDevice::Reset() void FairMQDevice::Reset()
{ {
// iterate over the channels map // iterate over the channels map
for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) for (auto& mi : fChannels)
{ {
// iterate over the channels vector // iterate over the channels vector
for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) for (auto& vi : mi.second)
{ {
vi->fSocket->Close(); vi.fSocket->Close();
delete vi->fSocket; delete vi.fSocket;
vi->fSocket = nullptr; vi.fSocket = nullptr;
delete vi->fPoller; delete vi.fPoller;
vi->fPoller = nullptr; vi.fPoller = nullptr;
vi->fCmdSocket->Close(); vi.fCmdSocket->Close();
delete vi->fCmdSocket; delete vi.fCmdSocket;
vi->fCmdSocket = nullptr; vi.fCmdSocket = nullptr;
} }
} }
} }
@ -905,18 +998,18 @@ void FairMQDevice::Shutdown()
LOG(DEBUG) << "Closing sockets..."; LOG(DEBUG) << "Closing sockets...";
// iterate over the channels map // iterate over the channels map
for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) for (const auto& mi : fChannels)
{ {
// iterate over the channels vector // iterate over the channels vector
for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) for (const auto& vi : mi.second)
{ {
if (vi->fSocket) if (vi.fSocket)
{ {
vi->fSocket->Close(); vi.fSocket->Close();
} }
if (vi->fCmdSocket) if (vi.fCmdSocket)
{ {
vi->fCmdSocket->Close(); vi.fCmdSocket->Close();
} }
} }
} }
@ -932,20 +1025,20 @@ void FairMQDevice::Shutdown()
FairMQDevice::~FairMQDevice() FairMQDevice::~FairMQDevice()
{ {
// iterate over the channels map // iterate over the channels map
for (auto mi = fChannels.begin(); mi != fChannels.end(); ++mi) for (auto& mi : fChannels)
{ {
// iterate over the channels vector // iterate over the channels vector
for (auto vi = (mi->second).begin(); vi != (mi->second).end(); ++vi) for (auto& vi : mi.second)
{ {
if (vi->fSocket) if (vi.fSocket)
{ {
delete vi->fSocket; delete vi.fSocket;
vi->fSocket = nullptr; vi.fSocket = nullptr;
} }
if (vi->fPoller) if (vi.fPoller)
{ {
delete vi->fPoller; delete vi.fPoller;
vi->fPoller = nullptr; vi.fPoller = nullptr;
} }
} }
} }

View File

@ -20,6 +20,7 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include <functional>
#include <mutex> #include <mutex>
#include <condition_variable> #include <condition_variable>
@ -33,8 +34,19 @@
#include "FairMQMessage.h" #include "FairMQMessage.h"
#include "FairMQParts.h" #include "FairMQParts.h"
typedef std::unordered_map<std::string, std::vector<FairMQChannel>> FairMQChannelMap;
typedef std::function<bool(std::unique_ptr<FairMQMessage>&, int)> InputMsgCallback;
typedef std::function<bool(FairMQParts&, int)> InputMultipartCallback;
class FairMQProgOptions; class FairMQProgOptions;
template<typename T>
void FairMQSimpleMsgCleanup(void* /*data*/, void* hint)
{
delete static_cast<T*>(hint);
}
class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
{ {
friend class FairMQChannel; friend class FairMQChannel;
@ -94,9 +106,9 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// @param i channel index /// @param i channel index
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. /// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
inline int Send(const std::unique_ptr<FairMQMessage>& msg, const std::string& chan, const int i = 0) const inline int Send(const std::unique_ptr<FairMQMessage>& msg, const std::string& chan, const int i = 0, int sndTimeoutInMs = -1) const
{ {
return fChannels.at(chan).at(i).Send(msg); return fChannels.at(chan).at(i).Send(msg, sndTimeoutInMs);
} }
/// Shorthand method to send `msg` on `chan` at index `i` without blocking /// Shorthand method to send `msg` on `chan` at index `i` without blocking
@ -116,9 +128,9 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// @param i channel index /// @param i channel index
/// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out. /// @return Number of bytes that have been queued. -2 If queueing was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
inline int64_t Send(const FairMQParts& parts, const std::string& chan, const int i = 0) const inline int64_t Send(const FairMQParts& parts, const std::string& chan, const int i = 0, int sndTimeoutInMs = -1) const
{ {
return fChannels.at(chan).at(i).Send(parts.fParts); return fChannels.at(chan).at(i).Send(parts.fParts, sndTimeoutInMs);
} }
/// Shorthand method to send FairMQParts on `chan` at index `i` without blocking /// Shorthand method to send FairMQParts on `chan` at index `i` without blocking
@ -138,9 +150,9 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// @param i channel index /// @param i channel index
/// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out. /// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
inline int Receive(const std::unique_ptr<FairMQMessage>& msg, const std::string& chan, const int i = 0) const inline int Receive(const std::unique_ptr<FairMQMessage>& msg, const std::string& chan, const int i = 0, int rcvTimeoutInMs = -1) const
{ {
return fChannels.at(chan).at(i).Receive(msg); return fChannels.at(chan).at(i).Receive(msg, rcvTimeoutInMs);
} }
/// Shorthand method to receive `msg` on `chan` at index `i` without blocking /// Shorthand method to receive `msg` on `chan` at index `i` without blocking
@ -160,9 +172,9 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// @param i channel index /// @param i channel index
/// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out. /// @return Number of bytes that have been received. -2 If reading from the queue was not possible or timed out.
/// In case of errors, returns -1. /// In case of errors, returns -1.
inline int64_t Receive(FairMQParts& parts, const std::string& chan, const int i = 0) const inline int64_t Receive(FairMQParts& parts, const std::string& chan, const int i = 0, int rcvTimeoutInMs = -1) const
{ {
return fChannels.at(chan).at(i).Receive(parts.fParts); return fChannels.at(chan).at(i).Receive(parts.fParts, rcvTimeoutInMs);
} }
/// Shorthand method to receive FairMQParts on `chan` at index `i` without blocking /// Shorthand method to receive FairMQParts on `chan` at index `i` without blocking
@ -176,6 +188,13 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
return fChannels.at(chan).at(i).ReceiveAsync(parts.fParts); return fChannels.at(chan).at(i).ReceiveAsync(parts.fParts);
} }
/// @brief Create FairMQPoller
/// @return pointer to FairMQPoller
inline FairMQPoller* NewPoller(const std::initializer_list<std::string> channelList) const
{
return fTransportFactory->CreatePoller(fChannels, channelList);
}
/// @brief Create empty FairMQMessage /// @brief Create empty FairMQMessage
/// @return pointer to FairMQMessage /// @return pointer to FairMQMessage
inline FairMQMessage* NewMessage() const inline FairMQMessage* NewMessage() const
@ -202,6 +221,26 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
return fTransportFactory->CreateMessage(data, size, ffn, hint); return fTransportFactory->CreateMessage(data, size, ffn, hint);
} }
template<typename T>
inline FairMQMessage* NewSimpleMessage(const T& data) const
{
T* dataCopy = new T(data);
return fTransportFactory->CreateMessage(dataCopy, sizeof(T), FairMQSimpleMsgCleanup<T>, dataCopy);
}
template<std::size_t N>
inline FairMQMessage* NewSimpleMessage(const char(&data)[N]) const
{
std::string* msgStr = new std::string(data);
return fTransportFactory->CreateMessage(const_cast<char*>(msgStr->c_str()), msgStr->length(), FairMQSimpleMsgCleanup<std::string>, msgStr);
}
inline FairMQMessage* NewSimpleMessage(const std::string& str) const
{
std::string* msgStr = new std::string(str);
return fTransportFactory->CreateMessage(const_cast<char*>(msgStr->c_str()), msgStr->length(), FairMQSimpleMsgCleanup<std::string>, msgStr);
}
/// Waits for the first initialization run to finish /// Waits for the first initialization run to finish
void WaitForInitialValidation(); void WaitForInitialValidation();
@ -255,8 +294,32 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// @param rhs Left hand side value for comparison /// @param rhs Left hand side value for comparison
static bool SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs); static bool SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs);
// TODO: make this const?
std::unordered_map<std::string, std::vector<FairMQChannel>> fChannels; ///< Device channels std::unordered_map<std::string, std::vector<FairMQChannel>> fChannels; ///< Device channels
FairMQProgOptions* fConfig; ///< Program options configuration
template<class T>
void OnData(const std::string& channelName, bool (T::* memberFunction)(std::unique_ptr<FairMQMessage>& msg, int index))
{
fDataCallbacks = true;
fMsgInputs.insert(std::make_pair(channelName, [this, memberFunction](std::unique_ptr<FairMQMessage>& msg, int index)
{
return (static_cast<T*>(this)->*memberFunction)(msg, index);
}));
}
void OnData(const std::string& channelName, InputMsgCallback);
template<class T>
void OnData(const std::string& channelName, bool (T::* memberFunction)(FairMQParts& parts, int index))
{
fDataCallbacks = true;
fMultipartInputs.insert(std::make_pair(channelName, [this, memberFunction](FairMQParts& parts, int index)
{
return (static_cast<T*>(this)->*memberFunction)(parts, index);
}));
}
void OnData(const std::string& channelName, InputMultipartCallback);
protected: protected:
std::string fId; ///< Device ID std::string fId; ///< Device ID
@ -274,7 +337,6 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
FairMQSocket* fCmdSocket; ///< Socket used for the internal unblocking mechanism FairMQSocket* fCmdSocket; ///< Socket used for the internal unblocking mechanism
FairMQTransportFactory* fTransportFactory; ///< Transport factory FairMQTransportFactory* fTransportFactory; ///< Transport factory
FairMQProgOptions* fConfig; ///< Program options configuration
/// Additional user initialization (can be overloaded in child classes). Prefer to use InitTask(). /// Additional user initialization (can be overloaded in child classes). Prefer to use InitTask().
virtual void Init(); virtual void Init();
@ -285,6 +347,15 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// Runs the device (to be overloaded in child classes) /// Runs the device (to be overloaded in child classes)
virtual void Run(); virtual void Run();
/// Called in the RUNNING state once before executing the Run()/ConditionalRun() method
virtual void PreRun();
/// Called during RUNNING state repeatedly until it returns false or device state changes
virtual bool ConditionalRun();
/// Called in the RUNNING state once after executing the Run()/ConditionalRun() method
virtual void PostRun();
/// Handles the PAUSE state /// Handles the PAUSE state
virtual void Pause(); virtual void Pause();
@ -330,9 +401,13 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
/// Signal handler /// Signal handler
void SignalHandler(int signal); void SignalHandler(int signal);
bool fCatchingSignals; bool fCatchingSignals;
bool fTerminated; bool fTerminationRequested;
// Interactive state loop helper // Interactive state loop helper
std::atomic<bool> fRunning; std::atomic<bool> fInteractiveRunning;
bool fDataCallbacks;
std::unordered_map<std::string, InputMsgCallback> fMsgInputs;
std::unordered_map<std::string, InputMultipartCallback> fMultipartInputs;
}; };
#endif /* FAIRMQDEVICE_H_ */ #endif /* FAIRMQDEVICE_H_ */

View File

@ -39,4 +39,6 @@ class FairMQMessage
virtual ~FairMQMessage() {}; virtual ~FairMQMessage() {};
}; };
using FairMQMessagePtr = std::unique_ptr<FairMQMessage>;
#endif /* FAIRMQMESSAGE_H_ */ #endif /* FAIRMQMESSAGE_H_ */

View File

@ -31,7 +31,10 @@
// This #define has to be before any msm header includes // This #define has to be before any msm header includes
#define FUSION_MAX_VECTOR_SIZE 20 #define FUSION_MAX_VECTOR_SIZE 20
#include <boost/mpl/for_each.hpp>
#include <boost/msm/back/state_machine.hpp> #include <boost/msm/back/state_machine.hpp>
#include <boost/msm/back/tools.hpp>
#include <boost/msm/back/metafunctions.hpp>
#include <boost/msm/front/state_machine_def.hpp> #include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp> #include <boost/msm/front/functor_row.hpp>
@ -233,7 +236,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState> template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{ {
LOG(STATE) << "Received STOP event"; LOG(STATE) << "Entering READY state";
fsm.fState = READY; fsm.fState = READY;
@ -288,7 +291,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState> template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{ {
LOG(STATE) << "Received END event"; LOG(STATE) << "Entering EXITING state";
fsm.fState = EXITING; fsm.fState = EXITING;
@ -321,7 +324,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState> template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{ {
LOG(STATE) << "ERROR!"; LOG(STATE) << "Entering ERROR state";
fsm.fState = ERROR; fsm.fState = ERROR;
} }
@ -348,20 +351,20 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
// Start Event Next Action Guard // Start Event Next Action Guard
// +------------------------+----------------------+------------------------+----------------+---------+ // +------------------------+----------------------+------------------------+----------------+---------+
msmf::Row<IDLE_FSM, INIT_DEVICE, INITIALIZING_DEVICE_FSM, InitDeviceFct, msmf::none>, msmf::Row<IDLE_FSM, INIT_DEVICE, INITIALIZING_DEVICE_FSM, InitDeviceFct, msmf::none>,
msmf::Row<IDLE_FSM, END, EXITING_FSM, ExitingFct, msmf::none>,
msmf::Row<INITIALIZING_DEVICE_FSM, internal_DEVICE_READY, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>, msmf::Row<INITIALIZING_DEVICE_FSM, internal_DEVICE_READY, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
msmf::Row<DEVICE_READY_FSM, INIT_TASK, INITIALIZING_TASK_FSM, InitTaskFct, msmf::none>, msmf::Row<DEVICE_READY_FSM, INIT_TASK, INITIALIZING_TASK_FSM, InitTaskFct, msmf::none>,
msmf::Row<DEVICE_READY_FSM, RESET_DEVICE, RESETTING_DEVICE_FSM, ResetDeviceFct, msmf::none>,
msmf::Row<INITIALIZING_TASK_FSM, internal_READY, READY_FSM, ReadyFct, msmf::none>, msmf::Row<INITIALIZING_TASK_FSM, internal_READY, READY_FSM, ReadyFct, msmf::none>,
msmf::Row<READY_FSM, RUN, RUNNING_FSM, RunFct, msmf::none>, msmf::Row<READY_FSM, RUN, RUNNING_FSM, RunFct, msmf::none>,
msmf::Row<READY_FSM, RESET_TASK, RESETTING_TASK_FSM, ResetTaskFct, msmf::none>,
msmf::Row<RUNNING_FSM, PAUSE, PAUSED_FSM, PauseFct, msmf::none>, msmf::Row<RUNNING_FSM, PAUSE, PAUSED_FSM, PauseFct, msmf::none>,
msmf::Row<PAUSED_FSM, RUN, RUNNING_FSM, ResumeFct, msmf::none>,
msmf::Row<RUNNING_FSM, STOP, READY_FSM, StopFct, msmf::none>, msmf::Row<RUNNING_FSM, STOP, READY_FSM, StopFct, msmf::none>,
msmf::Row<RUNNING_FSM, internal_READY, READY_FSM, InternalStopFct, msmf::none>, msmf::Row<RUNNING_FSM, internal_READY, READY_FSM, InternalStopFct, msmf::none>,
msmf::Row<READY_FSM, RESET_TASK, RESETTING_TASK_FSM, ResetTaskFct, msmf::none>,
msmf::Row<RESETTING_TASK_FSM, internal_DEVICE_READY, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
msmf::Row<DEVICE_READY_FSM, RESET_DEVICE, RESETTING_DEVICE_FSM, ResetDeviceFct, msmf::none>,
msmf::Row<RESETTING_DEVICE_FSM, internal_IDLE, IDLE_FSM, IdleFct, msmf::none>,
msmf::Row<RUNNING_FSM, END, EXITING_FSM, ExitingRunFct, msmf::none>, msmf::Row<RUNNING_FSM, END, EXITING_FSM, ExitingRunFct, msmf::none>,
msmf::Row<IDLE_FSM, END, EXITING_FSM, ExitingFct, msmf::none>, msmf::Row<PAUSED_FSM, RUN, RUNNING_FSM, ResumeFct, msmf::none>,
msmf::Row<RESETTING_TASK_FSM, internal_DEVICE_READY, DEVICE_READY_FSM, DeviceReadyFct, msmf::none>,
msmf::Row<RESETTING_DEVICE_FSM, internal_IDLE, IDLE_FSM, IdleFct, msmf::none>,
msmf::Row<OK_FSM, ERROR_FOUND, ERROR_FSM, ErrorFoundFct, msmf::none>> msmf::Row<OK_FSM, ERROR_FOUND, ERROR_FSM, ErrorFoundFct, msmf::none>>
{}; {};
@ -369,7 +372,25 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class FSM, class Event> template <class FSM, class Event>
void no_transition(Event const& e, FSM&, int state) void no_transition(Event const& e, FSM&, int state)
{ {
LOG(STATE) << "no transition from state " << GetStateName(state) << " (" << state << ") on event " << e.name(); typedef typename boost::msm::back::recursive_get_transition_table<FSM>::type recursive_stt;
typedef typename boost::msm::back::generate_state_set<recursive_stt>::type all_states;
std::string stateName;
boost::mpl::for_each<all_states,boost::msm::wrap<boost::mpl::placeholders::_1> >(boost::msm::back::get_state_name<recursive_stt>(stateName, state));
stateName = stateName.substr(24);
std::size_t pos = stateName.find("_FSME");
stateName.erase(pos);
if (stateName == "1RUNNING" || stateName == "6DEVICE_READY" || stateName == "0PAUSED")
{
stateName = stateName.substr(1);
}
if (stateName != "OK")
{
LOG(STATE) << "No transition from state " << stateName << " on event " << e.name();
}
// LOG(STATE) << "no transition from state " << GetStateName(state) << " (" << state << ") on event " << e.name();
} }
// backward compatibility to FairMQStateMachine // backward compatibility to FairMQStateMachine
@ -461,7 +482,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
boost::thread fTerminateStateThread; boost::thread fTerminateStateThread;
// condition variable to notify parent thread about end of state. // condition variable to notify parent thread about end of state.
bool fStateFinished; std::atomic<bool> fStateFinished;
boost::condition_variable fStateCondition; boost::condition_variable fStateCondition;
boost::mutex fStateMutex; boost::mutex fStateMutex;

View File

@ -30,15 +30,15 @@ class FairMQChannel;
class FairMQTransportFactory class FairMQTransportFactory
{ {
public: public:
virtual FairMQMessage* CreateMessage() = 0; virtual FairMQMessage* CreateMessage() const = 0;
virtual FairMQMessage* CreateMessage(const size_t size) = 0; virtual FairMQMessage* CreateMessage(const size_t size) const = 0;
virtual FairMQMessage* CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = NULL) = 0; virtual FairMQMessage* CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = NULL) const = 0;
virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, const int numIoThreads, const std::string& id = "") = 0; virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, const int numIoThreads, const std::string& id = "") const = 0;
virtual FairMQPoller* CreatePoller(const std::vector<FairMQChannel>& channels) = 0; virtual FairMQPoller* CreatePoller(const std::vector<FairMQChannel>& channels) const = 0;
virtual FairMQPoller* CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList) = 0; virtual FairMQPoller* CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const = 0;
virtual FairMQPoller* CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) = 0; virtual FairMQPoller* CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) const = 0;
virtual ~FairMQTransportFactory() {}; virtual ~FairMQTransportFactory() {};
}; };

View File

@ -35,8 +35,33 @@ The communication layer is available through an interface. Two interface impleme
![FairMQ transport interface](../docs/images/fairmq-transport-interface.png?raw=true "FairMQ transport interface") ![FairMQ transport interface](../docs/images/fairmq-transport-interface.png?raw=true "FairMQ transport interface")
## State Machine
Each FairMQ device has an internal state machine:
![FairMQ state machine](../docs/images/fairmq-states.png?raw=true "FairMQ state machine")
The state machine can be querried and controlled via `GetCurrentStateName()` and `ChangeState("<state name>")` methods. Only legal state transitions are allowed (see image above). Illegal transitions will fail with an error.
If the device is running in interactive mode (default), states can be changed via keyboard input:
- `'h'` - help
- `'p'` - pause
- `'r'` - run
- `'s'` - stop
- `'t'` - reset task
- `'d'` - reset device
- `'q'` - end
- `'j'` - init task
- `'i'` - init device
Without the interactive mode, for example for a run in background, two other control mechanisms are available:
- static (`--control static`) - device goes through a simple init -> run -> reset -> exit chain.
- dds (`--control dds`) - device is controled by external command, in this case using dds commands (fairmq-dds-command-ui).
## Examples ## Examples
A collection of simple examples in `examples` directory demonstrates some common usage patterns of FairMQ. A collection of simple examples in `FairRoot/examples/MQ` directory demonstrates some common usage patterns of FairMQ.
A number of devices to handle the data from the Tutorial3 FairTestDetector of FairRoot are provided as an example and can be found in `FairRoot/base/MQ` directory. The implementation of the tasks run by these devices can be found `FairRoot/example/Tutorial3`. The implementation includes sending raw binary data as well as serializing the data with either [Boost Serialization](http://www.boost.org/doc/libs/release/libs/serialization/), [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) or [Root TMessage](http://root.cern.ch/root/html/TMessage.html). Following the examples you can implement your own devices to transport arbitrary data. A number of devices to handle the data from the Tutorial3 FairTestDetector of FairRoot are provided as an example and can be found in `FairRoot/base/MQ` directory. The implementation of the tasks run by these devices can be found `FairRoot/examples/advanced/Tutorial3`. The implementation includes sending raw binary data as well as serializing the data with either [Boost Serialization](http://www.boost.org/doc/libs/release/libs/serialization/), [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) or [Root TMessage](http://root.cern.ch/root/html/TMessage.html). Following the examples you can implement your own devices to transport arbitrary data.

View File

@ -20,6 +20,7 @@
#include "FairMQBenchmarkSampler.h" #include "FairMQBenchmarkSampler.h"
#include "FairMQLogger.h" #include "FairMQLogger.h"
#include "FairMQProgOptions.h"
using namespace std; using namespace std;
@ -28,6 +29,7 @@ FairMQBenchmarkSampler::FairMQBenchmarkSampler()
, fNumMsgs(0) , fNumMsgs(0)
, fMsgCounter(0) , fMsgCounter(0)
, fMsgRate(1) , fMsgRate(1)
, fOutChannelName()
{ {
} }
@ -35,146 +37,79 @@ FairMQBenchmarkSampler::~FairMQBenchmarkSampler()
{ {
} }
void FairMQBenchmarkSampler::InitTask()
{
fMsgSize = fConfig->GetValue<int>("msg-size");
fNumMsgs = fConfig->GetValue<int>("num-msgs");
fMsgRate = fConfig->GetValue<int>("msg-rate");
fOutChannelName = fConfig->GetValue<string>("out-channel");
}
void FairMQBenchmarkSampler::Run() void FairMQBenchmarkSampler::Run()
{ {
boost::thread resetMsgCounter(boost::bind(&FairMQBenchmarkSampler::ResetMsgCounter, this)); // boost::thread resetMsgCounter(boost::bind(&FairMQBenchmarkSampler::ResetMsgCounter, this));
int numSentMsgs = 0; int numSentMsgs = 0;
unique_ptr<FairMQMessage> baseMsg(fTransportFactory->CreateMessage(fMsgSize)); FairMQMessagePtr baseMsg(fTransportFactory->CreateMessage(fMsgSize));
// store the channel reference to avoid traversing the map on every loop iteration // store the channel reference to avoid traversing the map on every loop iteration
const FairMQChannel& dataOutChannel = fChannels.at("data-out").at(0); const FairMQChannel& dataOutChannel = fChannels.at(fOutChannelName).at(0);
LOG(INFO) << "Starting the benchmark with message size of " << fMsgSize << " and number of messages " << fNumMsgs << "."; LOG(INFO) << "Starting the benchmark with message size of " << fMsgSize << " and number of messages " << fNumMsgs << ".";
boost::timer::auto_cpu_timer timer; boost::timer::auto_cpu_timer timer;
while (CheckCurrentState(RUNNING)) while (CheckCurrentState(RUNNING))
{ {
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage()); FairMQMessagePtr msg(fTransportFactory->CreateMessage());
msg->Copy(baseMsg); msg->Copy(baseMsg);
if (dataOutChannel.Send(msg) >= 0) if (dataOutChannel.Send(msg) >= 0)
{ {
if (fNumMsgs > 0) if (fNumMsgs > 0)
{ {
numSentMsgs++; if (++numSentMsgs >= fNumMsgs)
if (numSentMsgs >= fNumMsgs)
{ {
break; break;
} }
} }
} }
--fMsgCounter; // --fMsgCounter;
while (fMsgCounter == 0) { // while (fMsgCounter == 0) {
boost::this_thread::sleep(boost::posix_time::milliseconds(1)); // boost::this_thread::sleep(boost::posix_time::milliseconds(1));
} // }
} }
LOG(INFO) << "Sent " << numSentMsgs << " messages, leaving RUNNING state."; LOG(INFO) << "Sent " << numSentMsgs << " messages, leaving RUNNING state.";
LOG(INFO) << "Sending time: "; LOG(INFO) << "Sending time: ";
try // try
{ // {
resetMsgCounter.interrupt(); // resetMsgCounter.interrupt();
resetMsgCounter.join(); // resetMsgCounter.join();
} // }
catch(boost::thread_resource_error& e) // catch(boost::thread_resource_error& e)
{ // {
LOG(ERROR) << e.what(); // LOG(ERROR) << e.what();
exit(EXIT_FAILURE); // exit(EXIT_FAILURE);
} // }
} }
void FairMQBenchmarkSampler::ResetMsgCounter() void FairMQBenchmarkSampler::ResetMsgCounter()
{ {
while (true) { while (true)
try { {
try
{
fMsgCounter = fMsgRate / 100; fMsgCounter = fMsgRate / 100;
boost::this_thread::sleep(boost::posix_time::milliseconds(10)); boost::this_thread::sleep(boost::posix_time::milliseconds(10));
} catch (boost::thread_interrupted&) { }
catch (boost::thread_interrupted&)
{
LOG(DEBUG) << "Event rate limiter thread interrupted"; LOG(DEBUG) << "Event rate limiter thread interrupted";
break; break;
} }
} }
} }
void FairMQBenchmarkSampler::SetProperty(const int key, const string& value)
{
switch (key)
{
default:
FairMQDevice::SetProperty(key, value);
break;
}
}
string FairMQBenchmarkSampler::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{
default:
return FairMQDevice::GetProperty(key, default_);
}
}
void FairMQBenchmarkSampler::SetProperty(const int key, const int value)
{
switch (key)
{
case MsgSize:
fMsgSize = value;
break;
case MsgRate:
fMsgRate = value;
break;
case NumMsgs:
fNumMsgs = value;
break;
default:
FairMQDevice::SetProperty(key, value);
break;
}
}
int FairMQBenchmarkSampler::GetProperty(const int key, const int default_ /*= 0*/)
{
switch (key)
{
case MsgSize:
return fMsgSize;
case MsgRate:
return fMsgRate;
case NumMsgs:
return fNumMsgs;
default:
return FairMQDevice::GetProperty(key, default_);
}
}
string FairMQBenchmarkSampler::GetPropertyDescription(const int key)
{
switch (key)
{
case MsgSize:
return "MsgSize: Size of the transfered message buffer.";
case NumMsgs:
return "NumMsgs: Number of messages to send.";
case MsgRate:
return "MsgRate: Maximum msg rate.";
default:
return FairMQDevice::GetPropertyDescription(key);
}
}
void FairMQBenchmarkSampler::ListProperties()
{
LOG(INFO) << "Properties of FairMQBenchmarkSampler:";
for (int p = FairMQConfigurable::Last; p < FairMQBenchmarkSampler::Last; ++p)
{
LOG(INFO) << " " << GetPropertyDescription(p);
}
LOG(INFO) << "---------------------------";
}

View File

@ -26,33 +26,19 @@
class FairMQBenchmarkSampler : public FairMQDevice class FairMQBenchmarkSampler : public FairMQDevice
{ {
public: public:
enum
{
MsgSize = FairMQDevice::Last,
NumMsgs,
MsgRate,
Last
};
FairMQBenchmarkSampler(); FairMQBenchmarkSampler();
virtual ~FairMQBenchmarkSampler(); virtual ~FairMQBenchmarkSampler();
void ResetMsgCounter(); void ResetMsgCounter();
virtual void SetProperty(const int key, const std::string& value);
virtual std::string GetProperty(const int key, const std::string& default_ = "");
virtual void SetProperty(const int key, const int value);
virtual int GetProperty(const int key, const int default_ = 0);
virtual std::string GetPropertyDescription(const int key);
virtual void ListProperties();
protected: protected:
int fMsgSize; int fMsgSize;
int fNumMsgs; int fNumMsgs;
int fMsgCounter; int fMsgCounter;
int fMsgRate; int fMsgRate;
std::string fOutChannelName;
virtual void InitTask();
virtual void Run(); virtual void Run();
}; };

View File

@ -12,17 +12,17 @@
* @author D. Klein, A. Rybalchenko * @author D. Klein, A. Rybalchenko
*/ */
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "FairMQLogger.h" #include "FairMQLogger.h"
#include "FairMQMerger.h" #include "FairMQMerger.h"
#include "FairMQPoller.h" #include "FairMQPoller.h"
#include "FairMQProgOptions.h"
using namespace std; using namespace std;
FairMQMerger::FairMQMerger() FairMQMerger::FairMQMerger()
: fMultipart(1) : fMultipart(1)
, fInChannelName()
, fOutChannelName()
{ {
} }
@ -30,11 +30,18 @@ FairMQMerger::~FairMQMerger()
{ {
} }
void FairMQMerger::InitTask()
{
fMultipart = fConfig->GetValue<int>("multipart");
fInChannelName = fConfig->GetValue<string>("in-channel");
fOutChannelName = fConfig->GetValue<string>("out-channel");
}
void FairMQMerger::Run() void FairMQMerger::Run()
{ {
int numInputs = fChannels.at("data-in").size(); int numInputs = fChannels.at(fInChannelName).size();
std::unique_ptr<FairMQPoller> poller(fTransportFactory->CreatePoller(fChannels.at("data-in"))); std::unique_ptr<FairMQPoller> poller(fTransportFactory->CreatePoller(fChannels.at(fInChannelName)));
if (fMultipart) if (fMultipart)
{ {
@ -50,9 +57,9 @@ void FairMQMerger::Run()
{ {
FairMQParts payload; FairMQParts payload;
if (Receive(payload, "data-in", i) >= 0) if (Receive(payload, fInChannelName, i) >= 0)
{ {
if (Send(payload, "data-out") < 0) if (Send(payload, fOutChannelName) < 0)
{ {
LOG(DEBUG) << "Transfer interrupted"; LOG(DEBUG) << "Transfer interrupted";
break; break;
@ -79,11 +86,11 @@ void FairMQMerger::Run()
// Check if the channel has data ready to be received. // Check if the channel has data ready to be received.
if (poller->CheckInput(i)) if (poller->CheckInput(i))
{ {
unique_ptr<FairMQMessage> payload(fTransportFactory->CreateMessage()); FairMQMessagePtr payload(fTransportFactory->CreateMessage());
if (Receive(payload, "data-in", i) >= 0) if (Receive(payload, fInChannelName, i) >= 0)
{ {
if (Send(payload, "data-out") < 0) if (Send(payload, fOutChannelName) < 0)
{ {
LOG(DEBUG) << "Transfer interrupted"; LOG(DEBUG) << "Transfer interrupted";
break; break;
@ -99,67 +106,3 @@ void FairMQMerger::Run()
} }
} }
} }
void FairMQMerger::SetProperty(const int key, const string& value)
{
switch (key)
{
default:
FairMQDevice::SetProperty(key, value);
break;
}
}
string FairMQMerger::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{
default:
return FairMQDevice::GetProperty(key, default_);
}
}
void FairMQMerger::SetProperty(const int key, const int value)
{
switch (key)
{
case Multipart:
fMultipart = value;
break;
default:
FairMQDevice::SetProperty(key, value);
break;
}
}
int FairMQMerger::GetProperty(const int key, const int default_ /*= 0*/)
{
switch (key)
{
case Multipart:
return fMultipart;
default:
return FairMQDevice::GetProperty(key, default_);
}
}
string FairMQMerger::GetPropertyDescription(const int key)
{
switch (key)
{
case Multipart:
return "Multipart: Handle payloads as multipart messages.";
default:
return FairMQDevice::GetPropertyDescription(key);
}
}
void FairMQMerger::ListProperties()
{
LOG(INFO) << "Properties of FairMQMerger:";
for (int p = FairMQConfigurable::Last; p < FairMQMerger::Last; ++p)
{
LOG(INFO) << " " << GetPropertyDescription(p);
}
LOG(INFO) << "---------------------------";
}

View File

@ -17,30 +17,21 @@
#include "FairMQDevice.h" #include "FairMQDevice.h"
#include <string>
class FairMQMerger : public FairMQDevice class FairMQMerger : public FairMQDevice
{ {
public: public:
enum
{
Multipart = FairMQDevice::Last,
Last
};
FairMQMerger(); FairMQMerger();
virtual ~FairMQMerger(); virtual ~FairMQMerger();
virtual void SetProperty(const int key, const std::string& value);
virtual std::string GetProperty(const int key, const std::string& default_ = "");
virtual void SetProperty(const int key, const int value);
virtual int GetProperty(const int key, const int default_ = 0);
virtual std::string GetPropertyDescription(const int key);
virtual void ListProperties();
protected: protected:
int fMultipart; int fMultipart;
std::string fInChannelName;
std::string fOutChannelName;
virtual void Run(); virtual void Run();
virtual void InitTask();
}; };
#endif /* FAIRMQMERGER_H_ */ #endif /* FAIRMQMERGER_H_ */

View File

@ -0,0 +1,110 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "FairMQLogger.h"
#include "FairMQMultiplier.h"
#include "FairMQProgOptions.h"
using namespace std;
FairMQMultiplier::FairMQMultiplier()
: fMultipart(1)
, fNumOutputs(0)
, fInChannelName()
, fOutChannelNames()
{
}
FairMQMultiplier::~FairMQMultiplier()
{
}
void FairMQMultiplier::InitTask()
{
fMultipart = fConfig->GetValue<int>("multipart");
fInChannelName = fConfig->GetValue<string>("in-channel");
fOutChannelNames = fConfig->GetValue<vector<string>>("out-channel");
fNumOutputs = fChannels.at(fOutChannelNames.at(0)).size();
if (fMultipart)
{
OnData(fInChannelName, &FairMQMultiplier::HandleMultipartData);
}
else
{
OnData(fInChannelName, &FairMQMultiplier::HandleSingleData);
}
}
bool FairMQMultiplier::HandleSingleData(std::unique_ptr<FairMQMessage>& payload, int /*index*/)
{
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) // all except last channel
{
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) // all subChannels in a channel
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload);
Send(msgCopy, fOutChannelNames.at(i), j);
}
}
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size();
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) // iterate over all except last subChannels of the last channel
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload);
Send(msgCopy, fOutChannelNames.back(), i);
}
Send(payload, fOutChannelNames.back(), lastChannelSize - 1); // send final message to last subChannel of last channel
return true;
}
bool FairMQMultiplier::HandleMultipartData(FairMQParts& payload, int /*index*/)
{
for (unsigned int i = 0; i < fOutChannelNames.size() - 1; ++i) // all except last channel
{
for (unsigned int j = 0; j < fChannels.at(fOutChannelNames.at(i)).size(); ++j) // all subChannels in a channel
{
FairMQParts parts;
for (int k = 0; k < payload.Size(); ++k)
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.At(k));
parts.AddPart(msgCopy);
}
Send(parts, fOutChannelNames.at(i), j);
}
}
unsigned int lastChannelSize = fChannels.at(fOutChannelNames.back()).size();
for (unsigned int i = 0; i < lastChannelSize - 1; ++i) // iterate over all except last subChannels of the last channel
{
FairMQParts parts;
for (int k = 0; k < payload.Size(); ++k)
{
FairMQMessagePtr msgCopy(fTransportFactory->CreateMessage());
msgCopy->Copy(payload.At(k));
parts.AddPart(msgCopy);
}
Send(parts, fOutChannelNames.back(), i);
}
Send(payload, fOutChannelNames.back(), lastChannelSize - 1); // send final message to last subChannel of last channel
return true;
}

View File

@ -0,0 +1,34 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIRMQMULTIPLIER_H_
#define FAIRMQMULTIPLIER_H_
#include "FairMQDevice.h"
#include <string>
class FairMQMultiplier : public FairMQDevice
{
public:
FairMQMultiplier();
virtual ~FairMQMultiplier();
protected:
int fMultipart;
int fNumOutputs;
std::string fInChannelName;
std::vector<std::string> fOutChannelNames;
virtual void InitTask();
bool HandleSingleData(std::unique_ptr<FairMQMessage>&, int);
bool HandleMultipartData(FairMQParts&, int);
};
#endif /* FAIRMQMULTIPLIER_H_ */

View File

@ -12,16 +12,16 @@
* @author A. Rybalchenko * @author A. Rybalchenko
*/ */
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "FairMQLogger.h" #include "FairMQLogger.h"
#include "FairMQProxy.h" #include "FairMQProxy.h"
#include "FairMQProgOptions.h"
using namespace std; using namespace std;
FairMQProxy::FairMQProxy() FairMQProxy::FairMQProxy()
: fMultipart(1) : fMultipart(1)
, fInChannelName()
, fOutChannelName()
{ {
} }
@ -29,6 +29,13 @@ FairMQProxy::~FairMQProxy()
{ {
} }
void FairMQProxy::InitTask()
{
fMultipart = fConfig->GetValue<int>("multipart");
fInChannelName = fConfig->GetValue<string>("in-channel");
fOutChannelName = fConfig->GetValue<string>("out-channel");
}
void FairMQProxy::Run() void FairMQProxy::Run()
{ {
if (fMultipart) if (fMultipart)
@ -36,9 +43,9 @@ void FairMQProxy::Run()
while (CheckCurrentState(RUNNING)) while (CheckCurrentState(RUNNING))
{ {
FairMQParts payload; FairMQParts payload;
if (Receive(payload, "data-in") >= 0) if (Receive(payload, fInChannelName) >= 0)
{ {
if (Send(payload, "data-out") < 0) if (Send(payload, fOutChannelName) < 0)
{ {
LOG(DEBUG) << "Transfer interrupted"; LOG(DEBUG) << "Transfer interrupted";
break; break;
@ -56,9 +63,9 @@ void FairMQProxy::Run()
while (CheckCurrentState(RUNNING)) while (CheckCurrentState(RUNNING))
{ {
unique_ptr<FairMQMessage> payload(fTransportFactory->CreateMessage()); unique_ptr<FairMQMessage> payload(fTransportFactory->CreateMessage());
if (Receive(payload, "data-in") >= 0) if (Receive(payload, fInChannelName) >= 0)
{ {
if (Send(payload, "data-out") < 0) if (Send(payload, fOutChannelName) < 0)
{ {
LOG(DEBUG) << "Transfer interrupted"; LOG(DEBUG) << "Transfer interrupted";
break; break;

View File

@ -17,6 +17,8 @@
#include "FairMQDevice.h" #include "FairMQDevice.h"
#include <string>
class FairMQProxy : public FairMQDevice class FairMQProxy : public FairMQDevice
{ {
public: public:
@ -39,8 +41,11 @@ class FairMQProxy : public FairMQDevice
protected: protected:
int fMultipart; int fMultipart;
std::string fInChannelName;
std::string fOutChannelName;
virtual void Run(); virtual void Run();
virtual void InitTask();
}; };
#endif /* FAIRMQPROXY_H_ */ #endif /* FAIRMQPROXY_H_ */

View File

@ -12,25 +12,31 @@
* @author D. Klein, A. Rybalchenko * @author D. Klein, A. Rybalchenko
*/ */
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/timer/timer.hpp> #include <boost/timer/timer.hpp>
#include "FairMQSink.h" #include "FairMQSink.h"
#include "FairMQLogger.h" #include "FairMQLogger.h"
#include "FairMQProgOptions.h"
using namespace std; using namespace std;
FairMQSink::FairMQSink() FairMQSink::FairMQSink()
: fNumMsgs(0) : fNumMsgs(0)
, fInChannelName()
{ {
} }
void FairMQSink::InitTask()
{
fNumMsgs = fConfig->GetValue<int>("num-msgs");
fInChannelName = fConfig->GetValue<string>("in-channel");
}
void FairMQSink::Run() void FairMQSink::Run()
{ {
int numReceivedMsgs = 0; int numReceivedMsgs = 0;
// store the channel reference to avoid traversing the map on every loop iteration // store the channel reference to avoid traversing the map on every loop iteration
const FairMQChannel& dataInChannel = fChannels.at("data-in").at(0); const FairMQChannel& dataInChannel = fChannels.at(fInChannelName).at(0);
LOG(INFO) << "Starting the benchmark and expecting to receive " << fNumMsgs << " messages."; LOG(INFO) << "Starting the benchmark and expecting to receive " << fNumMsgs << " messages.";
boost::timer::auto_cpu_timer timer; boost::timer::auto_cpu_timer timer;
@ -59,67 +65,3 @@ void FairMQSink::Run()
FairMQSink::~FairMQSink() FairMQSink::~FairMQSink()
{ {
} }
void FairMQSink::SetProperty(const int key, const string& value)
{
switch (key)
{
default:
FairMQDevice::SetProperty(key, value);
break;
}
}
string FairMQSink::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{
default:
return FairMQDevice::GetProperty(key, default_);
}
}
void FairMQSink::SetProperty(const int key, const int value)
{
switch (key)
{
case NumMsgs:
fNumMsgs = value;
break;
default:
FairMQDevice::SetProperty(key, value);
break;
}
}
int FairMQSink::GetProperty(const int key, const int default_ /*= 0*/)
{
switch (key)
{
case NumMsgs:
return fNumMsgs;
default:
return FairMQDevice::GetProperty(key, default_);
}
}
string FairMQSink::GetPropertyDescription(const int key)
{
switch (key)
{
case NumMsgs:
return "NumMsgs: Number of messages to send.";
default:
return FairMQDevice::GetPropertyDescription(key);
}
}
void FairMQSink::ListProperties()
{
LOG(INFO) << "Properties of FairMQSink:";
for (int p = FairMQConfigurable::Last; p < FairMQSink::Last; ++p)
{
LOG(INFO) << " " << GetPropertyDescription(p);
}
LOG(INFO) << "---------------------------";
}

View File

@ -22,27 +22,15 @@
class FairMQSink : public FairMQDevice class FairMQSink : public FairMQDevice
{ {
public: public:
enum
{
NumMsgs = FairMQDevice::Last,
Last
};
FairMQSink(); FairMQSink();
virtual ~FairMQSink(); virtual ~FairMQSink();
virtual void SetProperty(const int key, const std::string& value);
virtual std::string GetProperty(const int key, const std::string& default_ = "");
virtual void SetProperty(const int key, const int value);
virtual int GetProperty(const int key, const int default_ = 0);
virtual std::string GetPropertyDescription(const int key);
virtual void ListProperties();
protected: protected:
int fNumMsgs; int fNumMsgs;
std::string fInChannelName;
virtual void Run(); virtual void Run();
virtual void InitTask();
}; };
#endif /* FAIRMQSINK_H_ */ #endif /* FAIRMQSINK_H_ */

View File

@ -12,16 +12,18 @@
* @author D. Klein, A. Rybalchenko * @author D. Klein, A. Rybalchenko
*/ */
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "FairMQLogger.h" #include "FairMQLogger.h"
#include "FairMQSplitter.h" #include "FairMQSplitter.h"
#include "FairMQProgOptions.h"
using namespace std; using namespace std;
FairMQSplitter::FairMQSplitter() FairMQSplitter::FairMQSplitter()
: fMultipart(1) : fMultipart(1)
, fNumOutputs(0)
, fDirection(0)
, fInChannelName()
, fOutChannelName()
{ {
} }
@ -29,129 +31,44 @@ FairMQSplitter::~FairMQSplitter()
{ {
} }
void FairMQSplitter::Run() void FairMQSplitter::InitTask()
{ {
int numOutputs = fChannels.at("data-out").size(); fMultipart = fConfig->GetValue<int>("multipart");
fInChannelName = fConfig->GetValue<string>("in-channel");
int direction = 0; fOutChannelName = fConfig->GetValue<string>("out-channel");
fNumOutputs = fChannels.at(fOutChannelName).size();
fDirection = 0;
if (fMultipart) if (fMultipart)
{ {
while (CheckCurrentState(RUNNING)) OnData(fInChannelName, &FairMQSplitter::HandleMultipartData);
{
FairMQParts payload;
if (Receive(payload, "data-in") >= 0)
{
if (Send(payload, "data-out", direction) < 0)
{
LOG(DEBUG) << "Transfer interrupted";
break;
}
} }
else else
{ {
LOG(DEBUG) << "Transfer interrupted"; OnData(fInChannelName, &FairMQSplitter::HandleSingleData);
break;
}
++direction;
if (direction >= numOutputs)
{
direction = 0;
}
}
}
else
{
while (CheckCurrentState(RUNNING))
{
unique_ptr<FairMQMessage> payload(fTransportFactory->CreateMessage());
if (Receive(payload, "data-in") >= 0)
{
if (Send(payload, "data-out", direction) < 0)
{
LOG(DEBUG) << "Transfer interrupted";
break;
}
}
else
{
LOG(DEBUG) << "Transfer interrupted";
break;
}
++direction;
if (direction >= numOutputs)
{
direction = 0;
}
}
} }
} }
void FairMQSplitter::SetProperty(const int key, const string& value) bool FairMQSplitter::HandleSingleData(FairMQMessagePtr& payload, int /*index*/)
{ {
switch (key) Send(payload, fOutChannelName, fDirection);
if (++fDirection >= fNumOutputs)
{ {
default: fDirection = 0;
FairMQDevice::SetProperty(key, value);
break;
}
} }
string FairMQSplitter::GetProperty(const int key, const string& default_ /*= ""*/) return true;
{
switch (key)
{
default:
return FairMQDevice::GetProperty(key, default_);
}
} }
void FairMQSplitter::SetProperty(const int key, const int value) bool FairMQSplitter::HandleMultipartData(FairMQParts& payload, int /*index*/)
{ {
switch (key) Send(payload, fOutChannelName, fDirection);
if (++fDirection >= fNumOutputs)
{ {
case Multipart: fDirection = 0;
fMultipart = value;
break;
default:
FairMQDevice::SetProperty(key, value);
break;
}
} }
int FairMQSplitter::GetProperty(const int key, const int default_ /*= 0*/) return true;
{
switch (key)
{
case Multipart:
return fMultipart;
default:
return FairMQDevice::GetProperty(key, default_);
} }
}
string FairMQSplitter::GetPropertyDescription(const int key)
{
switch (key)
{
case Multipart:
return "Multipart: Handle payloads as multipart messages.";
default:
return FairMQDevice::GetPropertyDescription(key);
}
}
void FairMQSplitter::ListProperties()
{
LOG(INFO) << "Properties of FairMQSplitter:";
for (int p = FairMQConfigurable::Last; p < FairMQSplitter::Last; ++p)
{
LOG(INFO) << " " << GetPropertyDescription(p);
}
LOG(INFO) << "---------------------------";
}

View File

@ -17,30 +17,25 @@
#include "FairMQDevice.h" #include "FairMQDevice.h"
#include <string>
class FairMQSplitter : public FairMQDevice class FairMQSplitter : public FairMQDevice
{ {
public: public:
enum
{
Multipart = FairMQDevice::Last,
Last
};
FairMQSplitter(); FairMQSplitter();
virtual ~FairMQSplitter(); virtual ~FairMQSplitter();
virtual void SetProperty(const int key, const std::string& value);
virtual std::string GetProperty(const int key, const std::string& default_ = "");
virtual void SetProperty(const int key, const int value);
virtual int GetProperty(const int key, const int default_ = 0);
virtual std::string GetPropertyDescription(const int key);
virtual void ListProperties();
protected: protected:
int fMultipart; int fMultipart;
int fNumOutputs;
int fDirection;
std::string fInChannelName;
std::string fOutChannelName;
virtual void Run(); virtual void InitTask();
bool HandleSingleData(std::unique_ptr<FairMQMessage>&, int);
bool HandleMultipartData(FairMQParts&, int);
}; };
#endif /* FAIRMQSPLITTER_H_ */ #endif /* FAIRMQSPLITTER_H_ */

View File

@ -33,7 +33,6 @@ namespace expr = boost::log::expressions;
namespace sinks = boost::log::sinks; namespace sinks = boost::log::sinks;
namespace attrs = boost::log::attributes; namespace attrs = boost::log::attributes;
BOOST_LOG_GLOBAL_LOGGER_INIT(global_logger, src::severity_logger_mt) BOOST_LOG_GLOBAL_LOGGER_INIT(global_logger, src::severity_logger_mt)
{ {
src::severity_logger_mt<custom_severity_level> global_logger; src::severity_logger_mt<custom_severity_level> global_logger;
@ -42,25 +41,26 @@ BOOST_LOG_GLOBAL_LOGGER_INIT(global_logger, src::severity_logger_mt)
return global_logger; return global_logger;
} }
namespace FairMQ
{
namespace Logger
namespace FairMQ{ {
namespace Logger{
std::vector<boost::shared_ptr<boost::log::sinks::basic_sink_frontend>> sinkList;// global var std::vector<boost::shared_ptr<boost::log::sinks::basic_sink_frontend>> sinkList;// global var
}}//end namespace } // end Logger namespace
} // end FairMQ namespace
void RemoveRegisteredSinks() void RemoveRegisteredSinks()
{ {
if (FairMQ::Logger::sinkList.size() > 0) if (FairMQ::Logger::sinkList.size() > 0)
{ {
for (const auto& sink : FairMQ::Logger::sinkList) for (const auto& sink : FairMQ::Logger::sinkList)
{
logging::core::get()->remove_sink(sink); logging::core::get()->remove_sink(sink);
}
FairMQ::Logger::sinkList.clear(); FairMQ::Logger::sinkList.clear();
} }
} }
void reinit_logger(bool color, const std::string& filename, custom_severity_level threshold) void reinit_logger(bool color, const std::string& filename, custom_severity_level threshold)
{ {
BOOST_LOG_SEV(global_logger::get(), custom_severity_level::NOLOG) << ""; BOOST_LOG_SEV(global_logger::get(), custom_severity_level::NOLOG) << "";
@ -73,7 +73,6 @@ namespace Logger{
DefaultAddFileSink(filename, threshold); DefaultAddFileSink(filename, threshold);
} }
} }
} }
// console sink related functions // console sink related functions
@ -124,7 +123,6 @@ namespace Logger{
int DefaultConsoleSetFilter(custom_severity_level threshold) int DefaultConsoleSetFilter(custom_severity_level threshold)
{ {
if (FairMQ::Logger::sinkList.size()>=2) if (FairMQ::Logger::sinkList.size()>=2)
{ {
FairMQ::Logger::sinkList.at(0)->set_filter([threshold](const boost::log::attribute_value_set& attr_set) FairMQ::Logger::sinkList.at(0)->set_filter([threshold](const boost::log::attribute_value_set& attr_set)
@ -150,10 +148,7 @@ namespace Logger{
return 0; return 0;
} }
// file sink related functions // file sink related functions
void DefaultAddFileSink(const std::string& filename, custom_severity_level threshold) void DefaultAddFileSink(const std::string& filename, custom_severity_level threshold)
{ {
// add a text sink // add a text sink
@ -176,7 +171,4 @@ namespace Logger{
boost::log::keywords::auto_flush = true boost::log::keywords::auto_flush = true
//keywords::time_based_rotation = &is_it_time_to_rotate //keywords::time_based_rotation = &is_it_time_to_rotate
); );
} }

View File

@ -22,8 +22,9 @@
#include <boost/log/utility/manipulators/to_log.hpp> #include <boost/log/utility/manipulators/to_log.hpp>
#include <boost/log/sources/record_ostream.hpp> #include <boost/log/sources/record_ostream.hpp>
namespace fairmq namespace FairMQ
{ {
enum severity_level enum severity_level
{ {
TRACE, TRACE,
@ -50,8 +51,9 @@ namespace fairmq
} }
}; };
namespace color namespace Color
{ {
enum code enum code
{ {
FG_BLACK = 30, FG_BLACK = 30,
@ -68,11 +70,13 @@ namespace fairmq
BG_BLUE = 44, BG_BLUE = 44,
BG_DEFAULT = 49 BG_DEFAULT = 49
}; };
}
} }
} // FairMQ namespace
// helper function to format in color console output // helper function to format in color console output
template <fairmq::color::code color> template <FairMQ::Color::code color>
inline std::string write_in(const std::string& text_in_bold) inline std::string write_in(const std::string& text_in_bold)
{ {
std::ostringstream os; std::ostringstream os;
@ -82,8 +86,8 @@ inline std::string write_in(const std::string& text_in_bold)
} }
// typedef // typedef
typedef fairmq::severity_level custom_severity_level; typedef FairMQ::severity_level custom_severity_level;
#define SEVERITY_THRESHOLD custom_severity_level::TRACE #define SEVERITY_MINIMUM custom_severity_level::TRACE
#define SEVERITY_ERROR custom_severity_level::ERROR #define SEVERITY_ERROR custom_severity_level::ERROR
#define SEVERITY_NOLOG custom_severity_level::NOLOG #define SEVERITY_NOLOG custom_severity_level::NOLOG
@ -100,41 +104,41 @@ inline boost::log::formatting_ostream& operator<<
{ {
custom_severity_level level = manip.get(); custom_severity_level level = manip.get();
std::size_t idx = static_cast<std::size_t>(level); std::size_t idx = static_cast<std::size_t>(level);
if (idx < fairmq::g_LogSeverityLevelString.size()) if (idx < FairMQ::g_LogSeverityLevelString.size())
{ {
// strm << " idx = " << idx << " "; // strm << " idx = " << idx << " ";
switch (level) switch (level)
{ {
case custom_severity_level::TRACE : case custom_severity_level::TRACE :
strm << write_in<fairmq::color::FG_BLUE>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_BLUE>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::DEBUG : case custom_severity_level::DEBUG :
strm << write_in<fairmq::color::FG_BLUE>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_BLUE>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::RESULTS : case custom_severity_level::RESULTS :
strm << write_in<fairmq::color::FG_MAGENTA>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_MAGENTA>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::INFO : case custom_severity_level::INFO :
strm << write_in<fairmq::color::FG_GREEN>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_GREEN>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::WARN : case custom_severity_level::WARN :
strm << write_in<fairmq::color::FG_YELLOW>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_YELLOW>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::STATE : case custom_severity_level::STATE :
strm << write_in<fairmq::color::FG_MAGENTA>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_MAGENTA>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::ERROR : case custom_severity_level::ERROR :
strm << write_in<fairmq::color::FG_RED>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_RED>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
case custom_severity_level::NOLOG : case custom_severity_level::NOLOG :
strm << write_in<fairmq::color::FG_DEFAULT>(fairmq::g_LogSeverityLevelString.at(idx)); strm << write_in<FairMQ::Color::FG_DEFAULT>(FairMQ::g_LogSeverityLevelString.at(idx));
break; break;
default: default:
@ -143,7 +147,7 @@ inline boost::log::formatting_ostream& operator<<
} }
else else
{ {
strm << write_in<fairmq::color::FG_RED>("Unknown log level ") strm << write_in<FairMQ::Color::FG_RED>("Unknown log level ")
<< "(int level = " << static_cast<int>(level) << ")"; << "(int level = " << static_cast<int>(level) << ")";
} }
return strm; return strm;
@ -158,13 +162,13 @@ inline boost::log::formatting_ostream& operator<<
{ {
custom_severity_level level = manip.get(); custom_severity_level level = manip.get();
std::size_t idx = static_cast<std::size_t>(level); std::size_t idx = static_cast<std::size_t>(level);
if (idx < fairmq::g_LogSeverityLevelString.size()) if (idx < FairMQ::g_LogSeverityLevelString.size())
{ {
strm << fairmq::g_LogSeverityLevelString.at(idx); strm << FairMQ::g_LogSeverityLevelString.at(idx);
} }
else else
{ {
strm << write_in<fairmq::color::FG_RED>("Unknown log level ") strm << write_in<FairMQ::Color::FG_RED>("Unknown log level ")
<< "(int level = " << static_cast<int>(level) << ")"; << "(int level = " << static_cast<int>(level) << ")";
} }
return strm; return strm;

View File

@ -66,8 +66,6 @@
std::cout << "----------------------------"<<std::endl; std::cout << "----------------------------"<<std::endl;
} }
int main() int main()
{ {
test_console_level(); test_console_level();
@ -83,14 +81,13 @@ int main()
ADD_LOG_FILESINK("test_log2",STATE); ADD_LOG_FILESINK("test_log2",STATE);
test_logger(); test_logger();
// advanced commands // advanced commands
std::cout << "----------------------------"<<std::endl; std::cout << "----------------------------"<<std::endl;
LOG(INFO)<<"open log file 3";// custom file sink setting LOG(INFO)<<"open log file 3";// custom file sink setting
AddFileSink([](const boost::log::attribute_value_set& attr_set) AddFileSink([](const boost::log::attribute_value_set& attr_set)
{ {
auto sev = attr_set["Severity"].extract<custom_severity_level>(); auto sev = attr_set["Severity"].extract<custom_severity_level>();
return (sev == fairmq::ERROR); return (sev == FairMQ::ERROR);
}, },
boost::log::keywords::file_name = "test_log3_%5N.log", boost::log::keywords::file_name = "test_log3_%5N.log",
boost::log::keywords::rotation_size = 5 * 1024 * 1024, boost::log::keywords::rotation_size = 5 * 1024 * 1024,
@ -105,7 +102,7 @@ int main()
FairMQ::Logger::sinkList.back()->set_filter([](const boost::log::attribute_value_set& attr_set) FairMQ::Logger::sinkList.back()->set_filter([](const boost::log::attribute_value_set& attr_set)
{ {
auto sev = attr_set["Severity"].extract<custom_severity_level>(); auto sev = attr_set["Severity"].extract<custom_severity_level>();
return (sev == fairmq::WARN) || (sev == fairmq::ERROR); return (sev == FairMQ::WARN) || (sev == FairMQ::ERROR);
}); });
test_logger(); test_logger();
@ -114,5 +111,3 @@ int main()
test_logger(); test_logger();
return 0; return 0;
} }

View File

@ -59,7 +59,7 @@ FairMQPollerNN::FairMQPollerNN(const vector<FairMQChannel>& channels)
} }
} }
FairMQPollerNN::FairMQPollerNN(const unordered_map<string, vector<FairMQChannel>>& channelsMap, const initializer_list<string> channelList) FairMQPollerNN::FairMQPollerNN(const unordered_map<string, vector<FairMQChannel>>& channelsMap, const vector<string>& channelList)
: items() : items()
, fNumItems(0) , fNumItems(0)
, fOffsetMap() , fOffsetMap()

View File

@ -33,7 +33,7 @@ class FairMQPollerNN : public FairMQPoller
public: public:
FairMQPollerNN(const std::vector<FairMQChannel>& channels); FairMQPollerNN(const std::vector<FairMQChannel>& channels);
FairMQPollerNN(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList); FairMQPollerNN(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList);
FairMQPollerNN(const FairMQPollerNN&) = delete; FairMQPollerNN(const FairMQPollerNN&) = delete;
FairMQPollerNN operator=(const FairMQPollerNN&) = delete; FairMQPollerNN operator=(const FairMQPollerNN&) = delete;

View File

@ -21,37 +21,37 @@ FairMQTransportFactoryNN::FairMQTransportFactoryNN()
LOG(INFO) << "Using nanomsg library"; LOG(INFO) << "Using nanomsg library";
} }
FairMQMessage* FairMQTransportFactoryNN::CreateMessage() FairMQMessage* FairMQTransportFactoryNN::CreateMessage() const
{ {
return new FairMQMessageNN(); return new FairMQMessageNN();
} }
FairMQMessage* FairMQTransportFactoryNN::CreateMessage(const size_t size) FairMQMessage* FairMQTransportFactoryNN::CreateMessage(const size_t size) const
{ {
return new FairMQMessageNN(size); return new FairMQMessageNN(size);
} }
FairMQMessage* FairMQTransportFactoryNN::CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint) FairMQMessage* FairMQTransportFactoryNN::CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint) const
{ {
return new FairMQMessageNN(data, size, ffn, hint); return new FairMQMessageNN(data, size, ffn, hint);
} }
FairMQSocket* FairMQTransportFactoryNN::CreateSocket(const string& type, const std::string& name, const int numIoThreads, const std::string& id /*= ""*/) FairMQSocket* FairMQTransportFactoryNN::CreateSocket(const string& type, const std::string& name, const int numIoThreads, const std::string& id /*= ""*/) const
{ {
return new FairMQSocketNN(type, name, numIoThreads, id); return new FairMQSocketNN(type, name, numIoThreads, id);
} }
FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const vector<FairMQChannel>& channels) FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const vector<FairMQChannel>& channels) const
{ {
return new FairMQPollerNN(channels); return new FairMQPollerNN(channels);
} }
FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList) FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const
{ {
return new FairMQPollerNN(channelsMap, channelList); return new FairMQPollerNN(channelsMap, channelList);
} }
FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) FairMQPoller* FairMQTransportFactoryNN::CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) const
{ {
return new FairMQPollerNN(cmdSocket, dataSocket); return new FairMQPollerNN(cmdSocket, dataSocket);
} }

View File

@ -27,15 +27,15 @@ class FairMQTransportFactoryNN : public FairMQTransportFactory
public: public:
FairMQTransportFactoryNN(); FairMQTransportFactoryNN();
virtual FairMQMessage* CreateMessage(); virtual FairMQMessage* CreateMessage() const;
virtual FairMQMessage* CreateMessage(const size_t size); virtual FairMQMessage* CreateMessage(const size_t size) const;
virtual FairMQMessage* CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = NULL); virtual FairMQMessage* CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = NULL) const;
virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, const int numIoThreads, const std::string& id = ""); virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, const int numIoThreads, const std::string& id = "") const;
virtual FairMQPoller* CreatePoller(const std::vector<FairMQChannel>& channels); virtual FairMQPoller* CreatePoller(const std::vector<FairMQChannel>& channels) const;
virtual FairMQPoller* CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList); virtual FairMQPoller* CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const;
virtual FairMQPoller* CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket); virtual FairMQPoller* CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) const;
virtual ~FairMQTransportFactoryNN() {}; virtual ~FairMQTransportFactoryNN() {};
}; };

View File

@ -26,15 +26,11 @@
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
enum class EventId : uint32_t enum class EventId : uint32_t
{ {
// Place your new EventManager events here // Place your new EventManager events here
UpdateParam = 0, UpdateParam = 0,
Custom = 1, Custom = 1,
}; };
namespace Events namespace Events
@ -44,7 +40,6 @@ namespace Events
template <typename T> struct Traits<EventId::UpdateParam, T> { using signal_type = boost::signals2::signal<void(const std::string&, T)>; } ; template <typename T> struct Traits<EventId::UpdateParam, T> { using signal_type = boost::signals2::signal<void(const std::string&, T)>; } ;
template <typename T> struct Traits<EventId::UpdateParam, std::vector<T> > { using signal_type = boost::signals2::signal<void(const std::string&, const std::vector<T>& )>; } ; template <typename T> struct Traits<EventId::UpdateParam, std::vector<T> > { using signal_type = boost::signals2::signal<void(const std::string&, const std::vector<T>& )>; } ;
template <> struct Traits<EventId::UpdateParam, std::string> { using signal_type = boost::signals2::signal<void(const std::string&, const std::string&)>; } ; template <> struct Traits<EventId::UpdateParam, std::string> { using signal_type = boost::signals2::signal<void(const std::string&, const std::string&)>; } ;
template<std::size_t N> struct Traits<EventId::UpdateParam, const char[N]> { using signal_type = boost::signals2::signal<void(const std::string&, const std::string&)>; } ; template<std::size_t N> struct Traits<EventId::UpdateParam, const char[N]> { using signal_type = boost::signals2::signal<void(const std::string&, const std::string&)>; } ;
@ -57,8 +52,8 @@ namespace Events
template <typename ...T> struct Traits2<EventId::UpdateParam,T...> { using signal_type = boost::signals2::signal<void(const std::string&, T...)>; } ; template <typename ...T> struct Traits2<EventId::UpdateParam,T...> { using signal_type = boost::signals2::signal<void(const std::string&, T...)>; } ;
template <> struct Traits2<EventId::UpdateParamInt> { using signal_type = boost::signals2::signal<void(const std::string&, int)>; } ; template <> struct Traits2<EventId::UpdateParamInt> { using signal_type = boost::signals2::signal<void(const std::string&, int)>; } ;
// */ // */
}
} // Events namespace
class FairMQEventManager class FairMQEventManager
{ {
@ -99,11 +94,8 @@ class FairMQEventManager
} }
private: private:
std::map<EventKey, boost::any> fEventMap; std::map<EventKey, boost::any> fEventMap;
template <EventId event, typename... T, typename Slot = typename Events::Traits<event,T...>::signal_type, template <EventId event, typename... T, typename Slot = typename Events::Traits<event,T...>::signal_type,
typename SlotPtr = boost::shared_ptr<Slot> > typename SlotPtr = boost::shared_ptr<Slot> >
Slot& GetSlot(const std::string& key) Slot& GetSlot(const std::string& key)
@ -128,6 +120,4 @@ class FairMQEventManager
} }
}; };
#endif /* FAIRMQEVENTMANAGER_H */ #endif /* FAIRMQEVENTMANAGER_H */

View File

@ -30,7 +30,8 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& id,
FairMQMap channelMap; FairMQMap channelMap;
// helper::PrintDeviceList(pt.get_child(rootNode)); // helper::PrintDeviceList(pt.get_child(rootNode));
// Extract value from boost::property_tree // Extract value from boost::property_tree
helper::DeviceParser(pt.get_child(rootNode), channelMap, id, formatFlag); Helper::DeviceParser(pt.get_child(rootNode), channelMap, id, formatFlag);
if (channelMap.size() > 0) if (channelMap.size() > 0)
{ {
stringstream channelKeys; stringstream channelKeys;
@ -77,8 +78,9 @@ FairMQMap XML::UserParser(stringstream& input, const string& deviceId, const str
return ptreeToMQMap(pt, deviceId, rootNode, "xml"); return ptreeToMQMap(pt, deviceId, rootNode, "xml");
} }
namespace helper namespace Helper
{ {
void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag) void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag)
{ {
string deviceIdKey; string deviceIdKey;
@ -138,14 +140,50 @@ namespace helper
LOG(DEBUG) << "Looking for '" << deviceId << "' id/key in the provided config file..."; LOG(DEBUG) << "Looking for '" << deviceId << "' id/key in the provided config file...";
// For each node in fairMQOptions // For each node in fairMQOptions
for (const auto& p0 : tree) for (const auto& p : tree)
{ {
if (p0.first == "devices") if (p.first == "devices")
{ {
for (const auto& p : p0.second) for (const auto& q : p.second)
{
// check if key is provided, otherwise use id
string key = q.second.get<string>("key", "");
if (key != "")
{
deviceIdKey = key;
// LOG(DEBUG) << "Found config for device key '" << deviceIdKey << "' in JSON input";
}
else
{
deviceIdKey = q.second.get<string>("id");
// LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input";
}
// if not correct device id, do not fill MQMap
if (deviceId != deviceIdKey)
{
continue;
}
LOG(DEBUG) << "Found with following channels:";
ChannelParser(q.second, channelMap, formatFlag);
}
}
if (p.first == "device")
{
if (formatFlag == "xml")
{
deviceIdKey = p.second.get<string>("<xmlattr>.id");
}
if (formatFlag == "json")
{ {
// check if key is provided, otherwise use id // check if key is provided, otherwise use id
string key = p.second.get<string>("key", ""); string key = p.second.get<string>("key", "");
if (key != "") if (key != "")
{ {
deviceIdKey = key; deviceIdKey = key;
@ -156,6 +194,7 @@ namespace helper
deviceIdKey = p.second.get<string>("id"); deviceIdKey = p.second.get<string>("id");
// LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input"; // LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input";
} }
}
// if not correct device id, do not fill MQMap // if not correct device id, do not fill MQMap
if (deviceId != deviceIdKey) if (deviceId != deviceIdKey)
@ -163,46 +202,11 @@ namespace helper
continue; continue;
} }
LOG(DEBUG) << "[" << p0.first << "] " << deviceIdKey; LOG(DEBUG) << "Found with following channels:";
ChannelParser(p.second, channelMap, formatFlag); ChannelParser(p.second, channelMap, formatFlag);
} }
} }
if (p0.first == "device")
{
if (formatFlag == "xml")
{
deviceIdKey = p0.second.get<string>("<xmlattr>.id");
LOG(DEBUG) << "Found config for '" << deviceIdKey << "' in XML input";
}
if (formatFlag == "json")
{
// check if key is provided, otherwise use id
string key = p0.second.get<string>("key", "");
if (key != "")
{
deviceIdKey = key;
// LOG(DEBUG) << "Found config for device key '" << deviceIdKey << "' in JSON input";
}
else
{
deviceIdKey = p0.second.get<string>("id");
// LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input";
}
}
// if not correct device id, do not fill MQMap
if (deviceId != deviceIdKey)
{
continue;
}
LOG(DEBUG) << "[" << p0.first << "] " << deviceIdKey;
ChannelParser(p0.second, channelMap, formatFlag);
}
}
} }
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const string& formatFlag) void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const string& formatFlag)
@ -217,6 +221,8 @@ namespace helper
{ {
channelKey = q.second.get<string>("name"); channelKey = q.second.get<string>("name");
int numSockets = q.second.get<int>("numSockets", 0);
// try to get common properties to use for all subChannels // try to get common properties to use for all subChannels
FairMQChannel commonChannel; FairMQChannel commonChannel;
commonChannel.UpdateType(q.second.get<string>("type", commonChannel.GetType())); commonChannel.UpdateType(q.second.get<string>("type", commonChannel.GetType()));
@ -227,11 +233,33 @@ namespace helper
commonChannel.UpdateRcvBufSize(q.second.get<int>("rcvBufSize", commonChannel.GetRcvBufSize())); commonChannel.UpdateRcvBufSize(q.second.get<int>("rcvBufSize", commonChannel.GetRcvBufSize()));
commonChannel.UpdateRateLogging(q.second.get<int>("rateLogging", commonChannel.GetRateLogging())); commonChannel.UpdateRateLogging(q.second.get<int>("rateLogging", commonChannel.GetRateLogging()));
LOG(DEBUG) << "\t[" << p.first << "] " << channelKey;
// temporary FairMQChannel container // temporary FairMQChannel container
vector<FairMQChannel> channelList; vector<FairMQChannel> channelList;
SocketParser(q.second.get_child(""), channelList, commonChannel);
if (numSockets > 0)
{
LOG(DEBUG) << "" << channelKey << ":";
LOG(DEBUG) << "\tnumSockets of " << numSockets << " specified,";
LOG(DEBUG) << "\tapplying common settings to each:";
LOG(DEBUG) << "\ttype = " << commonChannel.GetType();
LOG(DEBUG) << "\tmethod = " << commonChannel.GetMethod();
LOG(DEBUG) << "\taddress = " << commonChannel.GetAddress();
LOG(DEBUG) << "\tproperty = " << commonChannel.GetProperty();
LOG(DEBUG) << "\tsndBufSize = " << commonChannel.GetSndBufSize();
LOG(DEBUG) << "\trcvBufSize = " << commonChannel.GetRcvBufSize();
LOG(DEBUG) << "\trateLogging = " << commonChannel.GetRateLogging();
for (int i = 0; i < numSockets; ++i)
{
FairMQChannel channel(commonChannel);
channelList.push_back(channel);
}
}
else
{
SocketParser(q.second.get_child(""), channelList, channelKey, commonChannel);
}
channelMap.insert(make_pair(channelKey, move(channelList))); channelMap.insert(make_pair(channelKey, move(channelList)));
} }
@ -241,6 +269,7 @@ namespace helper
{ {
// try to get common properties to use for all subChannels // try to get common properties to use for all subChannels
FairMQChannel commonChannel; FairMQChannel commonChannel;
int numSockets = 0;
// get name attribute to form key // get name attribute to form key
if (formatFlag == "xml") if (formatFlag == "xml")
@ -252,6 +281,8 @@ namespace helper
{ {
channelKey = p.second.get<string>("name"); channelKey = p.second.get<string>("name");
numSockets = p.second.get<int>("numSockets", 0);
// try to get common properties to use for all subChannels // try to get common properties to use for all subChannels
commonChannel.UpdateType(p.second.get<string>("type", commonChannel.GetType())); commonChannel.UpdateType(p.second.get<string>("type", commonChannel.GetType()));
commonChannel.UpdateMethod(p.second.get<string>("method", commonChannel.GetMethod())); commonChannel.UpdateMethod(p.second.get<string>("method", commonChannel.GetMethod()));
@ -262,28 +293,50 @@ namespace helper
commonChannel.UpdateRateLogging(p.second.get<int>("rateLogging", commonChannel.GetRateLogging())); commonChannel.UpdateRateLogging(p.second.get<int>("rateLogging", commonChannel.GetRateLogging()));
} }
LOG(DEBUG) << "\t[" << p.first << "] " << channelKey;
// temporary FairMQChannel container // temporary FairMQChannel container
vector<FairMQChannel> channelList; vector<FairMQChannel> channelList;
SocketParser(p.second.get_child(""), channelList, commonChannel);
if (numSockets > 0)
{
LOG(DEBUG) << "" << channelKey << ":";
LOG(DEBUG) << "\tnumSockets of " << numSockets << " specified,";
LOG(DEBUG) << "\tapplying common settings to each:";
LOG(DEBUG) << "\ttype = " << commonChannel.GetType();
LOG(DEBUG) << "\tmethod = " << commonChannel.GetMethod();
LOG(DEBUG) << "\taddress = " << commonChannel.GetAddress();
LOG(DEBUG) << "\tproperty = " << commonChannel.GetProperty();
LOG(DEBUG) << "\tsndBufSize = " << commonChannel.GetSndBufSize();
LOG(DEBUG) << "\trcvBufSize = " << commonChannel.GetRcvBufSize();
LOG(DEBUG) << "\trateLogging = " << commonChannel.GetRateLogging();
for (int i = 0; i < numSockets; ++i)
{
FairMQChannel channel(commonChannel);
channelList.push_back(channel);
}
}
else
{
SocketParser(p.second.get_child(""), channelList, channelKey, commonChannel);
}
channelMap.insert(make_pair(channelKey, move(channelList))); channelMap.insert(make_pair(channelKey, move(channelList)));
} }
} }
} }
void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>& channelList, const FairMQChannel& commonChannel) void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>& channelList, const string& channelName, const FairMQChannel& commonChannel)
{ {
// for each socket in channel // for each socket in channel
int socketCounter = 0; int socketCounter = 0;
for (const auto& p : tree) for (const auto& p : tree)
{ {
if (p.first == "sockets") if (p.first == "sockets")
{ {
for (const auto& q : p.second) for (const auto& q : p.second)
{ {
++socketCounter;
// create new channel and apply setting from the common channel // create new channel and apply setting from the common channel
FairMQChannel channel(commonChannel); FairMQChannel channel(commonChannel);
@ -296,22 +349,22 @@ namespace helper
channel.UpdateRcvBufSize(q.second.get<int>("rcvBufSize", channel.GetRcvBufSize())); channel.UpdateRcvBufSize(q.second.get<int>("rcvBufSize", channel.GetRcvBufSize()));
channel.UpdateRateLogging(q.second.get<int>("rateLogging", channel.GetRateLogging())); channel.UpdateRateLogging(q.second.get<int>("rateLogging", channel.GetRateLogging()));
LOG(DEBUG) << "\t\t[" << p.first << "] " << socketCounter; LOG(DEBUG) << "" << channelName << "[" << socketCounter << "]:";
LOG(DEBUG) << "\t\t\ttype = " << channel.GetType(); LOG(DEBUG) << "\ttype = " << channel.GetType();
LOG(DEBUG) << "\t\t\tmethod = " << channel.GetMethod(); LOG(DEBUG) << "\tmethod = " << channel.GetMethod();
LOG(DEBUG) << "\t\t\taddress = " << channel.GetAddress(); LOG(DEBUG) << "\taddress = " << channel.GetAddress();
LOG(DEBUG) << "\t\t\tproperty = " << channel.GetProperty(); LOG(DEBUG) << "\tproperty = " << channel.GetProperty();
LOG(DEBUG) << "\t\t\tsndBufSize = " << channel.GetSndBufSize(); LOG(DEBUG) << "\tsndBufSize = " << channel.GetSndBufSize();
LOG(DEBUG) << "\t\t\trcvBufSize = " << channel.GetRcvBufSize(); LOG(DEBUG) << "\trcvBufSize = " << channel.GetRcvBufSize();
LOG(DEBUG) << "\t\t\trateLogging = " << channel.GetRateLogging(); LOG(DEBUG) << "\trateLogging = " << channel.GetRateLogging();
channelList.push_back(channel); channelList.push_back(channel);
++socketCounter;
} }
} }
if (p.first == "socket") if (p.first == "socket")
{ {
++socketCounter;
// create new channel and apply setting from the common channel // create new channel and apply setting from the common channel
FairMQChannel channel(commonChannel); FairMQChannel channel(commonChannel);
@ -324,16 +377,17 @@ namespace helper
channel.UpdateRcvBufSize(p.second.get<int>("rcvBufSize", channel.GetRcvBufSize())); channel.UpdateRcvBufSize(p.second.get<int>("rcvBufSize", channel.GetRcvBufSize()));
channel.UpdateRateLogging(p.second.get<int>("rateLogging", channel.GetRateLogging())); channel.UpdateRateLogging(p.second.get<int>("rateLogging", channel.GetRateLogging()));
LOG(DEBUG) << "\t\t[" << p.first << "] " << socketCounter; LOG(DEBUG) << "" << channelName << "[" << socketCounter << "]:";
LOG(DEBUG) << "\t\t\ttype = " << channel.GetType(); LOG(DEBUG) << "\ttype = " << channel.GetType();
LOG(DEBUG) << "\t\t\tmethod = " << channel.GetMethod(); LOG(DEBUG) << "\tmethod = " << channel.GetMethod();
LOG(DEBUG) << "\t\t\taddress = " << channel.GetAddress(); LOG(DEBUG) << "\taddress = " << channel.GetAddress();
LOG(DEBUG) << "\t\t\tproperty = " << channel.GetProperty(); LOG(DEBUG) << "\tproperty = " << channel.GetProperty();
LOG(DEBUG) << "\t\t\tsndBufSize = " << channel.GetSndBufSize(); LOG(DEBUG) << "\tsndBufSize = " << channel.GetSndBufSize();
LOG(DEBUG) << "\t\t\trcvBufSize = " << channel.GetRcvBufSize(); LOG(DEBUG) << "\trcvBufSize = " << channel.GetRcvBufSize();
LOG(DEBUG) << "\t\t\trateLogging = " << channel.GetRateLogging(); LOG(DEBUG) << "\trateLogging = " << channel.GetRateLogging();
channelList.push_back(channel); channelList.push_back(channel);
++socketCounter;
} }
} // end socket loop } // end socket loop
@ -343,22 +397,24 @@ namespace helper
} }
else else
{ {
LOG(DEBUG) << "\t\t\tNo subChannels specified,"; LOG(DEBUG) << "" << channelName << ":";
LOG(DEBUG) << "\t\t\tapplying common settings to the channel:"; LOG(DEBUG) << "\tNo sockets specified,";
LOG(DEBUG) << "\tapplying common settings to the channel:";
FairMQChannel channel(commonChannel); FairMQChannel channel(commonChannel);
LOG(DEBUG) << "\t\t\ttype = " << channel.GetType(); LOG(DEBUG) << "\ttype = " << channel.GetType();
LOG(DEBUG) << "\t\t\tmethod = " << channel.GetMethod(); LOG(DEBUG) << "\tmethod = " << channel.GetMethod();
LOG(DEBUG) << "\t\t\taddress = " << channel.GetAddress(); LOG(DEBUG) << "\taddress = " << channel.GetAddress();
LOG(DEBUG) << "\t\t\tproperty = " << channel.GetProperty(); LOG(DEBUG) << "\tproperty = " << channel.GetProperty();
LOG(DEBUG) << "\t\t\tsndBufSize = " << channel.GetSndBufSize(); LOG(DEBUG) << "\tsndBufSize = " << channel.GetSndBufSize();
LOG(DEBUG) << "\t\t\trcvBufSize = " << channel.GetRcvBufSize(); LOG(DEBUG) << "\trcvBufSize = " << channel.GetRcvBufSize();
LOG(DEBUG) << "\t\t\trateLogging = " << channel.GetRateLogging(); LOG(DEBUG) << "\trateLogging = " << channel.GetRateLogging();
channelList.push_back(channel); channelList.push_back(channel);
} }
} }
} // end helper namespace
} // end FairMQParser namespace } // Helper namespace
} // FairMQParser namespace

View File

@ -8,16 +8,13 @@
#ifndef FAIRMQPARSER_H #ifndef FAIRMQPARSER_H
#define FAIRMQPARSER_H #define FAIRMQPARSER_H
// std
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
// Boost
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
// FairMQ
#include "FairMQChannel.h" #include "FairMQChannel.h"
namespace FairMQParser namespace FairMQParser
@ -39,13 +36,15 @@ struct XML
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions"); FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
}; };
namespace helper namespace Helper
{ {
void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag = "json"); void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag = "json");
void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId, const std::string& formatFlag); void DeviceParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& deviceId, const std::string& formatFlag);
void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& formatFlag); void ChannelParser(const boost::property_tree::ptree& tree, FairMQMap& channelMap, const std::string& formatFlag);
void SocketParser(const boost::property_tree::ptree& tree, std::vector<FairMQChannel>& channelList, const FairMQChannel& commonChannel); void SocketParser(const boost::property_tree::ptree& tree, std::vector<FairMQChannel>& channelList, const std::string& channelName, const FairMQChannel& commonChannel);
}
} // Helper namespace
} // FairMQParser namespace } // FairMQParser namespace

View File

@ -16,6 +16,7 @@
#include <algorithm> #include <algorithm>
#include "FairMQParser.h" #include "FairMQParser.h"
#include "FairMQLogger.h" #include "FairMQLogger.h"
using namespace std; using namespace std;
FairMQProgOptions::FairMQProgOptions() FairMQProgOptions::FairMQProgOptions()
@ -41,7 +42,6 @@ FairMQProgOptions::~FairMQProgOptions()
void FairMQProgOptions::ParseAll(const int argc, char** argv, bool allowUnregistered) void FairMQProgOptions::ParseAll(const int argc, char** argv, bool allowUnregistered)
{ {
// init description // init description
InitOptionDescription(); InitOptionDescription();
// parse command line options // parse command line options
@ -71,33 +71,37 @@ void FairMQProgOptions::ParseAll(const int argc, char** argv, bool allowUnregist
} }
} }
// set log level before printing (default is 0 = DEBUG level) std::string verbosity = GetValue<std::string>("verbosity");
std::string verbosity = GetValue<std::string>("verbose"); std::string logFile = GetValue<std::string>("log-to-file");
bool color = GetValue<bool>("log-color"); bool color = GetValue<bool>("log-color");
// check if the provided verbosity level is valid, otherwise set to DEBUG
if (fSeverityMap.count(verbosity) == 0)
{
LOG(ERROR) << " verbosity level '" << verbosity << "' unknown, it will be set to DEBUG";
verbosity = "DEBUG";
}
if (logFile != "")
{
reinit_logger(false, logFile, fSeverityMap.at(verbosity));
DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
}
else
{
if (!color) if (!color)
{ {
reinit_logger(false); reinit_logger(false);
} }
if (fSeverityMap.count(verbosity)) DefaultConsoleSetFilter(fSeverityMap.at(verbosity));
{
DefaultConsoleSetFilter(fSeverityMap.at(verbosity));// return 1 if not success
//set_global_log_level(log_op::operation::GREATER_EQ_THAN, fSeverityMap.at(verbosity));
} }
else
{
LOG(ERROR) << " verbosity level '" << verbosity << "' unknown, it will be set to DEBUG";
//set_global_log_level(log_op::operation::GREATER_EQ_THAN, fSeverityMap.at("DEBUG"));
DefaultConsoleSetFilter(fSeverityMap.at("DEBUG"));
}
// check if one of required MQ config option is there // check if one of required MQ config option is there
auto parserOption_shptr = fMQParserOptions.options(); auto parserOptions = fMQParserOptions.options();
bool optionExists = false; bool optionExists = false;
vector<string> MQParserKeys; vector<string> MQParserKeys;
for (const auto& p : parserOption_shptr) for (const auto& p : parserOptions)
{ {
MQParserKeys.push_back(p->canonical_display_name()); MQParserKeys.push_back(p->canonical_display_name());
if (fVarMap.count(p->canonical_display_name())) if (fVarMap.count(p->canonical_display_name()))
@ -164,9 +168,18 @@ void FairMQProgOptions::ParseAll(const int argc, char** argv, bool allowUnregist
{ {
LOG(DEBUG) << "config-json-string: Parsing JSON string"; LOG(DEBUG) << "config-json-string: Parsing JSON string";
std::string id = fVarMap["id"].as<std::string>(); std::string id;
std::string value = fairmq::ConvertVariableValue<fairmq::ToString>().Run(fVarMap.at("config-json-string")); if (fVarMap.count("config-key"))
{
id = fVarMap["config-key"].as<std::string>();
}
else
{
id = fVarMap["id"].as<std::string>();
}
std::string value = FairMQ::ConvertVariableValue<FairMQ::ToString>().Run(fVarMap.at("config-json-string"));
std::stringstream ss; std::stringstream ss;
ss << value; ss << value;
UserParser<FairMQParser::JSON>(ss, id); UserParser<FairMQParser::JSON>(ss, id);
@ -175,14 +188,24 @@ void FairMQProgOptions::ParseAll(const int argc, char** argv, bool allowUnregist
{ {
LOG(DEBUG) << "config-json-string: Parsing XML string"; LOG(DEBUG) << "config-json-string: Parsing XML string";
std::string id = fVarMap["id"].as<std::string>(); std::string id;
std::string value = fairmq::ConvertVariableValue<fairmq::ToString>().Run(fVarMap.at("config-xml-string")); if (fVarMap.count("config-key"))
{
id = fVarMap["config-key"].as<std::string>();
}
else
{
id = fVarMap["id"].as<std::string>();
}
std::string value = FairMQ::ConvertVariableValue<FairMQ::ToString>().Run(fVarMap.at("config-xml-string"));
std::stringstream ss; std::stringstream ss;
ss << value; ss << value;
UserParser<FairMQParser::XML>(ss, id); UserParser<FairMQParser::XML>(ss, id);
} }
} }
FairProgOptions::PrintOptions(); FairProgOptions::PrintOptions();
} }
@ -301,6 +324,8 @@ void FairMQProgOptions::InitOptionDescription()
("control", po::value<string>()->default_value("interactive"), "States control ('interactive'/'static'/'dds').") ("control", po::value<string>()->default_value("interactive"), "States control ('interactive'/'static'/'dds').")
("network-interface", po::value<string>()->default_value("eth0"), "Network interface to bind on (e.g. eth0, ib0, wlan0, en0, lo...).") ("network-interface", po::value<string>()->default_value("eth0"), "Network interface to bind on (e.g. eth0, ib0, wlan0, en0, lo...).")
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file") ("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file")
("catch-signals", po::value<int >()->default_value(1), "Enable signal handling (1/0)")
("log-to-file", po::value<string>()->default_value(""), "Log output to a file")
; ;
fMQOptionsInCfg.add_options() fMQOptionsInCfg.add_options()
@ -311,6 +336,8 @@ void FairMQProgOptions::InitOptionDescription()
("control", po::value<string>()->default_value("interactive"), "States control ('interactive'/'static'/'dds').") ("control", po::value<string>()->default_value("interactive"), "States control ('interactive'/'static'/'dds').")
("network-interface", po::value<string>()->default_value("eth0"), "Network interface to bind on (e.g. eth0, ib0, wlan0, en0, lo...).") ("network-interface", po::value<string>()->default_value("eth0"), "Network interface to bind on (e.g. eth0, ib0, wlan0, en0, lo...).")
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file") ("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file")
("catch-signals", po::value<int >()->default_value(1), "Enable signal handling (1/0)")
("log-to-file", po::value<string>()->default_value(""), "Log output to a file")
; ;
} }
else else
@ -323,6 +350,8 @@ void FairMQProgOptions::InitOptionDescription()
("control", po::value<string>()->default_value("interactive"), "States control ('interactive'/'static'/'dds').") ("control", po::value<string>()->default_value("interactive"), "States control ('interactive'/'static'/'dds').")
("network-interface", po::value<string>()->default_value("eth0"), "Network interface to bind on (e.g. eth0, ib0, wlan0, en0, lo...).") ("network-interface", po::value<string>()->default_value("eth0"), "Network interface to bind on (e.g. eth0, ib0, wlan0, en0, lo...).")
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file") ("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file")
("catch-signals", po::value<int >()->default_value(1), "Enable signal handling (1/0)")
("log-to-file", po::value<string>()->default_value(""), "Log output to a file")
; ;
} }

View File

@ -20,13 +20,10 @@
#include <map> #include <map>
#include <set> #include <set>
#include "FairProgOptions.h" #include "FairProgOptions.h"
#include "FairMQEventManager.h" #include "FairMQEventManager.h"
#include "FairMQChannel.h" #include "FairMQChannel.h"
class FairMQProgOptions : public FairProgOptions , public FairMQEventManager class FairMQProgOptions : public FairProgOptions , public FairMQEventManager
{ {
protected: protected:
@ -98,7 +95,7 @@ class FairMQProgOptions : public FairProgOptions , public FairMQEventManager
{ {
if(!fairmq::is_this_type<std::string>(fVarMap.at(key))) if(!FairMQ::is_this_type<std::string>(fVarMap.at(key)))
{ {
LOG(ERROR) << "You try to update a value as string (for key="<< key <<") while it has been defined with a different type in the option description."; LOG(ERROR) << "You try to update a value as string (for key="<< key <<") while it has been defined with a different type in the option description.";
abort(); abort();
@ -238,9 +235,6 @@ class FairMQProgOptions : public FairProgOptions , public FairMQEventManager
std::string fHelpTitle; std::string fHelpTitle;
std::string fVersion; std::string fVersion;
bool EventKeyFound(const std::string& key) bool EventKeyFound(const std::string& key)
{ {
if ( if (
@ -251,8 +245,6 @@ class FairMQProgOptions : public FairProgOptions , public FairMQEventManager
return false; return false;
} }
typedef std::tuple<std::string,int,std::string> MQKey;//store key info typedef std::tuple<std::string,int,std::string> MQKey;//store key info
std::map<std::string,MQKey> fMQKeyMap;// key=full path - val=key info std::map<std::string,MQKey> fMQKeyMap;// key=full path - val=key info
@ -264,9 +256,7 @@ class FairMQProgOptions : public FairProgOptions , public FairMQEventManager
void UpdateMQValues(); void UpdateMQValues();
int Store(const FairMQMap& channels); int Store(const FairMQMap& channels);
private: private:
/* /*
// string API // string API
std::map<std::string, signal_type_ptr > fSignalMap; std::map<std::string, signal_type_ptr > fSignalMap;
@ -299,6 +289,4 @@ class FairMQProgOptions : public FairProgOptions , public FairMQEventManager
} }
}; };
#endif /* FAIRMQPROGOPTIONS_H */ #endif /* FAIRMQPROGOPTIONS_H */

View File

@ -28,7 +28,7 @@ FairProgOptions::FairProgOptions() :
fConfigFileOptions("Configuration file options"), fConfigFileOptions("Configuration file options"),
fSeverityMap(), fSeverityMap(),
fVisibleOptions("Visible options"), fVisibleOptions("Visible options"),
fVerboseLvl("INFO"), fVerbosityLevel("INFO"),
fUseConfigFile(false), fUseConfigFile(false),
fConfigFile() fConfigFile()
{ {
@ -37,7 +37,7 @@ FairProgOptions::FairProgOptions() :
fGenericDesc.add_options() fGenericDesc.add_options()
("help,h", "produce help") ("help,h", "produce help")
("version,v", "print version") ("version,v", "print version")
("verbose", po::value<std::string>(&fVerboseLvl)->default_value("DEBUG"), "Verbosity level : \n" ("verbosity", po::value<std::string>(&fVerbosityLevel)->default_value("DEBUG"), "Verbosity level : \n"
" TRACE \n" " TRACE \n"
" DEBUG \n" " DEBUG \n"
" RESULTS \n" " RESULTS \n"
@ -50,14 +50,14 @@ FairProgOptions::FairProgOptions() :
("log-color", po::value<bool>()->default_value(true), "logger color: true or false") ("log-color", po::value<bool>()->default_value(true), "logger color: true or false")
; ;
fSeverityMap["TRACE"] = fairmq::severity_level::TRACE; fSeverityMap["TRACE"] = FairMQ::severity_level::TRACE;
fSeverityMap["DEBUG"] = fairmq::severity_level::DEBUG; fSeverityMap["DEBUG"] = FairMQ::severity_level::DEBUG;
fSeverityMap["RESULTS"] = fairmq::severity_level::RESULTS; fSeverityMap["RESULTS"] = FairMQ::severity_level::RESULTS;
fSeverityMap["INFO"] = fairmq::severity_level::INFO; fSeverityMap["INFO"] = FairMQ::severity_level::INFO;
fSeverityMap["WARN"] = fairmq::severity_level::WARN; fSeverityMap["WARN"] = FairMQ::severity_level::WARN;
fSeverityMap["ERROR"] = fairmq::severity_level::ERROR; fSeverityMap["ERROR"] = FairMQ::severity_level::ERROR;
fSeverityMap["STATE"] = fairmq::severity_level::STATE; fSeverityMap["STATE"] = FairMQ::severity_level::STATE;
fSeverityMap["NOLOG"] = fairmq::severity_level::NOLOG; fSeverityMap["NOLOG"] = FairMQ::severity_level::NOLOG;
} }
/// Destructor /// Destructor
@ -221,7 +221,7 @@ string FairProgOptions::GetStringValue(const string& key)
{ {
if (fVarMap.count(key)) if (fVarMap.count(key))
{ {
valueStr=fairmq::ConvertVariableValue<fairmq::ToString>().Run(fVarMap.at(key)); valueStr=FairMQ::ConvertVariableValue<FairMQ::ToString>().Run(fVarMap.at(key));
} }
} }
catch(exception& e) catch(exception& e)
@ -288,8 +288,8 @@ int FairProgOptions::PrintOptions()
// formatting and printing // formatting and printing
LOG(INFO) << setfill ('*') << setw (totalLength + 3) << "*";// +3 because of string " = " LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 because of string " = "
string PrintOptionsTitle = " Program options found "; string PrintOptionsTitle = " Configuration ";
int leftSpaceLength = 0; int leftSpaceLength = 0;
int rightSpaceLength = 0; int rightSpaceLength = 0;
@ -313,11 +313,11 @@ int FairProgOptions::PrintOptions()
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength; rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
} }
LOG(INFO) << setfill ('*') << setw(leftSpaceLength) << "*" LOG(DEBUG) << setfill ('*') << setw(leftSpaceLength) << "*"
<< setw(PrintOptionsTitle.length()) << PrintOptionsTitle << setw(PrintOptionsTitle.length()) << PrintOptionsTitle
<< setfill ('*') << setw(rightSpaceLength) << "*"; << setfill ('*') << setw(rightSpaceLength) << "*";
LOG(INFO) << setfill ('*') << setw (totalLength+3) << "*"; LOG(DEBUG) << setfill ('*') << setw (totalLength+3) << "*";
for (const auto& p : mapinfo) for (const auto& p : mapinfo)
{ {
@ -328,7 +328,7 @@ int FairProgOptions::PrintOptions()
string emptyStr; string emptyStr;
keyStr = p.first; keyStr = p.first;
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second; tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
LOG(INFO) << std::setfill(' ') LOG(DEBUG) << std::setfill(' ')
<< setw(maxLength1st) << left << setw(maxLength1st) << left
<< p.first << " = " << p.first << " = "
<< setw(maxLength2nd) << setw(maxLength2nd)
@ -340,7 +340,7 @@ int FairProgOptions::PrintOptions()
<< setw(maxLengthEmpty) << setw(maxLengthEmpty)
<< emptyStr; << emptyStr;
} }
LOG(INFO) << setfill ('*') << setw (totalLength + 3) << "*";// +3 for " = " LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 for " = "
return 0; return 0;
} }
@ -365,5 +365,5 @@ int FairProgOptions::NotifySwitchOption()
FairProgOptions::VarValInfo_t FairProgOptions::GetVariableValueInfo(const po::variable_value& varValue) FairProgOptions::VarValInfo_t FairProgOptions::GetVariableValueInfo(const po::variable_value& varValue)
{ {
return fairmq::ConvertVariableValue<fairmq::ToVarInfo>().Run(varValue); return FairMQ::ConvertVariableValue<FairMQ::ToVarInfo>().Run(varValue);
} }

View File

@ -54,7 +54,6 @@
* } * }
*/ */
namespace po = boost::program_options; namespace po = boost::program_options;
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
@ -150,10 +149,10 @@ class FairProgOptions
// Description which is printed in help command line // Description which is printed in help command line
// to handle logger severity // to handle logger severity
std::map<std::string,fairmq::severity_level> fSeverityMap; std::map<std::string, FairMQ::severity_level> fSeverityMap;
po::options_description fVisibleOptions; po::options_description fVisibleOptions;
std::string fVerboseLvl; std::string fVerbosityLevel;
bool fUseConfigFile; bool fUseConfigFile;
boost::filesystem::path fConfigFile; boost::filesystem::path fConfigFile;
virtual int NotifySwitchOption(); virtual int NotifySwitchOption();

View File

@ -32,11 +32,10 @@ std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
return os; return os;
} }
namespace fairmq namespace FairMQ
{ {
namespace po = boost::program_options;
//_____________________________________________________________________________________________________________________________ namespace po = boost::program_options;
template<typename T> template<typename T>
bool is_this_type(const po::variable_value& varValue) bool is_this_type(const po::variable_value& varValue)
@ -48,8 +47,6 @@ namespace fairmq
return false; return false;
} }
//_____________________________________________________________________________________________________________________________
template<typename T> template<typename T>
std::string ConvertVariableValueToString(const po::variable_value& varValue) std::string ConvertVariableValueToString(const po::variable_value& varValue)
{ {
@ -93,7 +90,7 @@ namespace fairmq
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Weffc++"
#endif #endif
//_____________________________________________________________________________________________________________________________
// policy to convert boost variable value into string // policy to convert boost variable value into string
struct ToString struct ToString
{ {
@ -110,8 +107,6 @@ namespace fairmq
} }
}; };
//_____________________________________________________________________________________________________________________________
// policy to convert variable value content into a tuple with value, type, defaulted, empty information // policy to convert variable value content into a tuple with value, type, defaulted, empty information
struct ToVarInfo struct ToVarInfo
{ {
@ -125,12 +120,10 @@ namespace fairmq
returned_type DefaultValue(const std::string& defaulted, const std::string& empty) returned_type DefaultValue(const std::string& defaulted, const std::string& empty)
{ {
return make_tuple(std::string("Unknown value"), std::string(" [Type=Unknown]"), defaulted, empty); return make_tuple(std::string("Unknown value"), std::string(" [Unknown]"), defaulted, empty);
} }
}; };
//_____________________________________________________________________________________________________________________________
// host class that take one of the two policy defined above // host class that take one of the two policy defined above
template<typename T> template<typename T>
struct ConvertVariableValue : T struct ConvertVariableValue : T
@ -149,96 +142,95 @@ namespace fairmq
{ {
if (varValue.defaulted()) if (varValue.defaulted())
{ {
defaultedValue = " [default value]"; defaultedValue = " [default]";
} }
else else
{ {
defaultedValue = " [provided value]"; defaultedValue = " [provided]";
} }
} }
emptyValue += " *"; // emptyValue += " *";
//////////////////////////////// std types //////////////////////////////// std types
// std::string albeit useless here // std::string albeit useless here
if (is_this_type<std::string>(varValue)) if (is_this_type<std::string>(varValue))
return T::template Value<std::string>(varValue,std::string(" [Type=string]"),defaultedValue,emptyValue); return T::template Value<std::string>(varValue,std::string(" <string>"),defaultedValue,emptyValue);
// std::vector<std::string> // std::vector<std::string>
if (is_this_type<std::vector<std::string>>(varValue)) if (is_this_type<std::vector<std::string>>(varValue))
return T::template Value<std::vector<std::string>>(varValue,std::string(" [Type=vector<string>]"),defaultedValue,emptyValue); return T::template Value<std::vector<std::string>>(varValue,std::string(" <vector<string>>"),defaultedValue,emptyValue);
// int // int
if (is_this_type<int>(varValue)) if (is_this_type<int>(varValue))
return T::template Value<int>(varValue,std::string(" [Type=int]"),defaultedValue,emptyValue); return T::template Value<int>(varValue,std::string(" <int>"),defaultedValue,emptyValue);
// std::vector<int> // std::vector<int>
if (is_this_type<std::vector<int>>(varValue)) if (is_this_type<std::vector<int>>(varValue))
return T::template Value<std::vector<int>>(varValue,std::string(" [Type=vector<int>]"),defaultedValue,emptyValue); return T::template Value<std::vector<int>>(varValue,std::string(" <vector<int>>"),defaultedValue,emptyValue);
// float // float
if (is_this_type<float>(varValue)) if (is_this_type<float>(varValue))
return T::template Value<float>(varValue,std::string(" [Type=float]"),defaultedValue,emptyValue); return T::template Value<float>(varValue,std::string(" <float>"),defaultedValue,emptyValue);
// std::vector float // std::vector float
if (is_this_type<std::vector<float>>(varValue)) if (is_this_type<std::vector<float>>(varValue))
return T::template Value<std::vector<float>>(varValue,std::string(" [Type=vector<float>]"),defaultedValue,emptyValue); return T::template Value<std::vector<float>>(varValue,std::string(" <vector<float>>"),defaultedValue,emptyValue);
// double // double
if (is_this_type<double>(varValue)) if (is_this_type<double>(varValue))
return T::template Value<double>(varValue,std::string(" [Type=double]"),defaultedValue,emptyValue); return T::template Value<double>(varValue,std::string(" <double>"),defaultedValue,emptyValue);
// std::vector double // std::vector double
if (is_this_type<std::vector<double>>(varValue)) if (is_this_type<std::vector<double>>(varValue))
return T::template Value<std::vector<double>>(varValue,std::string(" [Type=vector<double>]"),defaultedValue,emptyValue); return T::template Value<std::vector<double>>(varValue,std::string(" <vector<double>>"),defaultedValue,emptyValue);
// short // short
if (is_this_type<short>(varValue)) if (is_this_type<short>(varValue))
return T::template Value<short>(varValue,std::string(" [Type=short]"),defaultedValue,emptyValue); return T::template Value<short>(varValue,std::string(" <short>"),defaultedValue,emptyValue);
// std::vector short // std::vector short
if (is_this_type<std::vector<short>>(varValue)) if (is_this_type<std::vector<short>>(varValue))
return T::template Value<std::vector<short>>(varValue,std::string(" [Type=vector<short>]"),defaultedValue,emptyValue); return T::template Value<std::vector<short>>(varValue,std::string(" <vector<short>>"),defaultedValue,emptyValue);
// long // long
if (is_this_type<long>(varValue)) if (is_this_type<long>(varValue))
return T::template Value<long>(varValue,std::string(" [Type=long]"),defaultedValue,emptyValue); return T::template Value<long>(varValue,std::string(" <long>"),defaultedValue,emptyValue);
// std::vector short // std::vector short
if (is_this_type<std::vector<long>>(varValue)) if (is_this_type<std::vector<long>>(varValue))
return T::template Value<std::vector<long>>(varValue,std::string(" [Type=vector<long>]"),defaultedValue,emptyValue); return T::template Value<std::vector<long>>(varValue,std::string(" <vector<long>>"),defaultedValue,emptyValue);
// size_t // size_t
if (is_this_type<std::size_t>(varValue)) if (is_this_type<std::size_t>(varValue))
return T::template Value<std::size_t>(varValue,std::string(" [Type=std::size_t]"),defaultedValue,emptyValue); return T::template Value<std::size_t>(varValue,std::string(" <std::size_t>"),defaultedValue,emptyValue);
// std::vector size_t // std::vector size_t
if (is_this_type<std::vector<std::size_t>>(varValue)) if (is_this_type<std::vector<std::size_t>>(varValue))
return T::template Value<std::vector<std::size_t>>(varValue,std::string(" [Type=vector<std::size_t>]"),defaultedValue,emptyValue); return T::template Value<std::vector<std::size_t>>(varValue,std::string(" <vector<std::size_t>>"),defaultedValue,emptyValue);
// bool // bool
if (is_this_type<bool>(varValue)) if (is_this_type<bool>(varValue))
return T::template Value<bool>(varValue,std::string(" [Type=bool]"),defaultedValue,emptyValue); return T::template Value<bool>(varValue,std::string(" <bool>"),defaultedValue,emptyValue);
// std::vector bool // std::vector bool
if (is_this_type<std::vector<bool>>(varValue)) if (is_this_type<std::vector<bool>>(varValue))
return T::template Value<std::vector<bool>>(varValue,std::string(" [Type=vector<bool>]"),defaultedValue,emptyValue); return T::template Value<std::vector<bool>>(varValue,std::string(" <vector<bool>>"),defaultedValue,emptyValue);
//////////////////////////////// boost types //////////////////////////////// boost types
// boost::filesystem::path // boost::filesystem::path
if (is_this_type<boost::filesystem::path>(varValue)) if (is_this_type<boost::filesystem::path>(varValue))
return T::template Value<boost::filesystem::path>(varValue,std::string(" [Type=boost::filesystem::path]"),defaultedValue,emptyValue); return T::template Value<boost::filesystem::path>(varValue,std::string(" <boost::filesystem::path>"),defaultedValue,emptyValue);
// if we get here, the type is not supported return unknown info // if we get here, the type is not supported return unknown info
return T::DefaultValue(defaultedValue,emptyValue); return T::DefaultValue(defaultedValue,emptyValue);
} }
}; };
#if defined(__GNUC__) || defined(__GNUG__) #if defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
} // FairMQ namespace
};
#endif /* FAIRPROGOPTIONSHELPER_H */ #endif /* FAIRPROGOPTIONSHELPER_H */

View File

@ -115,8 +115,8 @@ int main(int argc, char** argv)
return 0; return 0;
// Set severity level (Default is 0=DEBUG) // Set severity level (Default is 0=DEBUG)
int verbose=config->GetValue<int>("verbose"); int verbosity = config->GetValue<int>("verbosity");
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbose); FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
SET_LOGGER_LEVEL(lvl); SET_LOGGER_LEVEL(lvl);

View File

@ -49,8 +49,8 @@ int main(int argc, char** argv)
return 0; return 0;
// Set severity level (Default is 0=DEBUG) // Set severity level (Default is 0=DEBUG)
int verbose=config.GetValue<int>("verbose"); int verbosity=config.GetValue<int>("verbosity");
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbose); FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
SET_LOGGER_LEVEL(lvl); SET_LOGGER_LEVEL(lvl);
// parse XML file // parse XML file

View File

@ -6,6 +6,6 @@ VERBOSE="DEBUG"
JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json" JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json"
########################## start DEVICE ########################## start DEVICE
DEVICE="runConfigExample --transport $TRANSPORT --verbose $VERBOSE" DEVICE="runConfigExample --transport $TRANSPORT --verbosity $VERBOSE"
DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE" DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE"
@CMAKE_BINARY_DIR@/bin/$DEVICE @CMAKE_BINARY_DIR@/bin/$DEVICE

View File

@ -5,55 +5,22 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, * * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" * * copied verbatim in the file "LICENSE" *
********************************************************************************/ ********************************************************************************/
/**
* runBenchmarkSampler.cxx
*
* @since 2013-04-23
* @author D. Klein, A. Rybalchenko
*/
#include <iostream> #include "runFairMQDevice.h"
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQProgOptions.h"
#include "FairMQBenchmarkSampler.h" #include "FairMQBenchmarkSampler.h"
#include "runSimpleMQStateMachine.h"
using namespace boost::program_options; namespace bpo = boost::program_options;
int main(int argc, char** argv) void addCustomOptions(bpo::options_description& options)
{ {
try options.add_options()
{ ("out-channel", bpo::value<std::string>()->default_value("data-out"), "Name of the output channel")
int msgSize; ("msg-size", bpo::value<int>()->default_value(1000), "Message size in bytes")
int numMsgs; ("num-msgs", bpo::value<int>()->default_value(0), "Number of messages to send")
int msgRate; ("msg-rate", bpo::value<int>()->default_value(0), "Msg rate limit in maximum number of messages per second");
options_description samplerOptions("Sampler options");
samplerOptions.add_options()
("msg-size", value<int>(&msgSize)->default_value(1000), "Message size in bytes")
("num-msgs", value<int>(&numMsgs)->default_value(0), "Number of messages to send")
("msg-rate", value<int>(&msgRate)->default_value(0), "Msg rate limit in maximum number of messages per second");
FairMQProgOptions config;
config.AddToCmdLineOptions(samplerOptions);
config.ParseAll(argc, argv);
FairMQBenchmarkSampler sampler;
sampler.SetProperty(FairMQBenchmarkSampler::MsgSize, msgSize);
sampler.SetProperty(FairMQBenchmarkSampler::NumMsgs, numMsgs);
sampler.SetProperty(FairMQBenchmarkSampler::MsgRate, msgRate);
runStateMachine(sampler, config);
}
catch (std::exception& e)
{
LOG(ERROR) << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit";
return 1;
} }
return 0; FairMQDevice* getDevice(const FairMQProgOptions& /*config*/)
{
return new FairMQBenchmarkSampler();
} }

View File

@ -5,48 +5,21 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, * * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" * * copied verbatim in the file "LICENSE" *
********************************************************************************/ ********************************************************************************/
/**
* runMerger.cxx
*
* @since 2012-12-06
* @author D. Klein, A. Rybalchenko
*/
#include <iostream> #include "runFairMQDevice.h"
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQProgOptions.h"
#include "FairMQMerger.h" #include "FairMQMerger.h"
#include "runSimpleMQStateMachine.h"
using namespace boost::program_options; namespace bpo = boost::program_options;
int main(int argc, char** argv) void addCustomOptions(bpo::options_description& options)
{ {
try options.add_options()
{ ("in-channel", bpo::value<std::string>()->default_value("data-in"), "Name of the input channel")
int multipart; ("out-channel", bpo::value<std::string>()->default_value("data-out"), "Name of the output channel")
("multipart", bpo::value<int>()->default_value(1), "Handle multipart payloads");
options_description mergerOptions("Proxy options");
mergerOptions.add_options()
("multipart", value<int>(&multipart)->default_value(1), "Handle multipart payloads");
FairMQProgOptions config;
config.AddToCmdLineOptions(mergerOptions);
config.ParseAll(argc, argv);
FairMQMerger merger;
merger.SetProperty(FairMQMerger::Multipart, multipart);
runStateMachine(merger, config);
}
catch (std::exception& e)
{
LOG(ERROR) << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit";
return 1;
} }
return 0; FairMQDevice* getDevice(const FairMQProgOptions& /*config*/)
{
return new FairMQMerger();
} }

View File

@ -0,0 +1,25 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "runFairMQDevice.h"
#include "FairMQMultiplier.h"
namespace bpo = boost::program_options;
void addCustomOptions(bpo::options_description& options)
{
options.add_options()
("in-channel", bpo::value<std::string>()->default_value("data-in"), "Name of the input channel")
("out-channel", bpo::value<std::vector<std::string>>()->multitoken(), "Names of the output channels")
("multipart", bpo::value<int>()->default_value(1), "Handle multipart payloads");
}
FairMQDevice* getDevice(const FairMQProgOptions& /*config*/)
{
return new FairMQMultiplier();
}

View File

@ -5,48 +5,21 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, * * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" * * copied verbatim in the file "LICENSE" *
********************************************************************************/ ********************************************************************************/
/**
* runProxy.cxx
*
* @since 2013-10-07
* @author A. Rybalchenko
*/
#include <iostream> #include "runFairMQDevice.h"
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQProgOptions.h"
#include "FairMQProxy.h" #include "FairMQProxy.h"
#include "runSimpleMQStateMachine.h"
using namespace boost::program_options; namespace bpo = boost::program_options;
int main(int argc, char** argv) void addCustomOptions(bpo::options_description& options)
{ {
try options.add_options()
{ ("in-channel", bpo::value<std::string>()->default_value("data-in"), "Name of the input channel")
int multipart; ("out-channel", bpo::value<std::string>()->default_value("data-out"), "Name of the output channel")
("multipart", bpo::value<int>()->default_value(1), "Handle multipart payloads");
options_description proxyOptions("Proxy options");
proxyOptions.add_options()
("multipart", value<int>(&multipart)->default_value(1), "Handle multipart payloads");
FairMQProgOptions config;
config.AddToCmdLineOptions(proxyOptions);
config.ParseAll(argc, argv);
FairMQProxy proxy;
proxy.SetProperty(FairMQProxy::Multipart, multipart);
runStateMachine(proxy, config);
}
catch (std::exception& e)
{
LOG(ERROR) << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit";
return 1;
} }
return 0; FairMQDevice* getDevice(const FairMQProgOptions& /*config*/)
{
return new FairMQProxy();
} }

View File

@ -5,49 +5,20 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, * * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" * * copied verbatim in the file "LICENSE" *
********************************************************************************/ ********************************************************************************/
/**
* runSink.cxx
*
* @since 2013-01-21
* @author: D. Klein, A. Rybalchenko
*/
#include <iostream> #include "runFairMQDevice.h"
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQProgOptions.h"
#include "FairMQSink.h" #include "FairMQSink.h"
#include "runSimpleMQStateMachine.h"
using namespace boost::program_options; namespace bpo = boost::program_options;
int main(int argc, char** argv) void addCustomOptions(bpo::options_description& options)
{ {
try options.add_options()
{ ("in-channel", bpo::value<std::string>()->default_value("data-in"), "Name of the input channel")
int numMsgs; ("num-msgs", bpo::value<int>()->default_value(0), "Number of messages to receive");
options_description sinkOptions("Sink options");
sinkOptions.add_options()
("num-msgs", value<int>(&numMsgs)->default_value(0), "Number of messages to receive");
FairMQProgOptions config;
config.AddToCmdLineOptions(sinkOptions);
config.ParseAll(argc, argv);
FairMQSink sink;
sink.SetProperty(FairMQSink::NumMsgs, numMsgs);
runStateMachine(sink, config);
}
catch (std::exception& e)
{
LOG(ERROR) << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit";
return 1;
} }
return 0; FairMQDevice* getDevice(const FairMQProgOptions& /*config*/)
{
return new FairMQSink();
} }

View File

@ -5,48 +5,21 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, * * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" * * copied verbatim in the file "LICENSE" *
********************************************************************************/ ********************************************************************************/
/**
* runSplitter.cxx
*
* @since 2012-12-06
* @author D. Klein, A. Rybalchenko
*/
#include <iostream> #include "runFairMQDevice.h"
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQProgOptions.h"
#include "FairMQSplitter.h" #include "FairMQSplitter.h"
#include "runSimpleMQStateMachine.h"
using namespace boost::program_options; namespace bpo = boost::program_options;
int main(int argc, char** argv) void addCustomOptions(bpo::options_description& options)
{ {
try options.add_options()
{ ("in-channel", bpo::value<std::string>()->default_value("data-in"), "Name of the input channel")
int multipart; ("out-channel", bpo::value<std::string>()->default_value("data-out"), "Name of the output channel")
("multipart", bpo::value<int>()->default_value(1), "Handle multipart payloads");
options_description proxyOptions("Proxy options");
proxyOptions.add_options()
("multipart", value<int>(&multipart)->default_value(1), "Handle multipart payloads");
FairMQProgOptions config;
config.AddToCmdLineOptions(proxyOptions);
config.ParseAll(argc, argv);
FairMQSplitter splitter;
splitter.SetProperty(FairMQSplitter::Multipart, multipart);
runStateMachine(splitter, config);
}
catch (std::exception& e)
{
LOG(ERROR) << "Unhandled Exception reached the top of main: "
<< e.what() << ", application will now exit";
return 1;
} }
return 0; FairMQDevice* getDevice(const FairMQProgOptions& /*config*/)
{
return new FairMQSplitter();
} }

67
fairmq/runFairMQDevice.h Normal file
View File

@ -0,0 +1,67 @@
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include <boost/program_options.hpp>
#include "FairMQLogger.h"
#include "FairMQProgOptions.h"
#include "FairMQDevice.h"
#include "runSimpleMQStateMachine.h"
template <typename R>
class GenericFairMQDevice : public FairMQDevice
{
public:
GenericFairMQDevice(R func) : r(func) {}
protected:
virtual bool ConditionalRun() { return r(*static_cast<FairMQDevice*>(this)); }
private:
R r;
};
template <typename R>
FairMQDevice* makeDeviceWithConditionalRun(R r)
{
return new GenericFairMQDevice<R>(r);
}
// to be implemented by the user to return a child class of FairMQDevice
FairMQDevice* getDevice(const FairMQProgOptions& config);
// to be implemented by the user to add custom command line options (or just with empty body)
void addCustomOptions(boost::program_options::options_description&);
int main(int argc, char** argv)
{
try
{
boost::program_options::options_description customOptions("Custom options");
addCustomOptions(customOptions);
FairMQProgOptions config;
config.AddToCmdLineOptions(customOptions);
config.ParseAll(argc, argv);
std::unique_ptr<FairMQDevice> device(getDevice(config));
int result = runStateMachine(*device, config);
if (result > 0)
{
return 1;
}
}
catch (std::exception& e)
{
LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit";
return 1;
}
return 0;
}

View File

@ -24,42 +24,13 @@ class TransferTimeoutTester : public FairMQDevice
protected: protected:
virtual void Run() virtual void Run()
{ {
// bool setSndOK = false;
// bool setRcvOK = false;
bool getSndOK = false;
bool getRcvOK = false;
bool sendCanceling = false; bool sendCanceling = false;
bool receiveCanceling = false; bool receiveCanceling = false;
fChannels.at("data-out").at(0).SetSendTimeout(1000); FairMQMessagePtr msg1(NewMessage());
fChannels.at("data-in").at(0).SetReceiveTimeout(1000); FairMQMessagePtr msg2(NewMessage());
if (fChannels.at("data-out").at(0).GetSendTimeout() == 1000) if (Send(msg1, "data-out", 0, 1000) == -2)
{
getSndOK = true;
LOG(INFO) << "get send timeout OK: " << fChannels.at("data-out").at(0).GetSendTimeout();
}
else
{
LOG(ERROR) << "get send timeout failed";
}
if (fChannels.at("data-in").at(0).GetReceiveTimeout() == 1000)
{
getRcvOK = true;
LOG(INFO) << "get receive timeout OK: " << fChannels.at("data-in").at(0).GetReceiveTimeout();
}
else
{
LOG(ERROR) << "get receive timeout failed";
}
if (getSndOK && getRcvOK)
{
std::unique_ptr<FairMQMessage> msg1(NewMessage());
std::unique_ptr<FairMQMessage> msg2(NewMessage());
if (Send(msg1, "data-out") == -2)
{ {
LOG(INFO) << "send canceled"; LOG(INFO) << "send canceled";
sendCanceling = true; sendCanceling = true;
@ -69,7 +40,7 @@ class TransferTimeoutTester : public FairMQDevice
LOG(ERROR) << "send did not cancel"; LOG(ERROR) << "send did not cancel";
} }
if (Receive(msg2, "data-in") == -2) if (Receive(msg2, "data-in", 0, 1000) == -2)
{ {
LOG(INFO) << "receive canceled"; LOG(INFO) << "receive canceled";
receiveCanceling = true; receiveCanceling = true;
@ -84,7 +55,6 @@ class TransferTimeoutTester : public FairMQDevice
LOG(INFO) << "Transfer timeout test successfull"; LOG(INFO) << "Transfer timeout test successfull";
} }
} }
}
}; };
int main(int argc, char** argv) int main(int argc, char** argv)

View File

@ -8,34 +8,44 @@
#ifndef RUNSIMPLEMQSTATEMACHINE_H #ifndef RUNSIMPLEMQSTATEMACHINE_H
#define RUNSIMPLEMQSTATEMACHINE_H #define RUNSIMPLEMQSTATEMACHINE_H
#include "FairMQLogger.h"
#include "FairMQParser.h"
#include "FairMQProgOptions.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <dlfcn.h>
#ifdef DDS_FOUND #ifdef DDS_FOUND
#include "FairMQDDSTools.h" #include "FairMQDDSTools.h"
#endif /*DDS_FOUND*/ #endif /*DDS_FOUND*/
#include "FairMQLogger.h"
#include "FairMQParser.h"
#include "FairMQProgOptions.h"
// template function that takes any device // template function that takes any device
// and runs a simple MQ state machine configured from a JSON file and/or (optionally) DDS. // and runs a simple MQ state machine configured from a JSON file and/or (optionally) DDS.
template<typename TMQDevice> template<typename TMQDevice>
inline int runStateMachine(TMQDevice& device, FairMQProgOptions& config) inline int runStateMachine(TMQDevice& device, FairMQProgOptions& config)
{
if (config.GetValue<int>("catch-signals") > 0)
{ {
device.CatchSignals(); device.CatchSignals();
}
else
{
LOG(WARN) << "Signal handling (e.g. ctrl+C) has been deactivated via command line argument";
}
device.SetConfig(config); device.SetConfig(config);
std::string control = config.GetValue<std::string>("control"); std::string control = config.GetValue<std::string>("control");
device.ChangeState(TMQDevice::INIT_DEVICE); device.ChangeState(TMQDevice::INIT_DEVICE);
#ifdef DDS_FOUND #ifdef DDS_FOUND
if (control == "dds") if (control == "dds")
{ {
HandleConfigViaDDS(device); HandleConfigViaDDS(device);
} }
#endif /*DDS_FOUND*/ #endif /*DDS_FOUND*/
device.WaitForEndOfState(TMQDevice::INIT_DEVICE); device.WaitForEndOfState(TMQDevice::INIT_DEVICE);
device.ChangeState(TMQDevice::INIT_TASK); device.ChangeState(TMQDevice::INIT_TASK);
@ -78,7 +88,7 @@ inline int runStateMachine(TMQDevice& device, FairMQProgOptions& config)
<< ", 'dds'" << ", 'dds'"
#endif /*DDS_FOUND*/ #endif /*DDS_FOUND*/
<< ". Exiting."; << ". Exiting.";
exit(EXIT_FAILURE); return 1;
} }
return 0; return 0;

View File

@ -57,7 +57,7 @@ FairMQPollerZMQ::FairMQPollerZMQ(const vector<FairMQChannel>& channels)
} }
} }
FairMQPollerZMQ::FairMQPollerZMQ(const unordered_map<string, vector<FairMQChannel>>& channelsMap, const initializer_list<string> channelList) FairMQPollerZMQ::FairMQPollerZMQ(const unordered_map<string, vector<FairMQChannel>>& channelsMap, const vector<string>& channelList)
: items() : items()
, fNumItems(0) , fNumItems(0)
, fOffsetMap() , fOffsetMap()

View File

@ -34,7 +34,7 @@ class FairMQPollerZMQ : public FairMQPoller
public: public:
FairMQPollerZMQ(const std::vector<FairMQChannel>& channels); FairMQPollerZMQ(const std::vector<FairMQChannel>& channels);
FairMQPollerZMQ(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList); FairMQPollerZMQ(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList);
FairMQPollerZMQ(const FairMQPollerZMQ&) = delete; FairMQPollerZMQ(const FairMQPollerZMQ&) = delete;
FairMQPollerZMQ operator=(const FairMQPollerZMQ&) = delete; FairMQPollerZMQ operator=(const FairMQPollerZMQ&) = delete;

View File

@ -23,7 +23,7 @@
using namespace std; using namespace std;
// Context to hold the ZeroMQ sockets // Context to hold the ZeroMQ sockets
boost::shared_ptr<FairMQContextZMQ> FairMQSocketZMQ::fContext = boost::shared_ptr<FairMQContextZMQ>(new FairMQContextZMQ(1)); std::unique_ptr<FairMQContextZMQ> FairMQSocketZMQ::fContext = std::unique_ptr<FairMQContextZMQ>(new FairMQContextZMQ(1));
FairMQSocketZMQ::FairMQSocketZMQ(const string& type, const string& name, const int numIoThreads, const string& id /*= ""*/) FairMQSocketZMQ::FairMQSocketZMQ(const string& type, const string& name, const int numIoThreads, const string& id /*= ""*/)
: FairMQSocket(ZMQ_SNDMORE, ZMQ_RCVMORE, ZMQ_DONTWAIT) : FairMQSocket(ZMQ_SNDMORE, ZMQ_RCVMORE, ZMQ_DONTWAIT)

View File

@ -17,7 +17,7 @@
#include <atomic> #include <atomic>
#include <boost/shared_ptr.hpp> #include <memory> // unique_ptr
#include "FairMQSocket.h" #include "FairMQSocket.h"
#include "FairMQContextZMQ.h" #include "FairMQContextZMQ.h"
@ -72,7 +72,7 @@ class FairMQSocketZMQ : public FairMQSocket
std::atomic<unsigned long> fMessagesTx; std::atomic<unsigned long> fMessagesTx;
std::atomic<unsigned long> fMessagesRx; std::atomic<unsigned long> fMessagesRx;
static boost::shared_ptr<FairMQContextZMQ> fContext; static std::unique_ptr<FairMQContextZMQ> fContext;
}; };
#endif /* FAIRMQSOCKETZMQ_H_ */ #endif /* FAIRMQSOCKETZMQ_H_ */

View File

@ -25,37 +25,37 @@ FairMQTransportFactoryZMQ::FairMQTransportFactoryZMQ()
LOG(DEBUG) << "Using ZeroMQ library, version: " << major << "." << minor << "." << patch; LOG(DEBUG) << "Using ZeroMQ library, version: " << major << "." << minor << "." << patch;
} }
FairMQMessage* FairMQTransportFactoryZMQ::CreateMessage() FairMQMessage* FairMQTransportFactoryZMQ::CreateMessage() const
{ {
return new FairMQMessageZMQ(); return new FairMQMessageZMQ();
} }
FairMQMessage* FairMQTransportFactoryZMQ::CreateMessage(const size_t size) FairMQMessage* FairMQTransportFactoryZMQ::CreateMessage(const size_t size) const
{ {
return new FairMQMessageZMQ(size); return new FairMQMessageZMQ(size);
} }
FairMQMessage* FairMQTransportFactoryZMQ::CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint) FairMQMessage* FairMQTransportFactoryZMQ::CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint) const
{ {
return new FairMQMessageZMQ(data, size, ffn, hint); return new FairMQMessageZMQ(data, size, ffn, hint);
} }
FairMQSocket* FairMQTransportFactoryZMQ::CreateSocket(const string& type, const std::string& name, const int numIoThreads, const std::string& id /*= ""*/) FairMQSocket* FairMQTransportFactoryZMQ::CreateSocket(const string& type, const std::string& name, const int numIoThreads, const std::string& id /*= ""*/) const
{ {
return new FairMQSocketZMQ(type, name, numIoThreads, id); return new FairMQSocketZMQ(type, name, numIoThreads, id);
} }
FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const vector<FairMQChannel>& channels) FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const vector<FairMQChannel>& channels) const
{ {
return new FairMQPollerZMQ(channels); return new FairMQPollerZMQ(channels);
} }
FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList) FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const
{ {
return new FairMQPollerZMQ(channelsMap, channelList); return new FairMQPollerZMQ(channelsMap, channelList);
} }
FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) FairMQPoller* FairMQTransportFactoryZMQ::CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) const
{ {
return new FairMQPollerZMQ(cmdSocket, dataSocket); return new FairMQPollerZMQ(cmdSocket, dataSocket);
} }

View File

@ -28,15 +28,15 @@ class FairMQTransportFactoryZMQ : public FairMQTransportFactory
public: public:
FairMQTransportFactoryZMQ(); FairMQTransportFactoryZMQ();
virtual FairMQMessage* CreateMessage(); virtual FairMQMessage* CreateMessage() const;
virtual FairMQMessage* CreateMessage(const size_t size); virtual FairMQMessage* CreateMessage(const size_t size) const;
virtual FairMQMessage* CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = NULL); virtual FairMQMessage* CreateMessage(void* data, const size_t size, fairmq_free_fn* ffn, void* hint = NULL) const;
virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, const int numIoThreads, const std::string& id = ""); virtual FairMQSocket* CreateSocket(const std::string& type, const std::string& name, const int numIoThreads, const std::string& id = "") const;
virtual FairMQPoller* CreatePoller(const std::vector<FairMQChannel>& channels); virtual FairMQPoller* CreatePoller(const std::vector<FairMQChannel>& channels) const;
virtual FairMQPoller* CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::initializer_list<std::string> channelList); virtual FairMQPoller* CreatePoller(const std::unordered_map<std::string, std::vector<FairMQChannel>>& channelsMap, const std::vector<std::string>& channelList) const;
virtual FairMQPoller* CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket); virtual FairMQPoller* CreatePoller(const FairMQSocket& cmdSocket, const FairMQSocket& dataSocket) const;
virtual ~FairMQTransportFactoryZMQ() {}; virtual ~FairMQTransportFactoryZMQ() {};
}; };