Add orthogonal OK/ERROR states.

Replace state check mutex with atomic.

Update DDS example documentation.
This commit is contained in:
Alexey Rybalchenko 2015-08-24 17:35:30 +02:00 committed by Mohammad Al-Turany
parent a7ab33a10e
commit fbf7dbf2ba
38 changed files with 838 additions and 615 deletions

View File

@ -29,23 +29,24 @@ Set(INCLUDE_DIRECTORIES
${CMAKE_CURRENT_BINARY_DIR}
)
if(DDS_PATH)
if(DDS_FOUND)
add_definitions(-DENABLE_DDS)
Set(INCLUDE_DIRECTORIES
${INCLUDE_DIRECTORIES}
${CMAKE_SOURCE_DIR}/fairmq/examples/3-dds
)
endif(DDS_PATH)
endif(DDS_FOUND)
Set(SYSTEM_INCLUDE_DIRECTORIES
${Boost_INCLUDE_DIR}
)
If(DDS_PATH)
If(DDS_FOUND)
Set(SYSTEM_INCLUDE_DIRECTORIES
${SYSTEM_INCLUDE_DIRECTORIES}
${DDS_PATH}/include
${DDS_INCLUDE_DIR}
)
EndIf(DDS_PATH)
EndIf(DDS_FOUND)
If(PROTOBUF_FOUND)
Set(INCLUDE_DIRECTORIES
@ -86,12 +87,12 @@ Set(LINK_DIRECTORIES
${Boost_LIBRARY_DIRS}
)
if(DDS_PATH)
if(DDS_FOUND)
set(LINK_DIRECTORIES
${LINK_DIRECTORIES}
${DDS_PATH}/lib
${DDS_LIBRARY_DIR}
)
endif(DDS_PATH)
endif(DDS_FOUND)
Link_Directories(${LINK_DIRECTORIES})
@ -131,7 +132,7 @@ set(SRCS
"examples/5-req-rep/FairMQExample5Server.cxx"
)
if(DDS_PATH)
if(DDS_FOUND)
set(SRCS
${SRCS}
"examples/3-dds/FairMQExample3Sampler.cxx"
@ -142,7 +143,7 @@ if(DDS_PATH)
${DEPENDENCIES}
dds-key-value-lib
)
endif(DDS_PATH)
endif(DDS_FOUND)
if(PROTOBUF_FOUND)
# following source files are only for protobuf tests and are not essential part of FairMQ
@ -242,14 +243,14 @@ set(Exe_Names
ex5-server
)
if(DDS_PATH)
if(DDS_FOUND)
set(Exe_Names
${Exe_Names}
ex3-sampler-dds
ex3-processor-dds
ex3-sink-dds
)
endif(DDS_PATH)
endif(DDS_FOUND)
# following executables are only for protobuf tests and are not essential part of FairMQ
# if(PROTOBUF_FOUND)
@ -280,14 +281,14 @@ set(Exe_Source
examples/5-req-rep/runExample5Server.cxx
)
if(DDS_PATH)
if(DDS_FOUND)
set(Exe_Source
${Exe_Source}
examples/3-dds/runExample3Sampler.cxx
examples/3-dds/runExample3Processor.cxx
examples/3-dds/runExample3Sink.cxx
)
endif(DDS_PATH)
endif(DDS_FOUND)
# following source files are only for protobuf tests and are not essential part of FairMQ
# if(PROTOBUF_FOUND)

View File

@ -21,7 +21,7 @@
using namespace std;
boost::mutex FairMQChannel::channelMutex;
boost::mutex FairMQChannel::fChannelMutex;
FairMQChannel::FairMQChannel()
: fType("unspecified")
@ -63,7 +63,7 @@ std::string FairMQChannel::GetType() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fType;
}
catch (boost::exception& e)
@ -76,7 +76,7 @@ std::string FairMQChannel::GetMethod() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fMethod;
}
catch (boost::exception& e)
@ -89,7 +89,7 @@ std::string FairMQChannel::GetAddress() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fAddress;
}
catch (boost::exception& e)
@ -102,7 +102,7 @@ int FairMQChannel::GetSndBufSize() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fSndBufSize;
}
catch (boost::exception& e)
@ -115,7 +115,7 @@ int FairMQChannel::GetRcvBufSize() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fRcvBufSize;
}
catch (boost::exception& e)
@ -128,7 +128,7 @@ int FairMQChannel::GetRateLogging() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fRateLogging;
}
catch (boost::exception& e)
@ -141,7 +141,7 @@ void FairMQChannel::UpdateType(const std::string& type)
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
fIsValid = false;
fType = type;
}
@ -155,7 +155,7 @@ void FairMQChannel::UpdateMethod(const std::string& method)
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
fIsValid = false;
fMethod = method;
}
@ -169,7 +169,7 @@ void FairMQChannel::UpdateAddress(const std::string& address)
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
fIsValid = false;
fAddress = address;
}
@ -183,7 +183,7 @@ void FairMQChannel::UpdateSndBufSize(const int sndBufSize)
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
fIsValid = false;
fSndBufSize = sndBufSize;
}
@ -197,7 +197,7 @@ void FairMQChannel::UpdateRcvBufSize(const int rcvBufSize)
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
fIsValid = false;
fRcvBufSize = rcvBufSize;
}
@ -211,7 +211,7 @@ void FairMQChannel::UpdateRateLogging(const int rateLogging)
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
fIsValid = false;
fRateLogging = rateLogging;
}
@ -225,7 +225,7 @@ bool FairMQChannel::IsValid() const
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
return fIsValid;
}
catch (boost::exception& e)
@ -238,7 +238,7 @@ bool FairMQChannel::ValidateChannel()
{
try
{
boost::unique_lock<boost::mutex> scoped_lock(channelMutex);
boost::unique_lock<boost::mutex> scoped_lock(fChannelMutex);
stringstream ss;
ss << "Validating channel \"" << fChannelName << "\"... ";
@ -358,7 +358,7 @@ bool FairMQChannel::InitCommandInterface(FairMQTransportFactory* factory)
fNoBlockFlag = fCmdSocket->NOBLOCK;
fSndMoreFlag = fCmdSocket->SNDMORE;
fPoller = fTransportFactory->CreatePoller(*fSocket, *fCmdSocket);
fPoller = fTransportFactory->CreatePoller(*fCmdSocket, *fSocket);
return true;
}
@ -380,7 +380,7 @@ int FairMQChannel::Send(const unique_ptr<FairMQMessage>& msg) const
if (fPoller->CheckInput(0))
{
HandleCommand();
HandleUnblock();
return -1;
}
@ -408,7 +408,7 @@ int FairMQChannel::Receive(const unique_ptr<FairMQMessage>& msg) const
if (fPoller->CheckInput(0))
{
HandleCommand();
HandleUnblock();
return -1;
}
@ -433,7 +433,7 @@ int FairMQChannel::Send(FairMQMessage* msg, const string& flag) const
if (fPoller->CheckInput(0))
{
HandleCommand();
HandleUnblock();
return -1;
}
@ -458,7 +458,7 @@ int FairMQChannel::Send(FairMQMessage* msg, const int flags) const
if (fPoller->CheckInput(0))
{
HandleCommand();
HandleUnblock();
return -1;
}
@ -483,7 +483,7 @@ int FairMQChannel::Receive(FairMQMessage* msg, const string& flag) const
if (fPoller->CheckInput(0))
{
HandleCommand();
HandleUnblock();
return -1;
}
@ -508,7 +508,7 @@ int FairMQChannel::Receive(FairMQMessage* msg, const int flags) const
if (fPoller->CheckInput(0))
{
HandleCommand();
HandleUnblock();
return -1;
}
@ -548,7 +548,7 @@ bool FairMQChannel::ExpectsAnotherPart() const
}
}
inline bool FairMQChannel::HandleCommand() const
inline bool FairMQChannel::HandleUnblock() const
{
FairMQMessage* cmd = fTransportFactory->CreateMessage();
fCmdSocket->Receive(cmd, 0);

View File

@ -96,13 +96,13 @@ class FairMQChannel
int fNoBlockFlag;
int fSndMoreFlag;
bool HandleCommand() const;
bool HandleUnblock() const;
// use static mutex to make the class easily copyable
// implication: same mutex is used for all instances of the class
// this does not hurt much, because mutex is used only during initialization with very low contention
// possible TODO: improve this
static boost::mutex channelMutex;
static boost::mutex fChannelMutex;
};
#endif /* FAIRMQCHANNEL_H_ */

View File

@ -12,6 +12,8 @@
* @author D. Klein, A. Rybalchenko
*/
#include <cstdlib> // quick_exit()
#include "FairMQLogger.h"
#include "FairMQConfigurable.h"
@ -24,7 +26,7 @@ FairMQConfigurable::FairMQConfigurable()
void FairMQConfigurable::SetProperty(const int key, const string& value)
{
LOG(ERROR) << "Reached end of the property list. SetProperty(" << key << ", " << value << ") has no effect.";
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
string FairMQConfigurable::GetProperty(const int key, const string& default_ /*= ""*/)
@ -36,7 +38,7 @@ string FairMQConfigurable::GetProperty(const int key, const string& default_ /*=
void FairMQConfigurable::SetProperty(const int key, const int value)
{
LOG(ERROR) << "Reached end of the property list. SetProperty(" << key << ", " << value << ") has no effect.";
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
int FairMQConfigurable::GetProperty(const int key, const int default_ /*= 0*/)

View File

@ -13,8 +13,9 @@
*/
#include <list>
#include <algorithm> // for std::sort()
#include <csignal> // for catching system signals
#include <algorithm> // std::sort()
#include <csignal> // catching system signals
#include <cstdlib> // quick_exit()
#include <termios.h> // for the InteractiveStateLoop
@ -57,7 +58,7 @@ void FairMQDevice::CatchSignals()
if (!fCatchingSignals)
{
// setup signal catching
sigHandler = std::bind1st(std::mem_fun(&FairMQDevice::SignalHandler), this);
sigHandler = bind1st(mem_fun(&FairMQDevice::SignalHandler), this);
struct sigaction action;
action.sa_handler = CallSignalHandler;
action.sa_flags = 0;
@ -73,15 +74,17 @@ void FairMQDevice::SignalHandler(int signal)
{
LOG(INFO) << "Caught signal " << signal;
ChangeState(STOP);
// fState = EXITING;
// Unblock();
// fStateThread.interrupt();
// fStateThread.join();
ChangeState(RESET_TASK);
WaitForEndOfState(RESET_TASK);
// fTerminateStateThread = boost::thread(boost::bind(&FairMQDevice::Terminate, this));
// Shutdown();
// fTerminateStateThread.join();
ChangeState(RESET_DEVICE);
WaitForEndOfState(RESET_DEVICE);
ChangeState(END);
MQLOG(INFO) << "Exiting.";
quick_exit(EXIT_FAILURE);
}
void FairMQDevice::InitWrapper()
@ -145,7 +148,7 @@ void FairMQDevice::InitWrapper()
{
LOG(ERROR) << "could not initialize all channels after " << maxAttempts << " attempts";
// TODO: goto ERROR state;
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
if (numAttempts != 0)
@ -418,11 +421,6 @@ int FairMQDevice::GetProperty(const int key, const int default_ /*= 0*/)
}
}
void FairMQDevice::SetTransport(unique_ptr<FairMQTransportFactory>& factory)
{
fTransportFactory = factory.get();
}
void FairMQDevice::SetTransport(FairMQTransportFactory* factory)
{
fTransportFactory = factory;
@ -579,6 +577,10 @@ void FairMQDevice::InteractiveStateLoop()
LOG(INFO) << "[h] help";
PrintInteractiveStateLoopHelp();
break;
case 'x':
LOG(INFO) << "[x] ERROR";
ChangeState("ERROR_FOUND");
break;
case 'q':
LOG(INFO) << "[q] end";
ChangeState("END");
@ -605,11 +607,11 @@ inline void FairMQDevice::PrintInteractiveStateLoopHelp()
LOG(INFO) << "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device";
}
void FairMQDevice::SendCommand(const string& command)
void FairMQDevice::Unblock()
{
FairMQMessage* cmd = fTransportFactory->CreateMessage(command.size());
memcpy(cmd->GetData(), command.c_str(), command.size());
FairMQMessage* cmd = fTransportFactory->CreateMessage();
fCmdSocket->Send(cmd, 0);
delete cmd;
}
void FairMQDevice::ResetTaskWrapper()

View File

@ -61,7 +61,6 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
virtual int GetProperty(const int key, const int default_ = 0);
virtual void SetTransport(FairMQTransportFactory* factory);
virtual void SetTransport(std::unique_ptr<FairMQTransportFactory>& factory);
static bool SortSocketsByAddress(const FairMQChannel &lhs, const FairMQChannel &rhs);
@ -105,7 +104,7 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
void Shutdown();
void Terminate();
void SendCommand(const std::string& command);
void Unblock();
bool InitChannel(FairMQChannel&);

View File

@ -12,7 +12,6 @@
* @author D. Klein, A. Rybalchenko
*/
#include <boost/exception/all.hpp>
#include <boost/chrono.hpp> // for WaitForEndOfStateForMs()
@ -44,8 +43,9 @@ int FairMQStateMachine::GetEventNumber(std::string event)
if (event == "RESET_DEVICE") return RESET_DEVICE;
if (event == "RESET_TASK") return RESET_TASK;
if (event == "END") return END;
if (event == "ERROR_FOUND") return ERROR_FOUND;
LOG(ERROR) << "Requested number for non-existent event... " << event << std::endl
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_DEVICE, RESET_TASK, END";
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_DEVICE, RESET_TASK, END, ERROR_FOUND";
return -1;
}
@ -88,9 +88,12 @@ bool FairMQStateMachine::ChangeState(int event)
case END:
process_event(FairMQFSM::END());
return true;
case ERROR_FOUND:
process_event(FairMQFSM::ERROR_FOUND());
return true;
default:
LOG(ERROR) << "Requested unsupported state: " << event << std::endl
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_TASK, RESET_DEVICE, END";
LOG(ERROR) << "Requested state transition with an unsupported event: " << event << std::endl
<< "Supported are: INIT_DEVICE, INIT_TASK, RUN, PAUSE, STOP, RESET_TASK, RESET_DEVICE, END, ERROR_FOUND";
return false;
}
}

View File

@ -18,13 +18,19 @@
#define FAIRMQ_INTERFACE_VERSION 2
#include <string>
#include <atomic>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/locks.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
// Increase maximum number of boost::msm states (default is 10)
// This #define has to be before any msm header includes
#define FUSION_MAX_VECTOR_SIZE 20
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
@ -37,7 +43,6 @@ namespace msmf = boost::msm::front;
namespace FairMQFSM
{
// defining events for the boost MSM state machine
struct INIT_DEVICE { std::string name() const { return "INIT_DEVICE"; } };
struct internal_DEVICE_READY { std::string name() const { return "internal_DEVICE_READY"; } };
@ -50,6 +55,7 @@ struct RESET_TASK { std::string name() const { return "RESET_TASK"; }
struct RESET_DEVICE { std::string name() const { return "RESET_DEVICE"; } };
struct internal_IDLE { std::string name() const { return "internal_IDLE"; } };
struct END { std::string name() const { return "END"; } };
struct ERROR_FOUND { std::string name() const { return "ERROR_FOUND"; } };
// defining the boost MSM state machine
struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
@ -81,6 +87,9 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
}
// The list of FSM states
struct NORMAL_FSM : public msm::front::state<> {};
struct ERROR_FSM : public msm::front::terminate_state<> {};
struct IDLE_FSM : public msm::front::state<> {};
struct INITIALIZING_DEVICE_FSM : public msm::front::state<> {};
struct DEVICE_READY_FSM : public msm::front::state<> {};
@ -92,8 +101,8 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
struct RESETTING_DEVICE_FSM : public msm::front::state<> {};
struct EXITING_FSM : public msm::front::state<> {};
// Define initial state
typedef IDLE_FSM initial_state;
// Define initial states
typedef mpl::vector<IDLE_FSM, NORMAL_FSM> initial_state;
// Actions
struct IdleFct
@ -101,8 +110,9 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fState = IDLE;
LOG(STATE) << "Entering IDLE state";
fsm.fState = IDLE;
}
};
@ -111,9 +121,12 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fStateFinished = false;
LOG(STATE) << "Entering INITIALIZING DEVICE state";
fsm.fStateFinished = false;
fsm.fState = INITIALIZING_DEVICE;
fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::InitWrapper, &fsm));
}
};
@ -124,6 +137,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "Entering DEVICE READY state";
fsm.fState = DEVICE_READY;
}
};
@ -133,9 +147,12 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fStateFinished = false;
LOG(STATE) << "Entering INITIALIZING TASK state";
fsm.fStateFinished = false;
fsm.fState = INITIALIZING_TASK;
fsm.InitTaskWrapper();
// fsm.fInitializingTaskThread = boost::thread(boost::bind(&FairMQFSM_::InitTaskWrapper, &fsm));
}
@ -147,6 +164,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "Entering READY state";
fsm.fState = READY;
}
};
@ -156,9 +174,12 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fStateFinished = false;
LOG(STATE) << "Entering RUNNING state";
fsm.fStateFinished = false;
fsm.fState = RUNNING;
fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::RunWrapper, &fsm));
}
};
@ -168,11 +189,14 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fStateFinished = false;
fsm.fState = PAUSED;
fsm.SendCommand("pause");
fsm.fStateFinished = false;
fsm.Unblock();
fsm.fStateThread.join();
LOG(STATE) << "Entering PAUSED state";
fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::Pause, &fsm));
}
};
@ -183,10 +207,13 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fState = RUNNING;
fsm.fStateThread.interrupt();
fsm.fStateThread.join();
fsm.fStateFinished = false;
LOG(STATE) << "Entering RUNNING state";
fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::RunWrapper, &fsm));
}
};
@ -197,8 +224,10 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "Received STOP event";
fsm.fState = IDLE;
fsm.SendCommand("stop");
fsm.fState = READY;
fsm.Unblock();
fsm.fStateThread.join();
}
};
@ -208,8 +237,9 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "RUNNING state finished without an external event";
fsm.fState = IDLE;
LOG(STATE) << "RUNNING state finished without an external event, going to IDLE";
fsm.fState = READY;
}
};
@ -218,9 +248,12 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fStateFinished = false;
LOG(STATE) << "Entering RESETTING TASK state";
fsm.fStateFinished = false;
fsm.fState = RESETTING_TASK;
fsm.fStateThread = boost::thread(boost::bind(&FairMQFSM_::ResetTaskWrapper, &fsm));
}
};
@ -230,9 +263,12 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
fsm.fStateFinished = false;
LOG(STATE) << "Entering RESETTING DEVICE state";
fsm.fStateFinished = false;
fsm.fState = RESETTING_DEVICE;
fsm.ResetWrapper();
}
};
@ -243,6 +279,7 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "Received END event";
fsm.fState = EXITING;
fsm.fTerminateStateThread = boost::thread(boost::bind(&FairMQFSM_::Terminate, &fsm));
@ -257,9 +294,10 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "Entering EXITING state";
fsm.fState = EXITING;
fsm.SendCommand("stop");
fsm.fStateThread.interrupt();
fsm.Unblock();
fsm.fStateThread.join();
fsm.fTerminateStateThread = boost::thread(boost::bind(&FairMQFSM_::Terminate, &fsm));
@ -268,6 +306,18 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
}
};
struct ErrorFoundFct
{
template <class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{
LOG(STATE) << "ERROR!";
fsm.fState = ERROR;
// quick_exit(EXIT_FAILURE);
}
};
// actions to be overwritten by derived classes
virtual void InitWrapper() {}
virtual void Init() {}
@ -282,12 +332,12 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
virtual void ResetTask() {}
virtual void Shutdown() {}
virtual void Terminate() {} // Termination method called during StopFct action.
virtual void SendCommand(const std::string& command) {} // Method to send commands.
virtual void Unblock() {} // Method to send commands.
// Transition table for FairMQFMS
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +-------------------------+----------------------+------------------------+---------------+---------+
// Start Event Next Action Guard
// +------------------------+----------------------+------------------------+----------------+---------+
msmf::Row<IDLE_FSM, INIT_DEVICE, INITIALIZING_DEVICE_FSM, InitDeviceFct, 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>,
@ -301,8 +351,9 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
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>, // temporary
msmf::Row<IDLE_FSM, END, EXITING_FSM, ExitingFct, msmf::none> >
msmf::Row<RUNNING_FSM, END, EXITING_FSM, ExitingRunFct, msmf::none>,
msmf::Row<IDLE_FSM, END, EXITING_FSM, ExitingFct, msmf::none>,
msmf::Row<NORMAL_FSM, ERROR_FOUND, ERROR_FSM, ErrorFoundFct, msmf::none>>
{};
// Replaces the default no-transition response.
@ -312,13 +363,11 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
LOG(STATE) << "no transition from state " << GetStateName(state) << " on event " << e.name();
}
// this is to run certain functions in a separate thread
boost::thread fStateThread;
boost::thread fTerminateStateThread;
// backward compatibility to FairMQStateMachine
enum State
{
NORMAL,
ERROR,
IDLE,
INITIALIZING_DEVICE,
DEVICE_READY,
@ -335,6 +384,10 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
{
switch(state)
{
case NORMAL:
return "NORMAL";
case ERROR:
return "ERROR";
case IDLE:
return "IDLE";
case INITIALIZING_DEVICE:
@ -394,18 +447,23 @@ struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
}
}
// this is to run certain functions in a separate thread
boost::thread fStateThread;
boost::thread fTerminateStateThread;
// condition variable to notify parent thread about end of state.
bool fStateFinished;
boost::condition_variable fStateCondition;
boost::mutex fStateMutex;
private:
State fState;
protected:
std::atomic<State> fState;
};
typedef msm::back::state_machine<FairMQFSM_> FairMQFSM;
} // namespace FairMQFSM
class FairMQStateMachine : public FairMQFSM::FairMQFSM
{
public:
@ -421,8 +479,10 @@ class FairMQStateMachine : public FairMQFSM::FairMQFSM
RESET_TASK,
RESET_DEVICE,
internal_IDLE,
END
END,
ERROR_FOUND
};
FairMQStateMachine();
virtual ~FairMQStateMachine();

View File

@ -69,7 +69,7 @@ void FairMQBenchmarkSampler::Run()
void FairMQBenchmarkSampler::ResetEventCounter()
{
while (CheckCurrentState(RUNNING))
while (true)
{
try
{

View File

@ -12,12 +12,16 @@
* @author A. Rybalchenko
*/
#include <memory> // unique_ptr
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "FairMQExample1Sampler.h"
#include "FairMQLogger.h"
using namespace std;
FairMQExample1Sampler::FairMQExample1Sampler()
: fText()
{
@ -25,18 +29,18 @@ FairMQExample1Sampler::FairMQExample1Sampler()
void FairMQExample1Sampler::CustomCleanup(void *data, void *object)
{
delete (std::string*)object;
delete (string*)object;
}
void FairMQExample1Sampler::Run()
{
while (GetCurrentState() == RUNNING)
while (CheckCurrentState(RUNNING))
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
std::string* text = new std::string(fText);
string* text = new string(fText);
FairMQMessage* msg = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
LOG(INFO) << "Sending \"" << fText << "\"";
@ -48,7 +52,7 @@ FairMQExample1Sampler::~FairMQExample1Sampler()
{
}
void FairMQExample1Sampler::SetProperty(const int key, const std::string& value)
void FairMQExample1Sampler::SetProperty(const int key, const string& value)
{
switch (key)
{
@ -61,7 +65,7 @@ void FairMQExample1Sampler::SetProperty(const int key, const std::string& value)
}
}
std::string FairMQExample1Sampler::GetProperty(const int key, const std::string& default_ /*= ""*/)
string FairMQExample1Sampler::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{

View File

@ -28,15 +28,13 @@ void FairMQExample1Sink::Run()
{
while (CheckCurrentState(RUNNING))
{
FairMQMessage* msg = fTransportFactory->CreateMessage();
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage());
if (fChannels.at("data-in").at(0).Receive(msg) > 0)
{
LOG(INFO) << "Received message: \""
<< string(static_cast<char*>(msg->GetData()), msg->GetSize())
<< "\"";
delete msg;
}
}
}

View File

@ -18,6 +18,8 @@
#include "FairMQExample2Processor.h"
#include "FairMQLogger.h"
using namespace std;
FairMQExample2Processor::FairMQExample2Processor()
: fText()
{
@ -25,25 +27,33 @@ FairMQExample2Processor::FairMQExample2Processor()
void FairMQExample2Processor::CustomCleanup(void *data, void *object)
{
delete (std::string*)object;
delete (string*)object;
}
void FairMQExample2Processor::Run()
{
// Check if we are still in the RUNNING state
while (CheckCurrentState(RUNNING))
{
FairMQMessage* input = fTransportFactory->CreateMessage();
fChannels.at("data-in").at(0).Receive(input);
// Create empty message to hold the input
unique_ptr<FairMQMessage> input(fTransportFactory->CreateMessage());
LOG(INFO) << "Received data, processing...";
// Receive the message (blocks until received or interrupted (e.g. by state change)).
// Returns size of the received message or -1 if interrupted.
if (fChannels.at("data-in").at(0).Receive(input) > 0)
{
LOG(INFO) << "Received data, processing...";
std::string* text = new std::string(static_cast<char*>(input->GetData()), input->GetSize());
*text += " (modified by " + fId + ")";
// Modify the received string
string* text = new string(static_cast<char*>(input->GetData()), input->GetSize());
*text += " (modified by " + fId + ")";
delete input;
// Create output message
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
FairMQMessage* msg = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
fChannels.at("data-out").at(0).Send(msg);
// Send out the output message
fChannels.at("data-out").at(0).Send(msg);
}
}
}

View File

@ -18,6 +18,8 @@
#include "FairMQExample2Sampler.h"
#include "FairMQLogger.h"
using namespace std;
FairMQExample2Sampler::FairMQExample2Sampler()
: fText()
{
@ -25,18 +27,19 @@ FairMQExample2Sampler::FairMQExample2Sampler()
void FairMQExample2Sampler::CustomCleanup(void *data, void *object)
{
delete (std::string*)object;
delete (string*)object;
}
void FairMQExample2Sampler::Run()
{
// Check if we are still in the RUNNING state
while (CheckCurrentState(RUNNING))
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
std::string* text = new std::string(fText);
string* text = new string(fText);
FairMQMessage* msg = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
LOG(INFO) << "Sending \"" << fText << "\"";
@ -48,7 +51,7 @@ FairMQExample2Sampler::~FairMQExample2Sampler()
{
}
void FairMQExample2Sampler::SetProperty(const int key, const std::string& value)
void FairMQExample2Sampler::SetProperty(const int key, const string& value)
{
switch (key)
{
@ -61,7 +64,7 @@ void FairMQExample2Sampler::SetProperty(const int key, const std::string& value)
}
}
std::string FairMQExample2Sampler::GetProperty(const int key, const std::string& default_ /*= ""*/)
string FairMQExample2Sampler::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{

View File

@ -28,15 +28,14 @@ void FairMQExample2Sink::Run()
{
while (CheckCurrentState(RUNNING))
{
FairMQMessage* msg = fTransportFactory->CreateMessage();
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage());
fChannels.at("data-in").at(0).Receive(msg);
LOG(INFO) << "Received message: \""
<< string(static_cast<char*>(msg->GetData()), msg->GetSize())
<< "\"";
delete msg;
if (fChannels.at("data-in").at(0).Receive(msg) > 0)
{
LOG(INFO) << "Received message: \""
<< string(static_cast<char*>(msg->GetData()), msg->GetSize())
<< "\"";
}
}
}

View File

@ -18,6 +18,8 @@
#include "FairMQExample3Processor.h"
#include "FairMQLogger.h"
using namespace std;
FairMQExample3Processor::FairMQExample3Processor()
: fTaskIndex(0)
{
@ -25,29 +27,37 @@ FairMQExample3Processor::FairMQExample3Processor()
void FairMQExample3Processor::CustomCleanup(void *data, void *object)
{
delete (std::string*)object;
delete (string*)object;
}
void FairMQExample3Processor::Run()
{
// Check if we are still in the RUNNING state
while (CheckCurrentState(RUNNING))
{
FairMQMessage* input = fTransportFactory->CreateMessage();
fChannels.at("data-in").at(0).Receive(input);
// Create empty message to hold the input
unique_ptr<FairMQMessage> input(fTransportFactory->CreateMessage());
LOG(INFO) << "Received data, processing...";
// Receive the message (blocks until received or interrupted (e.g. by state change)).
// Returns size of the received message or -1 if interrupted.
if (fChannels.at("data-in").at(0).Receive(input) > 0)
{
LOG(INFO) << "Received data, processing...";
std::string* text = new std::string(static_cast<char*>(input->GetData()), input->GetSize());
*text += " (modified by " + fId + std::to_string(fTaskIndex) + ")";
// Modify the received string
string* text = new string(static_cast<char*>(input->GetData()), input->GetSize());
*text += " (modified by " + fId + to_string(fTaskIndex) + ")";
delete input;
// Create output message
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
FairMQMessage* msg = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
fChannels.at("data-out").at(0).Send(msg);
// Send out the output message
fChannels.at("data-out").at(0).Send(msg);
}
}
}
void FairMQExample3Processor::SetProperty(const int key, const std::string& value)
void FairMQExample3Processor::SetProperty(const int key, const string& value)
{
switch (key)
{
@ -57,7 +67,7 @@ void FairMQExample3Processor::SetProperty(const int key, const std::string& valu
}
}
std::string FairMQExample3Processor::GetProperty(const int key, const std::string& default_ /*= ""*/)
string FairMQExample3Processor::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{

View File

@ -18,6 +18,8 @@
#include "FairMQExample3Sampler.h"
#include "FairMQLogger.h"
using namespace std;
FairMQExample3Sampler::FairMQExample3Sampler()
: fText()
{
@ -25,18 +27,19 @@ FairMQExample3Sampler::FairMQExample3Sampler()
void FairMQExample3Sampler::CustomCleanup(void *data, void *object)
{
delete (std::string*)object;
delete (string*)object;
}
void FairMQExample3Sampler::Run()
{
// Check if we are still in the RUNNING state
while (CheckCurrentState(RUNNING))
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
std::string* text = new std::string(fText);
string* text = new string(fText);
FairMQMessage* msg = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
LOG(INFO) << "Sending \"" << fText << "\"";
@ -48,7 +51,7 @@ FairMQExample3Sampler::~FairMQExample3Sampler()
{
}
void FairMQExample3Sampler::SetProperty(const int key, const std::string& value)
void FairMQExample3Sampler::SetProperty(const int key, const string& value)
{
switch (key)
{
@ -61,7 +64,7 @@ void FairMQExample3Sampler::SetProperty(const int key, const std::string& value)
}
}
std::string FairMQExample3Sampler::GetProperty(const int key, const std::string& default_ /*= ""*/)
string FairMQExample3Sampler::GetProperty(const int key, const string& default_ /*= ""*/)
{
switch (key)
{

View File

@ -28,15 +28,14 @@ void FairMQExample3Sink::Run()
{
while (CheckCurrentState(RUNNING))
{
FairMQMessage* msg = fTransportFactory->CreateMessage();
unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage());
fChannels.at("data-in").at(0).Receive(msg);
LOG(INFO) << "Received message: \""
<< string(static_cast<char*>(msg->GetData()), msg->GetSize())
<< "\"";
delete msg;
if (fChannels.at("data-in").at(0).Receive(msg) > 0)
{
LOG(INFO) << "Received message: \""
<< string(static_cast<char*>(msg->GetData()), msg->GetSize())
<< "\"";
}
}
}

View File

@ -3,6 +3,119 @@ Example 3: DDS
This example demonstrates usage of the Dynamic Deployment System ([DDS](http://dds.gsi.de/)) to dynamically deploy and configure a topology of devices. The topology is similar to those of Example 2, but now it can be easily distributed on different computing nodes without the need for manual reconfiguration of the devices.
The description below outlines the minimal steps needed to run the example. For more detailed DDS documentation please visit [DDS Website](http://dds.gsi.de/).
The description below outlines the minimal steps needed to run the example with DDS. For more details please refer to DDS documentation on [DDS Website](http://dds.gsi.de/).
The topology run by DDS is defined in `ex3-dds-topology.xml` and the hosts to run it on are configured in `ex3-dds-hosts.cfg`. The topology starts one Sampler, one Sink and a group of 10 Processors.
##### 1. The devices that bind their sockets need to advertise their bound addresses to DDS by writing a property.
In our example Sampler and Sink bind their sockets. The bound addresses are available after the initial validation. The following code takes the address value and gives it to DDS:
```C++
sampler.ChangeState("INIT_DEVICE");
sampler.WaitForInitialValidation();
dds::key_value::CKeyValue ddsKeyValue;
ddsKeyValue.putValue("SamplerOutputAddress", sampler.fChannels.at("data-out").at(0).GetAddress());
sampler.WaitForEndOfState("INIT_DEVICE");
```
Same approach for the Sink.
##### 2. The devices that connect their sockets need to read the addresses from DDS.
The Processors in our example need the addresses of Sampler and Sink. They receive these from DDS via properties (sent in the step above):
```C++
dds::key_value::CKeyValue ddsKeyValue;
// Sampler properties
dds::key_value::CKeyValue::valuesMap_t samplerValues;
{
mutex keyMutex;
condition_variable keyCondition;
LOG(INFO) << "Subscribing and waiting for sampler output address.";
ddsKeyValue.subscribe([&keyCondition](const string& /*_key*/, const string& /*_value*/) { keyCondition.notify_all(); });
ddsKeyValue.getValues("SamplerOutputAddress", &samplerValues);
while (samplerValues.empty())
{
unique_lock<mutex> lock(keyMutex);
keyCondition.wait_until(lock, chrono::system_clock::now() + chrono::milliseconds(1000));
ddsKeyValue.getValues("SamplerOutputAddress", &samplerValues);
}
}
// Sink properties
// ... same as above, but for sinkValues ...
processor.fChannels.at("data-in").at(0).UpdateAddress(samplerValues.begin()->second);
processor.fChannels.at("data-out").at(0).UpdateAddress(sinkValues.begin()->second);
```
After this step each device will have the necessary connection information.
##### 3. Write DDS hosts file that contains a list of worker nodes to run the topology on (When deploying using the SSH plug-in).
We run this example on the local machine for simplicity. The file below defines one worker `wn0` with 12 DDS Agents (thus able to accept 12 tasks). The parameters for each worker node are:
- user-chosen worker ID (must be unique)
- a host name with or without a login, in a form: login@host.fqdn
- additional SSH params (can be empty)
- a remote working directory
- number of DDS Agents for this worker
```bash
@bash_begin@
echo "DBG: SSH ENV Script"
#source setup.sh
@bash_end@
wn0, username@localhost, , /tmp/, 12
```
##### 4. Write DDS topology file that describes which tasks (processes) to run and their topology and configuration.
Take a look at `ex3-dds-topology.xml`. It consists of a definition part (properties, tasks, collections and more) and execution part (main). In our example Sampler, Processor and Sink tasks are defines, containing their executables and exchanged properties. The `<main>` of the topology uses the defined tasks. Besides one Sampler and one Sink task, a group containing Processor task is defined. The group has a multiplicity of 10, meaninig 10 Processors will be executed. Each of the Processors will receive the properties with Sampler and Sink addresses.
##### 5. Start DDS server.
The DDS server is started with:
```bash
dds-server start -s
```
##### 6. Submit DDS Agents (configured in the hosts file).
Agents are submitted with:
```bash
dds-submit --rms ssh --ssh-rms-cfg ex3-dds-hosts.cfg
```
The `--rms` option defines a destination resource management system. The `--ssh-rms-cfg` specifies an SSH plug-in resource definition file.
##### 7. Set the topology file.
Point DDS to the topology file:
```bash
dds-topology --set ex3-dds-topology.xml
```
##### 8. Activate the topology.
```bash
dds-topology --activate
```
##### 9. Run
After activation, agents will execute the defined tasks on the worker nodes. Output of the tasks will be stored in the directory that was specified in the hosts file.
##### 10. Stop DDS server/topology.
The execution of tasks can be stopped with:
```bash
dds-topology --stop
```
Or by stopping the DDS server:
```bash
dds-server stop
```
For a more complete DDS documentation please refer to [DDS Website](http://dds.gsi.de/).

View File

@ -3,4 +3,4 @@ echo "DBG: SSH ENV Script"
#source setup.sh
@bash_end@
worker, username@localhost, , /tmp/, 12
wn0, username@localhost, , /tmp/, 12

View File

@ -83,13 +83,20 @@ int main(int argc, char** argv)
FairMQ::tools::getHostIPs(IPs);
stringstream ss;
// Check if ib0 (infiniband) interface is available, otherwise try eth0 or wlan0.
if (IPs.count("ib0")) {
ss << "tcp://" << IPs["ib0"] << ":1";
} else if (IPs.count("eth0")) {
ss << "tcp://" << IPs["eth0"] << ":1";
} else if (IPs.count("wlan0")) {
ss << "tcp://" << IPs["wlan0"] << ":1";
} else {
if (IPs.count("ib0"))
{
ss << "tcp://" << IPs["ib0"] << ":1";
}
else if (IPs.count("eth0"))
{
ss << "tcp://" << IPs["eth0"] << ":1";
}
else if (IPs.count("wlan0"))
{
ss << "tcp://" << IPs["wlan0"] << ":1";
}
else
{
LOG(INFO) << ss.str();
LOG(ERROR) << "Could not find ib0, eth0 or wlan0";
exit(EXIT_FAILURE);

View File

@ -74,13 +74,20 @@ int main(int argc, char** argv)
FairMQ::tools::getHostIPs(IPs);
stringstream ss;
// Check if ib0 (infiniband) interface is available, otherwise try eth0 or wlan0.
if (IPs.count("ib0")) {
ss << "tcp://" << IPs["ib0"] << ":1";
} else if (IPs.count("eth0")) {
ss << "tcp://" << IPs["eth0"] << ":1";
} else if (IPs.count("wlan0")) {
ss << "tcp://" << IPs["wlan0"] << ":1";
} else {
if (IPs.count("ib0"))
{
ss << "tcp://" << IPs["ib0"] << ":1";
}
else if (IPs.count("eth0"))
{
ss << "tcp://" << IPs["eth0"] << ":1";
}
else if (IPs.count("wlan0"))
{
ss << "tcp://" << IPs["wlan0"] << ":1";
}
else
{
LOG(INFO) << ss.str();
LOG(ERROR) << "Could not find ib0, eth0 or wlan0";
exit(EXIT_FAILURE);

View File

@ -12,7 +12,7 @@
* @author A. Rybalchenko
*/
#include <memory>
#include <memory> // unique_ptr
#include <boost/thread.hpp>
#include <boost/bind.hpp>
@ -32,9 +32,9 @@ void FairMQExample4Sampler::Run()
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
std::unique_ptr<uint64_t> number(new uint64_t(counter));
uint64_t* number = new uint64_t(counter);
std::unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(number.release(), sizeof(uint64_t)));
std::unique_ptr<FairMQMessage> msg(fTransportFactory->CreateMessage(number, sizeof(uint64_t)));
LOG(INFO) << "Sending \"" << counter << "\"";

View File

@ -42,19 +42,17 @@ void FairMQExample5Client::Run()
string* text = new string(fText);
FairMQMessage* request = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
FairMQMessage* reply = fTransportFactory->CreateMessage();
unique_ptr<FairMQMessage> request(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
unique_ptr<FairMQMessage> reply(fTransportFactory->CreateMessage());
LOG(INFO) << "Sending \"" << fText << "\" to server.";
if (fChannels.at("data").at(0).Send(request) > 0)
{
fChannels.at("data").at(0).Receive(reply);
LOG(INFO) << "Received reply from server: \"" << string(static_cast<char*>(reply->GetData()), reply->GetSize()) << "\"";
}
LOG(INFO) << "Received reply from server: \"" << string(static_cast<char*>(reply->GetData()), reply->GetSize()) << "\"";
delete reply;
}
}

View File

@ -35,7 +35,7 @@ void FairMQExample5Server::Run()
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
FairMQMessage* request = fTransportFactory->CreateMessage();
unique_ptr<FairMQMessage> request(fTransportFactory->CreateMessage());
if (fChannels.at("data").at(0).Receive(request) > 0)
{
@ -43,11 +43,9 @@ void FairMQExample5Server::Run()
string* text = new string("Thank you for the \"" + string(static_cast<char*>(request->GetData()), request->GetSize()) + "\"!");
delete request;
LOG(INFO) << "Sending reply to client.";
FairMQMessage* reply = fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text);
unique_ptr<FairMQMessage> reply(fTransportFactory->CreateMessage(const_cast<char*>(text->c_str()), text->length(), CustomCleanup, text));
fChannels.at("data").at(0).Send(reply);
}

View File

@ -12,6 +12,8 @@
* @author A. Rybalchenko
*/
#include <cstdlib> // quick_exit()
#include <nanomsg/nn.h>
#include <nanomsg/pipeline.h>
#include <nanomsg/pubsub.h>
@ -72,7 +74,7 @@ FairMQPollerNN::FairMQPollerNN(map< string,vector<FairMQChannel> >& channelsMap,
{
LOG(ERROR) << "At least one of the provided channel keys for poller initialization is invalid";
LOG(ERROR) << "Out of Range error: " << oor.what() << '\n';
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
@ -107,7 +109,7 @@ FairMQPollerNN::FairMQPollerNN(FairMQSocket& dataSocket, FairMQSocket& cmdSocket
else
{
LOG(ERROR) << "invalid poller configuration, exiting.";
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
@ -161,7 +163,7 @@ bool FairMQPollerNN::CheckInput(const string channelKey, const int index)
{
LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\"";
LOG(ERROR) << "Out of Range error: " << oor.what() << '\n';
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
@ -180,7 +182,7 @@ bool FairMQPollerNN::CheckOutput(const string channelKey, const int index)
{
LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\"";
LOG(ERROR) << "Out of Range error: " << oor.what() << '\n';
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}

View File

@ -12,6 +12,7 @@
* @author A. Rybalchenko
*/
#include <cstdlib> // quick_exit()
#include <sstream>
#include "FairMQSocketNN.h"
@ -45,7 +46,7 @@ FairMQSocketNN::FairMQSocketNN(const string& type, const std::string& name, int
if (fSocket == -1)
{
LOG(ERROR) << "failed creating socket " << fId << ", reason: " << nn_strerror(errno);
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
else
@ -54,7 +55,7 @@ FairMQSocketNN::FairMQSocketNN(const string& type, const std::string& name, int
if (fSocket == -1)
{
LOG(ERROR) << "failed creating socket " << fId << ", reason: " << nn_strerror(errno);
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
if (type == "sub")
{

View File

@ -13,7 +13,7 @@
*/
#include "FairMQParser.h"
#include "FairMQLogger.h"
#include "FairLogger.h"
#include <boost/property_tree/xml_parser.hpp>
// WARNING : pragma commands to hide boost (1.54.0) warning
@ -34,19 +34,21 @@
using namespace std;
namespace FairMQParser
{
// TODO : add key-value map<string,string> parameter for replacing/updating values from keys
// function that convert property tree (given the xml or json structure) to FairMQMap
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode, const std::string& formatFlag)
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const string& deviceId, const string& rootNode, const string& formatFlag)
{
// Create fair mq map
FairMQMap channelMap;
// variables to create key for the mq map. Note: maybe device name and id useless here
std::string deviceIdKey;
std::string channelKey;
string deviceIdKey;
string channelKey;
// do a first loop just to print the device-id in xml/json input
for(const auto& p : pt.get_child(rootNode))
@ -59,13 +61,13 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
//get id attribute to choose the device
if (formatFlag == "xml")
{
deviceIdKey = p.second.get<std::string>("<xmlattr>.id");
deviceIdKey = p.second.get<string>("<xmlattr>.id");
LOG(DEBUG) << "Found device id '" << deviceIdKey << "' in XML input";
}
if (formatFlag == "json")
{
deviceIdKey = p.second.get<std::string>("id");
deviceIdKey = p.second.get<string>("id");
LOG(DEBUG) << "Found device id '"<< deviceIdKey << "' in JSON input";
}
}
@ -82,12 +84,12 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
//get id attribute to choose the device
if (formatFlag == "xml")
{
deviceIdKey = p.second.get<std::string>("<xmlattr>.id");
deviceIdKey = p.second.get<string>("<xmlattr>.id");
}
if (formatFlag == "json")
{
deviceIdKey = p.second.get<std::string>("id");
deviceIdKey = p.second.get<string>("id");
}
// if not correct device id, do not fill MQMap
@ -97,9 +99,8 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
}
// print if DEBUG log level set
std::stringstream deviceStream;
deviceStream << "[node = " << p.first
<< "] id = " << deviceIdKey;
stringstream deviceStream;
deviceStream << "[node = " << p.first << "] id = " << deviceIdKey;
LOG(DEBUG) << deviceStream.str();
// for each channel in device
@ -113,22 +114,21 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
// get name attribute to form key
if (formatFlag == "xml")
{
channelKey = q.second.get<std::string>("<xmlattr>.name");
channelKey = q.second.get<string>("<xmlattr>.name");
}
if (formatFlag == "json")
{
channelKey = q.second.get<std::string>("name");
channelKey = q.second.get<string>("name");
}
// print if DEBUG log level set
std::stringstream channelStream;
channelStream << "\t [node = " << q.first
<< "] name = " << channelKey;
stringstream channelStream;
channelStream << "\t [node = " << q.first << "] name = " << channelKey;
LOG(DEBUG) << channelStream.str();
// temporary FairMQChannel container
std::vector<FairMQChannel> channelList;
vector<FairMQChannel> channelList;
int socketCounter = 0;
// for each socket in channel
@ -143,20 +143,19 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
FairMQChannel channel;
// print if DEBUG log level set
std::stringstream socket;
socket << "\t \t [node = " << r.first
<< "] socket index = " << socketCounter;
stringstream socket;
socket << "\t \t [node = " << r.first << "] socket index = " << socketCounter;
LOG(DEBUG) << socket.str();
LOG(DEBUG) << "\t \t \t type = " << r.second.get<std::string>("type", channel.GetType());
LOG(DEBUG) << "\t \t \t method = " << r.second.get<std::string>("method", channel.GetMethod());
LOG(DEBUG) << "\t \t \t address = " << r.second.get<std::string>("address", channel.GetAddress());
LOG(DEBUG) << "\t \t \t type = " << r.second.get<string>("type", channel.GetType());
LOG(DEBUG) << "\t \t \t method = " << r.second.get<string>("method", channel.GetMethod());
LOG(DEBUG) << "\t \t \t address = " << r.second.get<string>("address", channel.GetAddress());
LOG(DEBUG) << "\t \t \t sndBufSize = " << r.second.get<int>("sndBufSize", channel.GetSndBufSize());
LOG(DEBUG) << "\t \t \t rcvBufSize = " << r.second.get<int>("rcvBufSize", channel.GetRcvBufSize());
LOG(DEBUG) << "\t \t \t rateLogging = " << r.second.get<int>("rateLogging", channel.GetRateLogging());
channel.UpdateType(r.second.get<std::string>("type", channel.GetType()));
channel.UpdateMethod(r.second.get<std::string>("method", channel.GetMethod()));
channel.UpdateAddress(r.second.get<std::string>("address", channel.GetAddress()));
channel.UpdateType(r.second.get<string>("type", channel.GetType()));
channel.UpdateMethod(r.second.get<string>("method", channel.GetMethod()));
channel.UpdateAddress(r.second.get<string>("address", channel.GetAddress()));
channel.UpdateSndBufSize(r.second.get<int>("sndBufSize", channel.GetSndBufSize())); // int
channel.UpdateRcvBufSize(r.second.get<int>("rcvBufSize", channel.GetRcvBufSize())); // int
channel.UpdateRateLogging(r.second.get<int>("rateLogging", channel.GetRateLogging())); // int
@ -165,7 +164,7 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
}// end socket loop
//fill mq map option
channelMap.insert(std::make_pair(channelKey,std::move(channelList)));
channelMap.insert(make_pair(channelKey, move(channelList)));
}
}
@ -182,37 +181,36 @@ FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string&
LOG(WARN) << "---- No channel-keys found for device-id " << deviceId;
LOG(WARN) << "---- Check the "<< formatFlag << " inputs and/or command line inputs";
}
return channelMap;
}
////////////////////////////////////////////////////////////////////////////
FairMQMap JSON::UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode)
FairMQMap JSON::UserParser(const string& filename, const string& deviceId, const string& rootNode)
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(filename, pt);
return ptreeToMQMap(pt, deviceId, rootNode,"json");
}
FairMQMap JSON::UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode)
FairMQMap JSON::UserParser(stringstream& input, const string& deviceId, const string& rootNode)
{
boost::property_tree::ptree pt;
boost::property_tree::read_json(input, pt);
return ptreeToMQMap(pt, deviceId, rootNode,"json");
}
////////////////////////////////////////////////////////////////////////////
FairMQMap XML::UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode)
FairMQMap XML::UserParser(const string& filename, const string& deviceId, const string& rootNode)
{
boost::property_tree::ptree pt;
boost::property_tree::read_xml(filename, pt);
return ptreeToMQMap(pt,deviceId,rootNode,"xml");
return ptreeToMQMap(pt, deviceId, rootNode, "xml");
}
FairMQMap XML::UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode)
FairMQMap XML::UserParser(stringstream& input, const string& deviceId, const string& rootNode)
{
boost::property_tree::ptree pt;
boost::property_tree::read_xml(input, pt);
return ptreeToMQMap(pt,deviceId,rootNode,"xml");
return ptreeToMQMap(pt, deviceId, rootNode, "xml");
}
} // end FairMQParser namespace

View File

@ -23,7 +23,7 @@
namespace FairMQParser
{
typedef std::unordered_map< std::string,std::vector<FairMQChannel> > FairMQMap;
typedef std::unordered_map<std::string, std::vector<FairMQChannel>> FairMQMap;
FairMQMap ptreeToMQMap(const boost::property_tree::ptree& pt, const std::string& deviceId, const std::string& rootNode, const std::string& formatFlag = "json");
@ -35,8 +35,8 @@ struct JSON
struct XML
{
FairMQMap UserParser(const std::string& filename, const std::string& deviceId, const std::string& root_node="fairMQOptions");
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode="fairMQOptions");
FairMQMap UserParser(const std::string& filename, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
FairMQMap UserParser(std::stringstream& input, const std::string& deviceId, const std::string& rootNode = "fairMQOptions");
};
} // FairMQParser namespace

View File

@ -5,7 +5,6 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/*
* File: FairMQProgOptions.cxx
* Author: winckler
@ -16,13 +15,15 @@
#include "FairMQProgOptions.h"
#include <algorithm>
using namespace std;
FairMQProgOptions::FairMQProgOptions()
: FairProgOptions()
, fMQParserOptions("MQ-Device parser options")
, fMQOptionsInCmd("MQ-Device options")
, fMQOptionsInCfg("MQ-Device options")
, fMQtree()
, fFairMQmap()
, fFairMQMap()
{
}
@ -30,12 +31,12 @@ FairMQProgOptions::~FairMQProgOptions()
{
}
int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregistered)
int FairMQProgOptions::ParseAll(const int argc, char** argv, bool allowUnregistered)
{
// init description
InitOptionDescription();
// parse command line options
if (ParseCmdLine(argc,argv,fCmdline_options,fvarmap,AllowUnregistered))
if (ParseCmdLine(argc, argv, fCmdLineOptions, fVarMap, allowUnregistered))
{
return 1;
}
@ -46,12 +47,14 @@ int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregiste
// check if file exist
if (fs::exists(fConfigFile))
{
if (ParseCfgFile(fConfigFile.string(), fConfig_file_options, fvarmap, AllowUnregistered))
if (ParseCfgFile(fConfigFile.string(), fConfigFileOptions, fVarMap, allowUnregistered))
{
return 1;
}
}
else
{
LOG(ERROR)<<"config file '"<< fConfigFile <<"' not found";
LOG(ERROR) << "config file '" << fConfigFile << "' not found";
return 1;
}
}
@ -59,7 +62,7 @@ int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregiste
// set log level before printing (default is 0 = DEBUG level)
std::string verbose=GetValue<std::string>("verbose");
//SET_LOG_LEVEL(DEBUG);
if(fSeverity_map.count(verbose))
if (fSeverity_map.count(verbose))
{
set_global_log_level(log_op::operation::GREATER_EQ_THAN,fSeverity_map.at(verbose));
}
@ -73,25 +76,25 @@ int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregiste
// check if one of required MQ config option is there
auto parserOption_shptr = fMQParserOptions.options();
bool option_exists=false;
std::vector<std::string> MQParserKeys;
for(const auto& p : parserOption_shptr)
bool optionExists = false;
vector<string> MQParserKeys;
for (const auto& p : parserOption_shptr)
{
MQParserKeys.push_back( p->canonical_display_name() );
if( fvarmap.count( p->canonical_display_name() ) )
MQParserKeys.push_back(p->canonical_display_name());
if (fVarMap.count(p->canonical_display_name()))
{
option_exists=true;
optionExists = true;
break;
}
}
if(!option_exists)
if (!optionExists)
{
LOG(ERROR)<<"Required option to configure the MQ device is not there.";
LOG(ERROR)<<"Please provide the value of one of the following key:";
for(const auto& p : MQParserKeys)
LOG(ERROR) << "Required option to configure the MQ device is not there.";
LOG(ERROR) << "Please provide the value of one of the following key:";
for (const auto& p : MQParserKeys)
{
LOG(ERROR)<<p;
LOG(ERROR) << p;
}
return 1;
}
@ -101,13 +104,13 @@ int FairMQProgOptions::ParseAll(const int argc, char** argv, bool AllowUnregiste
int FairMQProgOptions::NotifySwitchOption()
{
if ( fvarmap.count("help") )
if (fVarMap.count("help"))
{
LOG(INFO) << "***** FAIRMQ Program Options ***** \n" << fVisible_options;
LOG(INFO) << "***** FAIRMQ Program Options ***** \n" << fVisibleOptions;
return 1;
}
if (fvarmap.count("version"))
if (fVarMap.count("version"))
{
LOG(INFO) << "Beta version 0.1\n";
return 1;
@ -116,33 +119,31 @@ int FairMQProgOptions::NotifySwitchOption()
return 0;
}
void FairMQProgOptions::InitOptionDescription()
{
// Id required in command line if config txt file not enabled
if (fUseConfigFile)
{
fMQOptionsInCmd.add_options()
("id", po::value< std::string >(), "Device ID (required argument)")
("io-threads", po::value<int>()->default_value(1), "io threads number");
("id", po::value<string>(), "Device ID (required argument).")
("io-threads", po::value<int>()->default_value(1), "Number of I/O threads.");
fMQOptionsInCfg.add_options()
("id", po::value< std::string >()->required(), "Device ID (required argument)")
("io-threads", po::value<int>()->default_value(1), "io threads number");
("id", po::value<string>()->required(), "Device ID (required argument).")
("io-threads", po::value<int>()->default_value(1), "Number of I/O threads.");
}
else
{
fMQOptionsInCmd.add_options()
("id", po::value< std::string >()->required(), "Device ID (required argument)")
("io-threads", po::value<int>()->default_value(1), "io threads number");
("id", po::value<string>()->required(), "Device ID (required argument)")
("io-threads", po::value<int>()->default_value(1), "Number of I/O threads");
}
fMQParserOptions.add_options()
("config-xml-string", po::value< std::vector<std::string> >()->multitoken(), "XML input as command line string.")
("config-xml-file", po::value< std::string >(), "XML input as file.")
("config-json-string", po::value< std::vector<std::string> >()->multitoken(), "JSON input as command line string.")
("config-json-file", po::value< std::string >(), "JSON input as file.");
("config-xml-string", po::value<vector<string>>()->multitoken(), "XML input as command line string.")
("config-xml-file", po::value<string>(), "XML input as file.")
("config-json-string", po::value<vector<string>>()->multitoken(), "JSON input as command line string.")
("config-json-file", po::value<string>(), "JSON input as file.");
AddToCmdLineOptions(fGenericDesc);
AddToCmdLineOptions(fMQOptionsInCmd);
@ -153,5 +154,4 @@ void FairMQProgOptions::InitOptionDescription()
AddToCfgFileOptions(fMQOptionsInCfg,false);
AddToCfgFileOptions(fMQParserOptions,false);
}
}

View File

@ -14,7 +14,7 @@
*/
#ifndef FAIRMQPROGOPTIONS_H
#define FAIRMQPROGOPTIONS_H
#define FAIRMQPROGOPTIONS_H
#include <unordered_map>
@ -24,16 +24,17 @@
#include <boost/property_tree/ptree.hpp>
namespace pt = boost::property_tree;
class FairMQProgOptions : public FairProgOptions
{
protected:
typedef std::unordered_map< std::string,std::vector<FairMQChannel> > FairMQMap;
protected:
typedef std::unordered_map<std::string, std::vector<FairMQChannel>> FairMQMap;
public:
public:
FairMQProgOptions();
virtual ~FairMQProgOptions();
virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered = false);
virtual int ParseAll(const int argc, char** argv, bool allowUnregistered = false);
// external parser, store function
template <typename T, typename ...Args>
@ -53,7 +54,7 @@ public:
int Store(const po::variables_map& vm)
{
fvarmap = vm;
fVarMap = vm;
return 0;
}
@ -65,26 +66,26 @@ public:
int Store(const FairMQMap& channels)
{
fFairMQmap = channels;
fFairMQMap = channels;
return 0;
}
FairMQMap GetFairMQMap()
{
return fFairMQmap;
return fFairMQMap;
}
protected:
protected:
po::options_description fMQParserOptions;
po::options_description fMQOptionsInCfg;
po::options_description fMQOptionsInCmd;
pt::ptree fMQtree;
FairMQMap fFairMQmap;
FairMQMap fFairMQMap;
virtual int NotifySwitchOption(); // for custom help & version printing
void InitOptionDescription();
};
#endif /* FAIRMQPROGOPTIONS_H */
#endif /* FAIRMQPROGOPTIONS_H */

View File

@ -5,7 +5,6 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/*
* File: FairProgOptions.cxx
* Author: winckler
@ -15,21 +14,20 @@
#include "FairProgOptions.h"
using namespace std;
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructor / destructor
/// Constructor
FairProgOptions::FairProgOptions() :
fGenericDesc("Generic options description"),
fConfigDesc("Configuration options description"),
fHiddenDesc("Hidden options description"),
fEnvironmentDesc("Environment Variables"),
fCmdline_options("Command line options"),
fConfig_file_options("Configuration file options"),
fVisible_options("Visible options"),
fCmdLineOptions("Command line options"),
fConfigFileOptions("Configuration file options"),
fVisibleOptions("Visible options"),
fVerboseLvl("INFO"), fUseConfigFile(false), fConfigFile()
{
// //////////////////////////////////
// define generic options
fGenericDesc.add_options()
("help,h", "produce help")
@ -54,45 +52,48 @@ FairProgOptions::FairProgOptions() :
fSeverity_map["ERROR"] = fairmq::severity_level::ERROR;
fSeverity_map["STATE"] = fairmq::severity_level::STATE;
fSeverity_map["NOLOG"] = fairmq::severity_level::NOLOG;
}
/// Destructor
FairProgOptions::~FairProgOptions()
{
}
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
/// Add option descriptions
int FairProgOptions::AddToCmdLineOptions(const po::options_description& optdesc, bool visible)
int FairProgOptions::AddToCmdLineOptions(const po::options_description& optDesc, bool visible)
{
fCmdline_options.add(optdesc);
if(visible)
fVisible_options.add(optdesc);
fCmdLineOptions.add(optDesc);
if (visible)
{
fVisibleOptions.add(optDesc);
}
return 0;
}
int FairProgOptions::AddToCfgFileOptions(const po::options_description& optdesc, bool visible)
int FairProgOptions::AddToCfgFileOptions(const po::options_description& optDesc, bool visible)
{
//if UseConfigFile() not yet called, then enable it with required file name to be provided by command line
if(!fUseConfigFile)
if (!fUseConfigFile)
{
UseConfigFile();
}
fConfig_file_options.add(optdesc);
if(visible)
fVisible_options.add(optdesc);
fConfigFileOptions.add(optDesc);
if (visible)
{
fVisibleOptions.add(optDesc);
}
return 0;
}
int FairProgOptions::AddToEnvironmentOptions(const po::options_description& optdesc)
int FairProgOptions::AddToEnvironmentOptions(const po::options_description& optDesc)
{
fEnvironmentDesc.add(optdesc);
fEnvironmentDesc.add(optDesc);
return 0;
}
void FairProgOptions::UseConfigFile(const std::string& filename)
void FairProgOptions::UseConfigFile(const string& filename)
{
fUseConfigFile = true;
if (filename.empty())
@ -110,176 +111,168 @@ void FairProgOptions::UseConfigFile(const std::string& filename)
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
/// Parser
int FairProgOptions::ParseCmdLine(const int argc, char** argv, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered)
int FairProgOptions::ParseCmdLine(const int argc, char** argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
{
// //////////////////////////////////
// get options from cmd line and store in variable map
// here we use command_line_parser instead of parse_command_line, to allow unregistered and positional options
if(AllowUnregistered)
if (allowUnregistered)
{
po::command_line_parser parser{argc, argv};
parser.options(desc).allow_unregistered();
po::parsed_options parsedOptions = parser.run();
po::store(parsedOptions,varmap);
po::store(parsedOptions, varmap);
}
else
{
po::store(po::parse_command_line(argc, argv, desc), varmap);
}
// //////////////////////////////////
// call the virtual NotifySwitchOption method to handle switch options like e.g. "--help" or "--version"
// return 1 if switch options found in varmap
if(NotifySwitchOption())
if (NotifySwitchOption())
{
return 1;
}
po::notify(varmap);
return 0;
}
int FairProgOptions::ParseCmdLine(const int argc, char** argv, const po::options_description& desc, bool AllowUnregistered)
int FairProgOptions::ParseCmdLine(const int argc, char** argv, const po::options_description& desc, bool allowUnregistered)
{
return ParseCmdLine(argc,argv,desc,fvarmap,AllowUnregistered);
return ParseCmdLine(argc,argv,desc,fVarMap,allowUnregistered);
}
int FairProgOptions::ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered)
int FairProgOptions::ParseCfgFile(ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
{
if (!ifs)
{
std::cout << "can not open configuration file \n";
cout << "can not open configuration file \n";
return -1;
}
else
{
po:store(parse_config_file(ifs, desc, AllowUnregistered), varmap);
po:store(parse_config_file(ifs, desc, allowUnregistered), varmap);
po::notify(varmap);
}
return 0;
}
int FairProgOptions::ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered)
int FairProgOptions::ParseCfgFile(const string& filename, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
{
std::ifstream ifs(filename.c_str());
ifstream ifs(filename.c_str());
if (!ifs)
{
std::cout << "can not open configuration file: " << filename << "\n";
cout << "can not open configuration file: " << filename << "\n";
return -1;
}
else
{
po:store(parse_config_file(ifs, desc, AllowUnregistered), varmap);
po:store(parse_config_file(ifs, desc, allowUnregistered), varmap);
po::notify(varmap);
}
return 0;
}
int FairProgOptions::ParseCfgFile(const std::string& filename, const po::options_description& desc, bool AllowUnregistered)
int FairProgOptions::ParseCfgFile(const string& filename, const po::options_description& desc, bool allowUnregistered)
{
return ParseCfgFile(filename,desc,fvarmap,AllowUnregistered);
return ParseCfgFile(filename,desc,fVarMap,allowUnregistered);
}
int FairProgOptions::ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool AllowUnregistered)
int FairProgOptions::ParseCfgFile(ifstream& ifs, const po::options_description& desc, bool allowUnregistered)
{
return ParseCfgFile(ifs,desc,fvarmap,AllowUnregistered);
return ParseCfgFile(ifs,desc,fVarMap,allowUnregistered);
}
int FairProgOptions::ParseEnvironment(const std::function<std::string(std::string)> & environment_mapper)
int FairProgOptions::ParseEnvironment(const function<string(string)>& environmentMapper)
{
po::store(po::parse_environment(fEnvironmentDesc, environment_mapper), fvarmap);
po::notify(fvarmap);
po::store(po::parse_environment(fEnvironmentDesc, environmentMapper), fVarMap);
po::notify(fVarMap);
return 0;
}
// Given a key, convert the variable value to string
std::string FairProgOptions::GetStringValue(const std::string& key)
string FairProgOptions::GetStringValue(const string& key)
{
string valueStr;
try
{
std::string val_str;
try
if (fVarMap.count(key))
{
if ( fvarmap.count(key) )
auto& value = fVarMap[key].value();
// string albeit useless here
if (auto q = boost::any_cast<string>(&value))
{
auto& value = fvarmap[key].value();
valueStr = VariableValueToString<string>(fVarMap[key]);
return valueStr;
}
// vector<string>
if (auto q = boost::any_cast<vector<string>>(&value))
{
valueStr = VariableValueToString<vector<string>>(fVarMap[key]);
return valueStr;
}
// string albeit useless here
if(auto q = boost::any_cast< std::string >(&value ))
{
val_str = variable_value_to_string< std::string >(fvarmap[key]);
return val_str;
}
// int
if (auto q = boost::any_cast<int>(&value))
{
valueStr = VariableValueToString<int>(fVarMap[key]);
return valueStr;
}
// vector<string>
if(auto q = boost::any_cast< std::vector<std::string> >(&value ))
{
val_str = variable_value_to_string< std::vector<std::string> >(fvarmap[key]);
return val_str;
}
// vector<int>
if (auto q = boost::any_cast<vector<int>>(&value))
{
valueStr = VariableValueToString<vector<int>>(fVarMap[key]);
return valueStr;
}
// int
if(auto q = boost::any_cast< int >(&value ))
{
val_str = variable_value_to_string< int >(fvarmap[key]);
return val_str;
}
// float
if (auto q = boost::any_cast<float>(&value))
{
valueStr = VariableValueToString<float>(fVarMap[key]);
return valueStr;
}
// vector<int>
if(auto q = boost::any_cast< std::vector<int> >(&value ))
{
val_str = variable_value_to_string< std::vector<int> >(fvarmap[key]);
return val_str;
}
// float
if(auto q = boost::any_cast< float >(&value ))
{
val_str = variable_value_to_string< float >(fvarmap[key]);
return val_str;
}
// vector float
if(auto q = boost::any_cast< std::vector<float> >(&value ))
{
val_str = variable_value_to_string< std::vector<float> >(fvarmap[key]);
return val_str;
}
// double
if(auto q = boost::any_cast< double >(&value ))
{
val_str = variable_value_to_string< double >(fvarmap[key]);
return val_str;
}
// vector double
if(auto q = boost::any_cast< std::vector<double> >(&value ))
{
val_str = variable_value_to_string< std::vector<double> >(fvarmap[key]);
return val_str;
}
// vector float
if (auto q = boost::any_cast<vector<float>>(&value))
{
valueStr = VariableValueToString<vector<float>>(fVarMap[key]);
return valueStr;
}
// double
if (auto q = boost::any_cast<double>(&value))
{
valueStr = VariableValueToString<double>(fVarMap[key]);
return valueStr;
}
// vector double
if (auto q = boost::any_cast<vector<double>>(&value))
{
valueStr = VariableValueToString<vector<double>>(fVarMap[key]);
return valueStr;
}
}
catch(std::exception& e)
{
LOG(ERROR) << "Exception thrown for the key '" << key << "'";
LOG(ERROR) << e.what();
}
return val_str;
}
catch(exception& e)
{
LOG(ERROR) << "Exception thrown for the key '" << key << "'";
LOG(ERROR) << e.what();
}
return valueStr;
}
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
/// Print/notify options
int FairProgOptions::PrintHelp() const
{
std::cout << fVisible_options << "\n";
cout << fVisibleOptions << "\n";
return 0;
}
@ -289,205 +282,210 @@ int FairProgOptions::PrintOptions()
// Method to overload.
// -> loop over variable map and print its content
// -> In this example the following types are supported:
// std::string, int, float, double, boost::filesystem::path
// std::vector<std::string>, std::vector<int>, std::vector<float>, std::vector<double>
// string, int, float, double, boost::filesystem::path
// vector<string>, vector<int>, vector<float>, vector<double>
MapVarValInfo_t mapinfo;
// get string length for formatting and convert varmap values into string
int maxlen_1st = 0;
int maxlen_2nd = 0;
int maxlen_TypeInfo = 0;
int maxlen_default =0;
int maxlen_empty = 0;
int total_len=0;
for (const auto& m : fvarmap)
int maxLength1st = 0;
int maxLength2nd = 0;
int maxLengthTypeInfo = 0;
int maxLengthDefault = 0;
int maxLengthEmpty = 0;
int totalLength = 0;
for (const auto& m : fVarMap)
{
Max(maxlen_1st, m.first.length());
Max(maxLength1st, m.first.length());
VarValInfo_t valinfo=Get_variable_value_info(m.second);
mapinfo[m.first]=valinfo;
std::string val_str;
std::string typeInfo_str;
std::string default_str;
std::string empty_str;
std::tie(val_str,typeInfo_str,default_str,empty_str)=valinfo;
Max(maxlen_2nd, val_str.length());
Max(maxlen_TypeInfo, typeInfo_str.length());
Max(maxlen_default, default_str.length());
Max(maxlen_empty, empty_str.length());
VarValInfo_t valinfo = GetVariableValueInfo(m.second);
mapinfo[m.first] = valinfo;
string valueStr;
string typeInfoStr;
string defaultStr;
string emptyStr;
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = valinfo;
Max(maxLength2nd, valueStr.length());
Max(maxLengthTypeInfo, typeInfoStr.length());
Max(maxLengthDefault, defaultStr.length());
Max(maxLengthEmpty, emptyStr.length());
}
// TODO : limit the value length field in a better way
if(maxlen_2nd>100)
maxlen_2nd=100;
total_len=maxlen_1st+maxlen_2nd+maxlen_TypeInfo+maxlen_default+maxlen_empty;
if (maxLength2nd > 100)
{
maxLength2nd = 100;
}
totalLength = maxLength1st + maxLength2nd + maxLengthTypeInfo + maxLengthDefault + maxLengthEmpty;
//maxlen_2nd=200;
// maxLength2nd = 200;
// formatting and printing
LOG(INFO)<<std::setfill ('*') << std::setw (total_len+3)<<"*";// +3 because of string " = "
std::string PrintOptionsTitle=" Program options found ";
LOG(INFO) << setfill ('*') << setw (totalLength + 3) << "*";// +3 because of string " = "
string PrintOptionsTitle = " Program options found ";
int leftSpace_len=0;
int rightSpace_len=0;
int leftTitle_shift_len=0;
int rightTitle_shift_len=0;
int leftSpaceLength = 0;
int rightSpaceLength = 0;
int leftTitleShiftLength = 0;
int rightTitleShiftLength = 0;
leftTitle_shift_len=PrintOptionsTitle.length()/2;
leftTitleShiftLength = PrintOptionsTitle.length() / 2;
if ((PrintOptionsTitle.length()) % 2)
rightTitle_shift_len=leftTitle_shift_len+1;
rightTitleShiftLength = leftTitleShiftLength + 1;
else
rightTitle_shift_len=leftTitle_shift_len;
rightTitleShiftLength = leftTitleShiftLength;
leftSpace_len=(total_len+3)/2-leftTitle_shift_len;
if ((total_len+3) % 2)
rightSpace_len=(total_len+3)/2-rightTitle_shift_len+1;
leftSpaceLength = (totalLength + 3) / 2 - leftTitleShiftLength;
if ((totalLength + 3) % 2)
{
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength + 1;
}
else
rightSpace_len=(total_len+3)/2-rightTitle_shift_len;
{
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
}
LOG(INFO) << setfill ('*') << setw(leftSpaceLength) << "*"
<< setw(PrintOptionsTitle.length()) << PrintOptionsTitle
<< setfill ('*') << setw(rightSpaceLength) << "*";
LOG(INFO) << std::setfill ('*') << std::setw(leftSpace_len) <<"*"
<< std::setfill(' ')
<< std::setw(PrintOptionsTitle.length()) << PrintOptionsTitle
<< std::setfill ('*') << std::setw(rightSpace_len) <<"*";
LOG(INFO) <<std::setfill ('*') << std::setw (total_len+3)<<"*";
LOG(INFO) << setfill ('*') << setw (totalLength+3) << "*";
for (const auto& p : mapinfo)
{
std::string key_str;
std::string val_str;
std::string typeInfo_str;
std::string default_str;
std::string empty_str;
key_str=p.first;
std::tie(val_str,typeInfo_str,default_str,empty_str)=p.second;
LOG(INFO) << std::setfill(' ')
<< std::setw(maxlen_1st)<<std::left
string keyStr;
string valueStr;
string typeInfoStr;
string defaultStr;
string emptyStr;
keyStr = p.first;
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
LOG(INFO) << std::setfill(' ')
<< setw(maxLength1st) << left
<< p.first << " = "
<< std::setw(maxlen_2nd)
<< val_str
<< std::setw(maxlen_TypeInfo)
<< typeInfo_str
<< std::setw(maxlen_default)
<< default_str
<< std::setw(maxlen_empty)
<< empty_str;
<< setw(maxLength2nd)
<< valueStr
<< setw(maxLengthTypeInfo)
<< typeInfoStr
<< setw(maxLengthDefault)
<< defaultStr
<< setw(maxLengthEmpty)
<< emptyStr;
}
LOG(INFO)<<std::setfill ('*') << std::setw (total_len+3)<<"*";// +3 for " = "
LOG(INFO) << setfill ('*') << setw (totalLength + 3) << "*";// +3 for " = "
return 0;
}
int FairProgOptions::NotifySwitchOption()
{
// //////////////////////////////////
// Method to overload.
if ( fvarmap.count("help") )
if (fVarMap.count("help"))
{
std::cout << "***** FAIR Program Options ***** \n" << fVisible_options;
cout << "***** FAIR Program Options ***** \n" << fVisibleOptions;
return 1;
}
if (fvarmap.count("version"))
if (fVarMap.count("version"))
{
std::cout << "alpha version 0.0\n";
cout << "alpha version 0.0\n";
return 1;
}
return 0;
}
FairProgOptions::VarValInfo_t FairProgOptions::Get_variable_value_info(const po::variable_value& var_val)
FairProgOptions::VarValInfo_t FairProgOptions::GetVariableValueInfo(const po::variable_value& varValue)
{
// tuple<valueStr, type_info_str, defaultStr, empty>
auto& value = varValue.value();
string defaultedValue;
string emptyValue;
if (varValue.empty())
{
// tuple<val_str, type_info_str, default_str, empty>
auto& value = var_val.value();
std::string defaulted_val;
std::string empty_val;
if(var_val.empty())
empty_val=" [empty]";
emptyValue = " [empty]";
}
else
{
if (varValue.defaulted())
{
defaultedValue = " [default value]";
}
else
if(var_val.defaulted())
defaulted_val=" [default value]";
else
defaulted_val=" [provided value]";
empty_val+=" *";
// string
if(auto q = boost::any_cast< std::string >(&value))
{
std::string val_str = *q;
return std::make_tuple(val_str,std::string(" [Type=string]"),defaulted_val,empty_val);
defaultedValue = " [provided value]";
}
// vector<string>
if(auto q = boost::any_cast< std::vector<std::string> >(&value))
{
std::string val_str = variable_value_to_string< std::vector<std::string> >(var_val);
return std::make_tuple(val_str,std::string(" [Type=vector<string>]"),defaulted_val,empty_val);
}
// int
if(auto q = boost::any_cast< int >(&value))
{
std::string val_str = variable_value_to_string< int >(var_val);
return std::make_tuple(val_str,std::string(" [Type=int]"),defaulted_val,empty_val);
}
// vector<int>
if(auto q = boost::any_cast< std::vector<int> >(&value))
{
std::string val_str = variable_value_to_string< std::vector<int> >(var_val);
return std::make_tuple(val_str,std::string(" [Type=vector<int>]"),defaulted_val,empty_val);
}
// float
if(auto q = boost::any_cast< float >(&value))
{
std::string val_str = variable_value_to_string< float >(var_val);
return std::make_tuple(val_str,std::string(" [Type=float]"),defaulted_val,empty_val);
}
// vector<float>
if(auto q = boost::any_cast< std::vector<float> >(&value))
{
std::string val_str = variable_value_to_string< std::vector<float> >(var_val);
return std::make_tuple(val_str,std::string(" [Type=vector<float>]"),defaulted_val,empty_val);
}
// double
if(auto q = boost::any_cast< double >(&value))
{
std::string val_str = variable_value_to_string< double >(var_val);
return std::make_tuple(val_str,std::string(" [Type=double]"),defaulted_val,empty_val);
}
// vector<double>
if(auto q = boost::any_cast< std::vector<double> >(&value))
{
std::string val_str = variable_value_to_string< std::vector<double> >(var_val);
return std::make_tuple(val_str,std::string(" [Type=vector<double>]"),defaulted_val,empty_val);
}
// boost::filesystem::path
if(auto q = boost::any_cast<boost::filesystem::path>(&value))
{
std::string val_str = (*q).string();
//std::string val_str = (*q).filename().generic_string();
return std::make_tuple(val_str,std::string(" [Type=boost::filesystem::path]"),defaulted_val,empty_val);
}
// if we get here, the type is not supported return unknown info
return std::make_tuple(std::string("Unknown value"), std::string(" [Type=Unknown]"),defaulted_val,empty_val);
}
emptyValue += " *";
// string
if (auto q = boost::any_cast<string>(&value))
{
string valueStr = *q;
return make_tuple(valueStr, string(" [Type=string]"), defaultedValue, emptyValue);
}
// vector<string>
if (auto q = boost::any_cast<vector<string>>(&value))
{
string valueStr = VariableValueToString<vector<string>>(varValue);
return make_tuple(valueStr, string(" [Type=vector<string>]"), defaultedValue, emptyValue);
}
// int
if (auto q = boost::any_cast<int>(&value))
{
string valueStr = VariableValueToString<int>(varValue);
return make_tuple(valueStr, string(" [Type=int]"), defaultedValue, emptyValue);
}
// vector<int>
if (auto q = boost::any_cast<vector<int>>(&value))
{
string valueStr = VariableValueToString<vector<int>>(varValue);
return make_tuple(valueStr, string(" [Type=vector<int>]"), defaultedValue, emptyValue);
}
// float
if (auto q = boost::any_cast<float>(&value))
{
string valueStr = VariableValueToString<float>(varValue);
return make_tuple(valueStr, string(" [Type=float]"), defaultedValue, emptyValue);
}
// vector<float>
if (auto q = boost::any_cast<vector<float>>(&value))
{
string valueStr = VariableValueToString<vector<float>>(varValue);
return make_tuple(valueStr, string(" [Type=vector<float>]"), defaultedValue, emptyValue);
}
// double
if (auto q = boost::any_cast<double>(&value))
{
string valueStr = VariableValueToString<double>(varValue);
return make_tuple(valueStr, string(" [Type=double]"), defaultedValue, emptyValue);
}
// vector<double>
if (auto q = boost::any_cast<vector<double>>(&value))
{
string valueStr = VariableValueToString<vector<double>>(varValue);
return make_tuple(valueStr, string(" [Type=vector<double>]"), defaultedValue, emptyValue);
}
// boost::filesystem::path
if (auto q = boost::any_cast<boost::filesystem::path>(&value))
{
string valueStr = (*q).string();
//string valueStr = (*q).filename().generic_string();
return make_tuple(valueStr, string(" [Type=boost::filesystem::path]"), defaultedValue, emptyValue);
}
// if we get here, the type is not supported return unknown info
return make_tuple(string("Unknown value"), string(" [Type=Unknown]"), defaultedValue, emptyValue);
}

View File

@ -5,7 +5,6 @@
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
/*
* File: FairProgOptions.h
* Author: winckler
@ -14,7 +13,7 @@
*/
#ifndef FAIRPROGOPTIONS_H
#define FAIRPROGOPTIONS_H
#define FAIRPROGOPTIONS_H
#include "FairMQLogger.h"
#include <boost/program_options.hpp>
@ -39,14 +38,16 @@
* public :
* MyOptions() : FairProgOptions()
* {
* fCmdline_options.add(fGenericDesc);
* fVisible_options.add(fCmdline_options);
* fCmdlineOptions.add(fGenericDesc);
* fVisibleOptions.add(fCmdlineOptions);
* }
* virtual ~MyOptions(){}
* virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered = false)
* virtual ~MyOptions() {}
* virtual int ParseAll(const int argc, char** argv, bool allowUnregistered = false)
* {
* if(ParseCmdLine(argc,argv,fCmdline_options,fvarmap,AllowUnregistered))
* if(ParseCmdLine(argc, argv, fCmdlineOptions, fVarMap, allowUnregistered))
* {
* return 1;
* }
*
* PrintOptions();
* return 0;
@ -66,14 +67,14 @@ namespace fs = boost::filesystem;
class FairProgOptions
{
public:
public:
FairProgOptions();
virtual ~FairProgOptions();
// add options_description
int AddToCmdLineOptions(const po::options_description& optdesc, bool visible = true);
int AddToCfgFileOptions(const po::options_description& optdesc, bool visible = true);
int AddToEnvironmentOptions(const po::options_description& optdesc);
int AddToCmdLineOptions(const po::options_description& optDesc, bool visible = true);
int AddToCfgFileOptions(const po::options_description& optDesc, bool visible = true);
int AddToEnvironmentOptions(const po::options_description& optDesc);
void UseConfigFile(const std::string& filename = "");
@ -84,9 +85,9 @@ public:
T val = T();
try
{
if (fvarmap.count(key))
if (fVarMap.count(key))
{
val = fvarmap[key].as<T>();
val = fVarMap[key].as<T>();
}
}
catch(std::exception& e)
@ -102,27 +103,27 @@ public:
// convert value to string that corresponds to the key
std::string GetStringValue(const std::string& key);
const po::variables_map& GetVarMap() const {return fvarmap;}
const po::variables_map& GetVarMap() const {return fVarMap;}
// boost prog options parsers
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered = false);
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, bool AllowUnregistered = false);
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
int ParseCmdLine(const int argc, char** argv, const po::options_description& desc, bool allowUnregistered = false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered = false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, bool AllowUnregistered = false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool AllowUnregistered = false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool AllowUnregistered = false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
int ParseCfgFile(const std::string& filename, const po::options_description& desc, bool allowUnregistered = false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool allowUnregistered = false);
int ParseEnvironment(const std::function<std::string(std::string)>&);
virtual int ParseAll(const int argc, char** argv, bool AllowUnregistered = false) = 0;
virtual int ParseAll(const int argc, char** argv, bool allowUnregistered = false) = 0;
virtual int PrintOptions();
int PrintHelp() const;
protected:
protected:
// options container
po::variables_map fvarmap;
po::variables_map fVarMap;
// basic description categories
po::options_description fGenericDesc;
@ -131,14 +132,13 @@ protected:
po::options_description fHiddenDesc;
// Description of cmd line and simple configuration file (configuration file like txt, but not like xml json ini)
po::options_description fCmdline_options;
po::options_description fConfig_file_options;
po::options_description fCmdLineOptions;
po::options_description fConfigFileOptions;
// Description which is printed in help command line
po::options_description fVisible_options;
// to handle logger severity
std::map<std::string,fairmq::severity_level> fSeverity_map;
std::map<std::string,fairmq::severity_level> fSeverityMap;
po::options_description fVisibleOptions;
std::string fVerboseLvl;
bool fUseConfigFile;
@ -149,7 +149,7 @@ protected:
template<typename T>
void UpadateVarMap(const std::string& key, const T& val)
{
replace(fvarmap, key, val);
replace(fVarMap, key, val);
}
template<typename T>
@ -158,25 +158,24 @@ protected:
vm[opt].value() = boost::any(val);
}
private:
// /////////////////////////////////////////////
private:
// Methods below are helper functions used in the PrintOptions method
typedef std::tuple<std::string, std::string,std::string, std::string> VarValInfo_t;
typedef std::map<std::string, VarValInfo_t > MapVarValInfo_t;
typedef std::map<std::string, VarValInfo_t> MapVarValInfo_t;
VarValInfo_t Get_variable_value_info(const po::variable_value& var_val);
VarValInfo_t GetVariableValueInfo(const po::variable_value& varValue);
template<typename T>
std::string variable_value_to_string(const po::variable_value& var_val)
std::string VariableValueToString(const po::variable_value& varValue)
{
auto& value = var_val.value();
auto& value = varValue.value();
std::ostringstream ostr;
if (auto q = boost::any_cast<T>(&value))
{
ostr << *q;
}
std::string val_str = ostr.str();
return val_str;
std::string valStr = ostr.str();
return valStr;
}
static void Max(int &val, const int &comp)
@ -188,6 +187,4 @@ private:
}
};
#endif /* FAIRPROGOPTIONS_H */
#endif /* FAIRPROGOPTIONS_H */

View File

@ -17,6 +17,7 @@
#include "boost/program_options.hpp"
#include "FairMQLogger.h"
#include "FairMQTools.h"
#include "FairMQParser.h"
#include "FairMQProgOptions.h"
#include "FairMQBenchmarkSampler.h"
@ -72,7 +73,6 @@ int main(int argc, char** argv)
sampler.SetTransport(new FairMQTransportFactoryZMQ());
#endif
sampler.SetProperty(FairMQBenchmarkSampler::Id, id);
sampler.SetProperty(FairMQBenchmarkSampler::EventSize, eventSize);
sampler.SetProperty(FairMQBenchmarkSampler::EventRate, eventRate);

View File

@ -2,7 +2,7 @@
#define FAIRMQTOOLS_H_
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */
#define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST
#endif
#include <sys/socket.h>
@ -23,6 +23,12 @@ namespace FairMQ
namespace tools
{
template<typename T, typename ...Args>
unique_ptr<T> make_unique(Args&& ...args)
{
return unique_ptr<T>(new T(forward<Args>(args)...));
}
int getHostIPs(map<string, string>& addressMap)
{
struct ifaddrs *ifaddr, *ifa;

View File

@ -12,6 +12,7 @@
* @author D. Klein, A. Rybalchenko
*/
#include <cstdlib> // quick_exit()
#include <sstream>
#include "FairMQLogger.h"
@ -24,7 +25,7 @@ FairMQContextZMQ::FairMQContextZMQ(int numIoThreads)
if (fContext == NULL)
{
LOG(ERROR) << "failed creating context, reason: " << zmq_strerror(errno);
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
if (zmq_ctx_set(fContext, ZMQ_IO_THREADS, numIoThreads) != 0)

View File

@ -12,6 +12,8 @@
* @author A. Rybalchenko
*/
#include <cstdlib> // quick_exit()
#include <zmq.h>
#include "FairMQPollerZMQ.h"
@ -72,11 +74,11 @@ FairMQPollerZMQ::FairMQPollerZMQ(map< string,vector<FairMQChannel> >& channelsMa
{
LOG(ERROR) << "At least one of the provided channel keys for poller initialization is invalid";
LOG(ERROR) << "Out of Range error: " << oor.what() << '\n';
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
FairMQPollerZMQ::FairMQPollerZMQ(FairMQSocket& dataSocket, FairMQSocket& cmdSocket)
FairMQPollerZMQ::FairMQPollerZMQ(FairMQSocket& cmdSocket, FairMQSocket& dataSocket)
: items()
, fNumItems(2)
, fOffsetMap()
@ -111,7 +113,7 @@ FairMQPollerZMQ::FairMQPollerZMQ(FairMQSocket& dataSocket, FairMQSocket& cmdSock
else
{
LOG(ERROR) << "invalid poller configuration, exiting.";
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
@ -165,7 +167,7 @@ bool FairMQPollerZMQ::CheckInput(const string channelKey, const int index)
{
LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\"";
LOG(ERROR) << "Out of Range error: " << oor.what() << '\n';
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}
@ -184,7 +186,7 @@ bool FairMQPollerZMQ::CheckOutput(const string channelKey, const int index)
{
LOG(ERROR) << "Invalid channel key: \"" << channelKey << "\"";
LOG(ERROR) << "Out of Range error: " << oor.what() << '\n';
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}

View File

@ -43,7 +43,7 @@ class FairMQPollerZMQ : public FairMQPoller
virtual ~FairMQPollerZMQ();
private:
FairMQPollerZMQ(FairMQSocket& dataSocket, FairMQSocket& cmdSocket);
FairMQPollerZMQ(FairMQSocket& cmdSocket, FairMQSocket& dataSocket);
zmq_pollitem_t* items;
int fNumItems;

View File

@ -12,6 +12,7 @@
* @author D. Klein, A. Rybalchenko
*/
#include <cstdlib> // quick_exit()
#include <sstream>
#include "FairMQSocketZMQ.h"
@ -43,7 +44,7 @@ FairMQSocketZMQ::FairMQSocketZMQ(const string& type, const string& name, int num
if (fSocket == NULL)
{
LOG(ERROR) << "failed creating socket " << fId << ", reason: " << zmq_strerror(errno);
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
if (zmq_setsockopt(fSocket, ZMQ_IDENTITY, &fId, fId.length()) != 0)
@ -99,7 +100,7 @@ void FairMQSocketZMQ::Connect(const string& address)
{
LOG(ERROR) << "failed connecting socket " << fId << ", reason: " << zmq_strerror(errno);
// error here means incorrect configuration. exit if it happens.
exit(EXIT_FAILURE);
quick_exit(EXIT_FAILURE);
}
}