- Proper process termination:

if interrupted with CTRL+C blocking socket calls will return with -1. Each device should call FairMQDevice::Shutdown() before ending the running state to close open sockets, otherwise the interrupt call itself will block.

- FIX: Update number of received messages for FairMQFileSink.
- Add ability to poll on outputs for FairMQPoller.
This commit is contained in:
Alexey Rybalchenko 2014-08-12 09:11:51 +02:00 committed by Mohammad Al-Turany
parent 8cd120aef4
commit 0a610926a1
23 changed files with 236 additions and 208 deletions

View File

@ -15,7 +15,8 @@ if(PROTOBUF_FOUND)
set(INCLUDE_DIRECTORIES set(INCLUDE_DIRECTORIES
${INCLUDE_DIRECTORIES} ${INCLUDE_DIRECTORIES}
${PROTOBUF_INCLUDE_DIR} ${PROTOBUF_INCLUDE_DIR}
${CMAKE_SOURCE_DIR}/fairmq/prototest # # following directory is only for protobuf tests and is not essential part of FairMQ
#${CMAKE_SOURCE_DIR}/fairmq/prototest
) )
endif(PROTOBUF_FOUND) endif(PROTOBUF_FOUND)
@ -59,14 +60,15 @@ set(SRCS
) )
if(PROTOBUF_FOUND) if(PROTOBUF_FOUND)
set(SRCS # following source files are only for protobuf tests and are not essential part of FairMQ
${SRCS} # set(SRCS
"prototest/payload.pb.cc" # ${SRCS}
"prototest/FairMQProtoSampler.cxx" # "prototest/payload.pb.cc"
"prototest/FairMQBinSampler.cxx" # "prototest/FairMQProtoSampler.cxx"
"prototest/FairMQBinSink.cxx" # "prototest/FairMQBinSampler.cxx"
"prototest/FairMQProtoSink.cxx" # "prototest/FairMQBinSink.cxx"
) # "prototest/FairMQProtoSink.cxx"
# )
set(DEPENDENCIES set(DEPENDENCIES
${DEPENDENCIES} ${DEPENDENCIES}
${PROTOBUF_LIBRARY} ${PROTOBUF_LIBRARY}
@ -117,15 +119,16 @@ set(Exe_Names
sink sink
proxy) proxy)
if(PROTOBUF_FOUND) # following executables are only for protobuf tests and are not essential part of FairMQ
set(Exe_Names # if(PROTOBUF_FOUND)
${Exe_Names} # set(Exe_Names
binsampler # ${Exe_Names}
protosampler # binsampler
binsink # protosampler
protosink # binsink
) # protosink
endif(PROTOBUF_FOUND) # )
# endif(PROTOBUF_FOUND)
set(Exe_Source set(Exe_Source
run/runBenchmarkSampler.cxx run/runBenchmarkSampler.cxx
@ -136,15 +139,16 @@ set(Exe_Source
run/runProxy.cxx run/runProxy.cxx
) )
if(PROTOBUF_FOUND) # following source files are only for protobuf tests and are not essential part of FairMQ
set(Exe_Source # if(PROTOBUF_FOUND)
${Exe_Source} # set(Exe_Source
run/runBinSampler.cxx # ${Exe_Source}
run/runProtoSampler.cxx # run/runBinSampler.cxx
run/runBinSink.cxx # run/runProtoSampler.cxx
run/runProtoSink.cxx # run/runBinSink.cxx
) # run/runProtoSink.cxx
endif(PROTOBUF_FOUND) # )
# endif(PROTOBUF_FOUND)
list(LENGTH Exe_Names _length) list(LENGTH Exe_Names _length)
math(EXPR _length ${_length}-1) math(EXPR _length ${_length}-1)

View File

@ -256,79 +256,61 @@ void FairMQDevice::LogSocketRates()
timestamp_t t0; timestamp_t t0;
timestamp_t t1; timestamp_t t1;
timestamp_t timeSinceLastLog_ms; timestamp_t msSinceLastLog;
vector<unsigned long> bytesInput(fNumInputs); vector<unsigned long> bytesIn(fNumInputs);
vector<unsigned long> messagesInput(fNumInputs); vector<unsigned long> msgIn(fNumInputs);
vector<unsigned long> bytesOutput(fNumOutputs); vector<unsigned long> bytesOut(fNumOutputs);
vector<unsigned long> messagesOutput(fNumOutputs); vector<unsigned long> msgOut(fNumOutputs);
vector<unsigned long> bytesInputNew(fNumInputs); vector<unsigned long> bytesInNew(fNumInputs);
vector<unsigned long> messagesInputNew(fNumInputs); vector<unsigned long> msgInNew(fNumInputs);
vector<unsigned long> bytesOutputNew(fNumOutputs); vector<unsigned long> bytesOutNew(fNumOutputs);
vector<unsigned long> messagesOutputNew(fNumOutputs); vector<unsigned long> msgOutNew(fNumOutputs);
vector<double> megabytesPerSecondInput(fNumInputs); vector<double> mbPerSecIn(fNumInputs);
vector<double> messagesPerSecondInput(fNumInputs); vector<double> msgPerSecIn(fNumInputs);
vector<double> megabytesPerSecondOutput(fNumOutputs); vector<double> mbPerSecOut(fNumOutputs);
vector<double> messagesPerSecondOutput(fNumOutputs); vector<double> msgPerSecOut(fNumOutputs);
// Temp stuff for process termination
// bool receivedSomething = false;
// bool sentSomething = false;
// int didNotReceiveFor = 0;
// int didNotSendFor = 0;
// End of temp stuff
int i = 0; int i = 0;
for (vector<FairMQSocket*>::iterator itr = fPayloadInputs->begin(); itr != fPayloadInputs->end(); itr++) for (vector<FairMQSocket*>::iterator itr = fPayloadInputs->begin(); itr != fPayloadInputs->end(); itr++)
{ {
bytesInput.at(i) = (*itr)->GetBytesRx(); bytesIn.at(i) = (*itr)->GetBytesRx();
messagesInput.at(i) = (*itr)->GetMessagesRx(); msgIn.at(i) = (*itr)->GetMessagesRx();
++i; ++i;
} }
i = 0; i = 0;
for (vector<FairMQSocket*>::iterator itr = fPayloadOutputs->begin(); itr != fPayloadOutputs->end(); itr++) for (vector<FairMQSocket*>::iterator itr = fPayloadOutputs->begin(); itr != fPayloadOutputs->end(); itr++)
{ {
bytesOutput.at(i) = (*itr)->GetBytesTx(); bytesOut.at(i) = (*itr)->GetBytesTx();
messagesOutput.at(i) = (*itr)->GetMessagesTx(); msgOut.at(i) = (*itr)->GetMessagesTx();
++i; ++i;
} }
t0 = get_timestamp(); t0 = get_timestamp();
while (true) while (fState == RUNNING)
{ {
try try
{ {
t1 = get_timestamp(); t1 = get_timestamp();
timeSinceLastLog_ms = (t1 - t0) / 1000.0L; msSinceLastLog = (t1 - t0) / 1000.0L;
i = 0; i = 0;
for (vector<FairMQSocket*>::iterator itr = fPayloadInputs->begin(); itr != fPayloadInputs->end(); itr++) for (vector<FairMQSocket*>::iterator itr = fPayloadInputs->begin(); itr != fPayloadInputs->end(); itr++)
{ {
bytesInputNew.at(i) = (*itr)->GetBytesRx(); bytesInNew.at(i) = (*itr)->GetBytesRx();
megabytesPerSecondInput.at(i) = ((double)(bytesInputNew.at(i) - bytesInput.at(i)) / (1024. * 1024.)) / (double)timeSinceLastLog_ms * 1000.; mbPerSecIn.at(i) = ((double)(bytesInNew.at(i) - bytesIn.at(i)) / (1024. * 1024.)) / (double)msSinceLastLog * 1000.;
bytesInput.at(i) = bytesInputNew.at(i); bytesIn.at(i) = bytesInNew.at(i);
messagesInputNew.at(i) = (*itr)->GetMessagesRx(); msgInNew.at(i) = (*itr)->GetMessagesRx();
messagesPerSecondInput.at(i) = (double)(messagesInputNew.at(i) - messagesInput.at(i)) / (double)timeSinceLastLog_ms * 1000.; msgPerSecIn.at(i) = (double)(msgInNew.at(i) - msgIn.at(i)) / (double)msSinceLastLog * 1000.;
messagesInput.at(i) = messagesInputNew.at(i); msgIn.at(i) = msgInNew.at(i);
LOG(DEBUG) << "#" << fId << "." << (*itr)->GetId() << ": " << messagesPerSecondInput.at(i) << " msg/s, " << megabytesPerSecondInput.at(i) << " MB/s"; LOG(DEBUG) << "#" << fId << "." << (*itr)->GetId() << ": " << msgPerSecIn.at(i) << " msg/s, " << mbPerSecIn.at(i) << " MB/s";
// Temp stuff for process termination
// if ( !receivedSomething && messagesPerSecondInput.at(i) > 0 ) {
// receivedSomething = true;
// }
// if ( receivedSomething && messagesPerSecondInput.at(i) == 0 ) {
// cout << "Did not receive anything on socket " << i << " for " << didNotReceiveFor++ << " seconds." << endl;
// } else {
// didNotReceiveFor = 0;
// }
// End of temp stuff
++i; ++i;
} }
@ -337,52 +319,29 @@ void FairMQDevice::LogSocketRates()
for (vector<FairMQSocket*>::iterator itr = fPayloadOutputs->begin(); itr != fPayloadOutputs->end(); itr++) for (vector<FairMQSocket*>::iterator itr = fPayloadOutputs->begin(); itr != fPayloadOutputs->end(); itr++)
{ {
bytesOutputNew.at(i) = (*itr)->GetBytesTx(); bytesOutNew.at(i) = (*itr)->GetBytesTx();
megabytesPerSecondOutput.at(i) = ((double)(bytesOutputNew.at(i) - bytesOutput.at(i)) / (1024. * 1024.)) / (double)timeSinceLastLog_ms * 1000.; mbPerSecOut.at(i) = ((double)(bytesOutNew.at(i) - bytesOut.at(i)) / (1024. * 1024.)) / (double)msSinceLastLog * 1000.;
bytesOutput.at(i) = bytesOutputNew.at(i); bytesOut.at(i) = bytesOutNew.at(i);
messagesOutputNew.at(i) = (*itr)->GetMessagesTx(); msgOutNew.at(i) = (*itr)->GetMessagesTx();
messagesPerSecondOutput.at(i) = (double)(messagesOutputNew.at(i) - messagesOutput.at(i)) / (double)timeSinceLastLog_ms * 1000.; msgPerSecOut.at(i) = (double)(msgOutNew.at(i) - msgOut.at(i)) / (double)msSinceLastLog * 1000.;
messagesOutput.at(i) = messagesOutputNew.at(i); msgOut.at(i) = msgOutNew.at(i);
LOG(DEBUG) << "#" << fId << "." << (*itr)->GetId() << ": " << messagesPerSecondOutput.at(i) << " msg/s, " << megabytesPerSecondOutput.at(i) LOG(DEBUG) << "#" << fId << "." << (*itr)->GetId() << ": " << msgPerSecOut.at(i) << " msg/s, " << mbPerSecOut.at(i) << " MB/s";
<< " MB/s";
// Temp stuff for process termination
// if ( !sentSomething && messagesPerSecondOutput.at(i) > 0 ) {
// sentSomething = true;
// }
// if ( sentSomething && messagesPerSecondOutput.at(i) == 0 ) {
// cout << "Did not send anything on socket " << i << " for " << didNotSendFor++ << " seconds." << endl;
// } else {
// didNotSendFor = 0;
// }
// End of temp stuff
++i; ++i;
} }
// Temp stuff for process termination
// if (receivedSomething && didNotReceiveFor > 5) {
// cout << "stopping because nothing was received for 5 seconds." << endl;
// ChangeState(STOP);
// }
// if (sentSomething && didNotSendFor > 5) {
// cout << "stopping because nothing was sent for 5 seconds." << endl;
// ChangeState(STOP);
// }
// End of temp stuff
t0 = t1; t0 = t1;
boost::this_thread::sleep(boost::posix_time::milliseconds(fLogIntervalInMs)); boost::this_thread::sleep(boost::posix_time::milliseconds(fLogIntervalInMs));
} }
catch (boost::thread_interrupted&) catch (boost::thread_interrupted&)
{ {
cout << "rateLogger interrupted" << endl; LOG(INFO) << "FairMQDevice::LogSocketRates() interrupted";
break; break;
} }
} }
LOG(INFO) << ">>>>>>> stopping rateLogger <<<<<<<"; LOG(INFO) << ">>>>>>> stopping FairMQDevice::LogSocketRates() <<<<<<<";
} }
void FairMQDevice::ListenToCommands() void FairMQDevice::ListenToCommands()
@ -404,6 +363,24 @@ void FairMQDevice::Shutdown()
} }
} }
void FairMQDevice::Terminate()
{
// Termination signal has to be sent only once to any socket.
// Find available socket and send termination signal to it.
if (fPayloadInputs->size() > 0)
{
fPayloadInputs->at(0)->Terminate();
}
else if (fPayloadOutputs->size() > 0)
{
fPayloadOutputs->at(0)->Terminate();
}
else
{
LOG(ERROR) << "No sockets available to terminate.";
}
}
FairMQDevice::~FairMQDevice() FairMQDevice::~FairMQDevice()
{ {
for (vector<FairMQSocket*>::iterator itr = fPayloadInputs->begin(); itr != fPayloadInputs->end(); itr++) for (vector<FairMQSocket*>::iterator itr = fPayloadInputs->begin(); itr != fPayloadInputs->end(); itr++)

View File

@ -88,6 +88,8 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
vector<FairMQSocket*>* fPayloadInputs; vector<FairMQSocket*>* fPayloadInputs;
vector<FairMQSocket*>* fPayloadOutputs; vector<FairMQSocket*>* fPayloadOutputs;
FairMQSocket* fCommandSocket;
int fLogIntervalInMs; int fLogIntervalInMs;
FairMQTransportFactory* fTransportFactory; FairMQTransportFactory* fTransportFactory;
@ -98,6 +100,8 @@ class FairMQDevice : public FairMQStateMachine, public FairMQConfigurable
virtual void Shutdown(); virtual void Shutdown();
virtual void InitOutput(); virtual void InitOutput();
virtual void InitInput(); virtual void InitInput();
virtual void Terminate();
}; };
#endif /* FAIRMQDEVICE_H_ */ #endif /* FAIRMQDEVICE_H_ */

View File

@ -32,14 +32,6 @@ FairMQLogger::~FairMQLogger()
std::ostringstream& FairMQLogger::Log(int type) std::ostringstream& FairMQLogger::Log(int type)
{ {
timestamp_t tm = get_timestamp();
timestamp_t ms = tm / 1000.0L;
timestamp_t s = ms / 1000.0L;
std::time_t t = s;
// std::size_t fractional_seconds = ms % 1000;
char mbstr[100];
std::strftime(mbstr, 100, "%H:%M:%S", std::localtime(&t));
string type_str; string type_str;
switch (type) switch (type)
{ {
@ -61,6 +53,14 @@ std::ostringstream& FairMQLogger::Log(int type)
break; break;
} }
timestamp_t tm = get_timestamp();
timestamp_t ms = tm / 1000.0L;
timestamp_t s = ms / 1000.0L;
std::time_t t = s;
// std::size_t fractional_seconds = ms % 1000;
char mbstr[100];
std::strftime(mbstr, 100, "%H:%M:%S", std::localtime(&t));
os << "[\033[01;36m" << mbstr << "\033[0m]" os << "[\033[01;36m" << mbstr << "\033[0m]"
<< "[" << type_str << "]" << "[" << type_str << "]"
<< " "; << " ";

View File

@ -20,6 +20,7 @@ class FairMQPoller
public: public:
virtual void Poll(int timeout) = 0; virtual void Poll(int timeout) = 0;
virtual bool CheckInput(int index) = 0; virtual bool CheckInput(int index) = 0;
virtual bool CheckOutput(int index) = 0;
virtual ~FairMQPoller() {}; virtual ~FairMQPoller() {};
}; };

View File

@ -29,12 +29,13 @@ class FairMQSocket
virtual void Bind(const string& address) = 0; virtual void Bind(const string& address) = 0;
virtual void Connect(const string& address) = 0; virtual void Connect(const string& address) = 0;
virtual size_t Send(FairMQMessage* msg, const string& flag="") = 0; virtual int Send(FairMQMessage* msg, const string& flag="") = 0;
virtual size_t Receive(FairMQMessage* msg, const string& flag="") = 0; virtual int Receive(FairMQMessage* msg, const string& flag="") = 0;
virtual void* GetSocket() = 0; virtual void* GetSocket() = 0;
virtual int GetSocket(int nothing) = 0; virtual int GetSocket(int nothing) = 0;
virtual void Close() = 0; virtual void Close() = 0;
virtual void Terminate() = 0;
virtual void SetOption(const string& option, const void* value, size_t valueSize) = 0; virtual void SetOption(const string& option, const void* value, size_t valueSize) = 0;
virtual void GetOption(const string& option, void* value, size_t* valueSize) = 0; virtual void GetOption(const string& option, void* value, size_t* valueSize) = 0;

View File

@ -33,27 +33,13 @@ namespace msmf = boost::msm::front;
namespace FairMQFSM namespace FairMQFSM
{ {
// defining events for the boost MSM state machine // defining events for the boost MSM state machine
struct INIT struct INIT {};
{ struct SETOUTPUT {};
}; struct SETINPUT {};
struct SETOUTPUT struct PAUSE {};
{ struct RUN {};
}; struct STOP {};
struct SETINPUT struct END {};
{
};
struct PAUSE
{
};
struct RUN
{
};
struct STOP
{
};
struct END
{
};
// defining the boost MSM state machine // defining the boost MSM state machine
struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_> struct FairMQFSM_ : public msm::front::state_machine_def<FairMQFSM_>
@ -70,24 +56,12 @@ namespace FairMQFSM
LOG(STATE) << "Exiting FairMQ state machine"; LOG(STATE) << "Exiting FairMQ state machine";
} }
// The list of FSM states // The list of FSM states
struct IDLE_FSM : public msm::front::state<> struct IDLE_FSM : public msm::front::state<> {};
{ struct INITIALIZING_FSM : public msm::front::state<> {};
}; struct SETTINGOUTPUT_FSM : public msm::front::state<> {};
struct INITIALIZING_FSM : public msm::front::state<> struct SETTINGINPUT_FSM : public msm::front::state<> {};
{ struct WAITING_FSM : public msm::front::state<> {};
}; struct RUNNING_FSM : public msm::front::state<> {};
struct SETTINGOUTPUT_FSM : public msm::front::state<>
{
};
struct SETTINGINPUT_FSM : public msm::front::state<>
{
};
struct WAITING_FSM : public msm::front::state<>
{
};
struct RUNNING_FSM : public msm::front::state<>
{
};
// Define initial state // Define initial state
typedef IDLE_FSM initial_state; typedef IDLE_FSM initial_state;
// Actions // Actions
@ -141,8 +115,8 @@ namespace FairMQFSM
void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&)
{ {
fsm.fState = IDLE; fsm.fState = IDLE;
fsm.Terminate();
fsm.running_state.join(); fsm.running_state.join();
fsm.Shutdown();
} }
}; };
struct PauseFct struct PauseFct
@ -156,24 +130,13 @@ namespace FairMQFSM
} }
}; };
// actions to be overwritten by derived classes // actions to be overwritten by derived classes
virtual void Init() virtual void Init() {}
{ virtual void Run() {}
} virtual void Pause() {}
virtual void Run() virtual void Shutdown() {}
{ virtual void InitOutput() {}
} virtual void InitInput() {}
virtual void Pause() virtual void Terminate() {} // Termination method called during StopFct action.
{
}
virtual void Shutdown()
{
}
virtual void InitOutput()
{
}
virtual void InitInput()
{
}
// Transition table for FairMQFMS // Transition table for FairMQFMS
struct transition_table : mpl::vector< struct transition_table : mpl::vector<
// Start Event Next Action Guard // Start Event Next Action Guard

View File

@ -68,12 +68,14 @@ void FairMQBenchmarkSampler::Run()
try { try {
rateLogger.interrupt(); rateLogger.interrupt();
resetEventCounter.interrupt();
rateLogger.join(); rateLogger.join();
resetEventCounter.interrupt();
resetEventCounter.join(); resetEventCounter.join();
} catch(boost::thread_resource_error& e) { } catch(boost::thread_resource_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
} }
FairMQDevice::Shutdown();
} }
void FairMQBenchmarkSampler::ResetEventCounter() void FairMQBenchmarkSampler::ResetEventCounter()

View File

@ -30,17 +30,17 @@ void FairMQBuffer::Run()
boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this));
bool received = false; int received = 0;
while (fState == RUNNING) while (fState == RUNNING)
{ {
FairMQMessage* msg = fTransportFactory->CreateMessage(); FairMQMessage* msg = fTransportFactory->CreateMessage();
received = fPayloadInputs->at(0)->Receive(msg); received = fPayloadInputs->at(0)->Receive(msg);
if (received) if (received > 0)
{ {
fPayloadOutputs->at(0)->Send(msg); fPayloadOutputs->at(0)->Send(msg);
received = false; received = 0;
} }
delete msg; delete msg;
@ -52,6 +52,8 @@ void FairMQBuffer::Run()
} catch(boost::thread_resource_error& e) { } catch(boost::thread_resource_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
} }
FairMQDevice::Shutdown();
} }
FairMQBuffer::~FairMQBuffer() FairMQBuffer::~FairMQBuffer()

View File

@ -35,7 +35,7 @@ void FairMQMerger::Run()
FairMQPoller* poller = fTransportFactory->CreatePoller(*fPayloadInputs); FairMQPoller* poller = fTransportFactory->CreatePoller(*fPayloadInputs);
bool received = false; int received = 0;
while (fState == RUNNING) while (fState == RUNNING)
{ {
@ -49,10 +49,10 @@ void FairMQMerger::Run()
{ {
received = fPayloadInputs->at(i)->Receive(msg); received = fPayloadInputs->at(i)->Receive(msg);
} }
if (received) if (received > 0)
{ {
fPayloadOutputs->at(0)->Send(msg); fPayloadOutputs->at(0)->Send(msg);
received = false; received = 0;
} }
} }
@ -67,4 +67,6 @@ void FairMQMerger::Run()
} catch(boost::thread_resource_error& e) { } catch(boost::thread_resource_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
} }
FairMQDevice::Shutdown();
} }

View File

@ -34,15 +34,15 @@ void FairMQProxy::Run()
FairMQMessage* msg = fTransportFactory->CreateMessage(); FairMQMessage* msg = fTransportFactory->CreateMessage();
size_t bytes_received = 0; int received = 0;
while (fState == RUNNING) while (fState == RUNNING)
{ {
bytes_received = fPayloadInputs->at(0)->Receive(msg); received = fPayloadInputs->at(0)->Receive(msg);
if (bytes_received) if (received > 0)
{ {
fPayloadOutputs->at(0)->Send(msg); fPayloadOutputs->at(0)->Send(msg);
bytes_received = 0; received = 0;
} }
} }
@ -54,4 +54,6 @@ void FairMQProxy::Run()
} catch(boost::thread_resource_error& e) { } catch(boost::thread_resource_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
} }
FairMQDevice::Shutdown();
} }

View File

@ -28,13 +28,13 @@ void FairMQSink::Run()
boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this));
size_t bytes_received = 0; int received = 0;
while (fState == RUNNING) while (fState == RUNNING)
{ {
FairMQMessage* msg = fTransportFactory->CreateMessage(); FairMQMessage* msg = fTransportFactory->CreateMessage();
bytes_received = fPayloadInputs->at(0)->Receive(msg); received = fPayloadInputs->at(0)->Receive(msg);
delete msg; delete msg;
} }
@ -45,6 +45,8 @@ void FairMQSink::Run()
} catch(boost::thread_resource_error& e) { } catch(boost::thread_resource_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
} }
FairMQDevice::Shutdown();
} }
FairMQSink::~FairMQSink() FairMQSink::~FairMQSink()

View File

@ -32,7 +32,7 @@ void FairMQSplitter::Run()
boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this)); boost::thread rateLogger(boost::bind(&FairMQDevice::LogSocketRates, this));
bool received = false; int received = 0;
int direction = 0; int direction = 0;
while (fState == RUNNING) while (fState == RUNNING)
@ -41,7 +41,7 @@ void FairMQSplitter::Run()
received = fPayloadInputs->at(0)->Receive(msg); received = fPayloadInputs->at(0)->Receive(msg);
if (received) if (received > 0)
{ {
fPayloadOutputs->at(direction)->Send(msg); fPayloadOutputs->at(direction)->Send(msg);
direction++; direction++;
@ -49,7 +49,7 @@ void FairMQSplitter::Run()
{ {
direction = 0; direction = 0;
} }
received = false; received = 0;
} }
delete msg; delete msg;
@ -61,4 +61,6 @@ void FairMQSplitter::Run()
} catch(boost::thread_resource_error& e) { } catch(boost::thread_resource_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
} }
FairMQDevice::Shutdown();
} }

View File

@ -13,6 +13,7 @@
*/ */
#include <cstring> #include <cstring>
#include <stdlib.h>
#include <nanomsg/nn.h> #include <nanomsg/nn.h>

View File

@ -41,6 +41,14 @@ bool FairMQPollerNN::CheckInput(int index)
return false; return false;
} }
bool FairMQPollerNN::CheckOutput(int index)
{
if (items[index].revents & NN_POLLOUT)
return true;
return false;
}
FairMQPollerNN::~FairMQPollerNN() FairMQPollerNN::~FairMQPollerNN()
{ {
if (items != NULL) if (items != NULL)

View File

@ -29,6 +29,7 @@ class FairMQPollerNN : public FairMQPoller
virtual void Poll(int timeout); virtual void Poll(int timeout);
virtual bool CheckInput(int index); virtual bool CheckInput(int index);
virtual bool CheckOutput(int index);
virtual ~FairMQPollerNN(); virtual ~FairMQPollerNN();

View File

@ -69,7 +69,7 @@ void FairMQSocketNN::Connect(const string& address)
} }
} }
size_t FairMQSocketNN::Send(FairMQMessage* msg, const string& flag) int FairMQSocketNN::Send(FairMQMessage* msg, const string& flag)
{ {
void* ptr = msg->GetMessage(); void* ptr = msg->GetMessage();
int rc = nn_send(fSocket, &ptr, NN_MSG, 0); int rc = nn_send(fSocket, &ptr, NN_MSG, 0);
@ -87,7 +87,7 @@ size_t FairMQSocketNN::Send(FairMQMessage* msg, const string& flag)
return rc; return rc;
} }
size_t FairMQSocketNN::Receive(FairMQMessage* msg, const string& flag) int FairMQSocketNN::Receive(FairMQMessage* msg, const string& flag)
{ {
void* ptr = NULL; void* ptr = NULL;
int rc = nn_recv(fSocket, &ptr, NN_MSG, 0); int rc = nn_recv(fSocket, &ptr, NN_MSG, 0);
@ -106,6 +106,16 @@ size_t FairMQSocketNN::Receive(FairMQMessage* msg, const string& flag)
return rc; return rc;
} }
void FairMQSocketNN::Close()
{
nn_close(fSocket);
}
void FairMQSocketNN::Terminate()
{
nn_term();
}
void* FairMQSocketNN::GetSocket() void* FairMQSocketNN::GetSocket()
{ {
return NULL; // dummy method to comply with the interface. functionality not possible in zeromq. return NULL; // dummy method to comply with the interface. functionality not possible in zeromq.
@ -116,11 +126,6 @@ int FairMQSocketNN::GetSocket(int nothing)
return fSocket; return fSocket;
} }
void FairMQSocketNN::Close()
{
nn_close(fSocket);
}
void FairMQSocketNN::SetOption(const string& option, const void* value, size_t valueSize) void FairMQSocketNN::SetOption(const string& option, const void* value, size_t valueSize)
{ {
int rc = nn_setsockopt(fSocket, NN_SOL_SOCKET, GetConstant(option), value, valueSize); int rc = nn_setsockopt(fSocket, NN_SOL_SOCKET, GetConstant(option), value, valueSize);
@ -186,6 +191,8 @@ int FairMQSocketNN::GetConstant(const string& constant)
LOG(ERROR) << "Multipart messages functionality currently not supported by nanomsg!"; LOG(ERROR) << "Multipart messages functionality currently not supported by nanomsg!";
return -1; return -1;
} }
if (constant == "linger")
return NN_LINGER;
return -1; return -1;
} }

View File

@ -31,12 +31,13 @@ class FairMQSocketNN : public FairMQSocket
virtual void Bind(const string& address); virtual void Bind(const string& address);
virtual void Connect(const string& address); virtual void Connect(const string& address);
virtual size_t Send(FairMQMessage* msg, const string& flag=""); virtual int Send(FairMQMessage* msg, const string& flag="");
virtual size_t Receive(FairMQMessage* msg, const string& flag=""); virtual int Receive(FairMQMessage* msg, const string& flag="");
virtual void* GetSocket(); virtual void* GetSocket();
virtual int GetSocket(int nothing); virtual int GetSocket(int nothing);
virtual void Close(); virtual void Close();
virtual void Terminate();
virtual void SetOption(const string& option, const void* value, size_t valueSize); virtual void SetOption(const string& option, const void* value, size_t valueSize);
virtual void GetOption(const string& option, void* value, size_t* valueSize); virtual void GetOption(const string& option, void* value, size_t* valueSize);

View File

@ -51,8 +51,11 @@ void FairMQContextZMQ::Close()
int rc = zmq_ctx_destroy(fContext); int rc = zmq_ctx_destroy(fContext);
if (rc != 0) if (rc != 0)
{ {
LOG(ERROR) << "failed closing context, reason: " << zmq_strerror(errno); if (errno == EINTR) {
LOG(ERROR) << " failed closing context, reason: " << zmq_strerror(errno);
} else {
fContext = NULL;
return;
}
} }
fContext = NULL;
} }

View File

@ -15,6 +15,7 @@
#include <zmq.h> #include <zmq.h>
#include "FairMQPollerZMQ.h" #include "FairMQPollerZMQ.h"
#include "FairMQLogger.h"
FairMQPollerZMQ::FairMQPollerZMQ(const vector<FairMQSocket*>& inputs) FairMQPollerZMQ::FairMQPollerZMQ(const vector<FairMQSocket*>& inputs)
{ {
@ -32,7 +33,11 @@ FairMQPollerZMQ::FairMQPollerZMQ(const vector<FairMQSocket*>& inputs)
void FairMQPollerZMQ::Poll(int timeout) void FairMQPollerZMQ::Poll(int timeout)
{ {
zmq_poll(items, fNumItems, timeout); int rc = zmq_poll(items, fNumItems, timeout);
if (rc < 0)
{
LOG(ERROR) << "polling failed, reason: " << zmq_strerror(errno);
}
} }
bool FairMQPollerZMQ::CheckInput(int index) bool FairMQPollerZMQ::CheckInput(int index)
@ -43,6 +48,14 @@ bool FairMQPollerZMQ::CheckInput(int index)
return false; return false;
} }
bool FairMQPollerZMQ::CheckOutput(int index)
{
if (items[index].revents & ZMQ_POLLOUT)
return true;
return false;
}
FairMQPollerZMQ::~FairMQPollerZMQ() FairMQPollerZMQ::~FairMQPollerZMQ()
{ {
if (items != NULL) if (items != NULL)

View File

@ -29,6 +29,7 @@ class FairMQPollerZMQ : public FairMQPoller
virtual void Poll(int timeout); virtual void Poll(int timeout);
virtual bool CheckInput(int index); virtual bool CheckInput(int index);
virtual bool CheckOutput(int index);
virtual ~FairMQPollerZMQ(); virtual ~FairMQPollerZMQ();

View File

@ -40,7 +40,16 @@ FairMQSocketZMQ::FairMQSocketZMQ(const string& type, int num, int numIoThreads)
rc = zmq_setsockopt(fSocket, ZMQ_IDENTITY, &fId, fId.length()); rc = zmq_setsockopt(fSocket, ZMQ_IDENTITY, &fId, fId.length());
if (rc != 0) if (rc != 0)
{ {
LOG(ERROR) << "failed setting socket option, reason: " << zmq_strerror(errno); LOG(ERROR) << "failed setting ZMQ_IDENTITY socket option, reason: " << zmq_strerror(errno);
}
// Tell socket to try and send/receive outstanding messages for <linger> milliseconds before terminating.
// Default value for ZeroMQ is -1, which is to wait forever.
int linger = 500;
rc = zmq_setsockopt(fSocket, ZMQ_LINGER, &linger, sizeof(linger));
if (rc != 0)
{
LOG(ERROR) << "failed setting ZMQ_LINGER socket option, reason: " << zmq_strerror(errno);
} }
if (type == "sub") if (type == "sub")
@ -48,7 +57,7 @@ FairMQSocketZMQ::FairMQSocketZMQ(const string& type, int num, int numIoThreads)
rc = zmq_setsockopt(fSocket, ZMQ_SUBSCRIBE, NULL, 0); rc = zmq_setsockopt(fSocket, ZMQ_SUBSCRIBE, NULL, 0);
if (rc != 0) if (rc != 0)
{ {
LOG(ERROR) << "failed setting socket option, reason: " << zmq_strerror(errno); LOG(ERROR) << "failed setting ZMQ_SUBSCRIBE socket option, reason: " << zmq_strerror(errno);
} }
} }
@ -82,7 +91,7 @@ void FairMQSocketZMQ::Connect(const string& address)
} }
} }
size_t FairMQSocketZMQ::Send(FairMQMessage* msg, const string& flag) int FairMQSocketZMQ::Send(FairMQMessage* msg, const string& flag)
{ {
int nbytes = zmq_msg_send(static_cast<zmq_msg_t*>(msg->GetMessage()), fSocket, GetConstant(flag)); int nbytes = zmq_msg_send(static_cast<zmq_msg_t*>(msg->GetMessage()), fSocket, GetConstant(flag));
if (nbytes >= 0) if (nbytes >= 0)
@ -93,13 +102,18 @@ size_t FairMQSocketZMQ::Send(FairMQMessage* msg, const string& flag)
} }
if (zmq_errno() == EAGAIN) if (zmq_errno() == EAGAIN)
{ {
return false; return 0;
}
if (zmq_errno() == ETERM)
{
LOG(INFO) << "terminating socket #" << fId;
return -1;
} }
LOG(ERROR) << "failed sending on socket #" << fId << ", reason: " << zmq_strerror(errno); LOG(ERROR) << "failed sending on socket #" << fId << ", reason: " << zmq_strerror(errno);
return nbytes; return nbytes;
} }
size_t FairMQSocketZMQ::Receive(FairMQMessage* msg, const string& flag) int FairMQSocketZMQ::Receive(FairMQMessage* msg, const string& flag)
{ {
int nbytes = zmq_msg_recv(static_cast<zmq_msg_t*>(msg->GetMessage()), fSocket, GetConstant(flag)); int nbytes = zmq_msg_recv(static_cast<zmq_msg_t*>(msg->GetMessage()), fSocket, GetConstant(flag));
if (nbytes >= 0) if (nbytes >= 0)
@ -110,7 +124,12 @@ size_t FairMQSocketZMQ::Receive(FairMQMessage* msg, const string& flag)
} }
if (zmq_errno() == EAGAIN) if (zmq_errno() == EAGAIN)
{ {
return false; return 0;
}
if (zmq_errno() == ETERM)
{
LOG(INFO) << "terminating socket #" << fId;
return -1;
} }
LOG(ERROR) << "failed receiving on socket #" << fId << ", reason: " << zmq_strerror(errno); LOG(ERROR) << "failed receiving on socket #" << fId << ", reason: " << zmq_strerror(errno);
return nbytes; return nbytes;
@ -132,6 +151,15 @@ void FairMQSocketZMQ::Close()
fSocket = NULL; fSocket = NULL;
} }
void FairMQSocketZMQ::Terminate()
{
int rc = zmq_ctx_destroy(fContext->GetContext());
if (rc != 0)
{
LOG(ERROR) << "failed terminating context, reason: " << zmq_strerror(errno);
}
}
void* FairMQSocketZMQ::GetSocket() void* FairMQSocketZMQ::GetSocket()
{ {
return fSocket; return fSocket;
@ -204,6 +232,8 @@ int FairMQSocketZMQ::GetConstant(const string& constant)
return ZMQ_SNDMORE; return ZMQ_SNDMORE;
if (constant == "rcv-more") if (constant == "rcv-more")
return ZMQ_RCVMORE; return ZMQ_RCVMORE;
if (constant == "linger")
return ZMQ_LINGER;
return -1; return -1;
} }

View File

@ -32,12 +32,13 @@ class FairMQSocketZMQ : public FairMQSocket
virtual void Bind(const string& address); virtual void Bind(const string& address);
virtual void Connect(const string& address); virtual void Connect(const string& address);
virtual size_t Send(FairMQMessage* msg, const string& flag=""); virtual int Send(FairMQMessage* msg, const string& flag="");
virtual size_t Receive(FairMQMessage* msg, const string& flag=""); virtual int Receive(FairMQMessage* msg, const string& flag="");
virtual void* GetSocket(); virtual void* GetSocket();
virtual int GetSocket(int nothing); virtual int GetSocket(int nothing);
virtual void Close(); virtual void Close();
virtual void Terminate();
virtual void SetOption(const string& option, const void* value, size_t valueSize); virtual void SetOption(const string& option, const void* value, size_t valueSize);
virtual void GetOption(const string& option, void* value, size_t* valueSize); virtual void GetOption(const string& option, void* value, size_t* valueSize);