zmq hwm are specified to 2 for gui and restreaming of receiver if all zmq not closed at end of acquiistion

This commit is contained in:
2020-10-08 13:01:01 +02:00
parent c9bba6fbdc
commit 6c1035aa99
21 changed files with 614 additions and 190 deletions

View File

@ -1257,7 +1257,40 @@ std::string CmdProxy::ReceiverHostname(int action) {
return os.str();
}
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
std::string CmdProxy::ZMQHWM(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[n_limit] \n\tClient's zmq receive high water mark. Default is "
"the zmq library's default (1000), can also be set here using "
"-1. \n This is a high number and can be set to 2 for gui "
"purposes. \n One must also set the receiver's send high water "
"mark to similar value. Final effect is sum of them.\n\t Setting "
"it via command line is useful only before zmq enabled (before "
"opening gui)."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty()) {
WrongNumberOfParameters(0);
}
auto t = det->getClientZmqHwm();
os << t << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
int t = StringTo<int>(args[0]);
det->setClientZmqHwm(t);
os << det->getClientZmqHwm() << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* Eiger Specific */
std::string CmdProxy::Threshold(int action) {
@ -2681,7 +2714,7 @@ std::string CmdProxy::ExecuteCommand(int action) {
throw sls::RuntimeError("Cannot get.");
} else if (action == defs::PUT_ACTION) {
std::string command;
for (auto &i: args) {
for (auto &i : args) {
command += (i + ' ');
}
auto t = det->executeCommand(command, std::vector<int>{det_id});

View File

@ -235,6 +235,36 @@
return os.str(); \
}
/** int, set no id, get id */
#define INTEGER_COMMAND_SET_NOID_GET_ID(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \
std::string CMDNAME(const int action) { \
std::ostringstream os; \
os << cmd << ' '; \
if (action == slsDetectorDefs::HELP_ACTION) \
os << HLPSTR << '\n'; \
else if (action == slsDetectorDefs::GET_ACTION) { \
if (!args.empty()) { \
WrongNumberOfParameters(0); \
} \
auto t = det->GETFCN(std::vector<int>{det_id}); \
os << OutString(t) << '\n'; \
} else if (action == slsDetectorDefs::PUT_ACTION) { \
if (det_id != -1) { \
throw sls::RuntimeError( \
"Cannot execute this at module level"); \
} \
if (args.size() != 1) { \
WrongNumberOfParameters(1); \
} \
auto val = CONV(args[0]); \
det->SETFCN(val); \
os << args.front() << '\n'; \
} else { \
throw sls::RuntimeError("Unknown action"); \
} \
return os.str(); \
}
/** int, no id */
#define INTEGER_COMMAND_NOID(CMDNAME, GETFCN, SETFCN, CONV, HLPSTR) \
std::string CMDNAME(const int action) { \
@ -868,6 +898,8 @@ class CmdProxy {
{"zmqport", &CmdProxy::zmqport},
{"rx_zmqip", &CmdProxy::rx_zmqip},
{"zmqip", &CmdProxy::zmqip},
{"zmqhwm", &CmdProxy::ZMQHWM},
{"rx_zmqhwm", &CmdProxy::rx_zmqhwm},
/* Eiger Specific */
{"subexptime", &CmdProxy::subexptime},
@ -1071,6 +1103,7 @@ class CmdProxy {
std::string ReceiverHostname(int action);
/* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */
std::string ZMQHWM(int action);
/* Eiger Specific */
std::string Threshold(int action);
std::string ThresholdNoTb(int action);
@ -1692,6 +1725,15 @@ class CmdProxy {
"an intermediate process between receiver and client(gui). Also "
"restarts client zmq streaming if enabled.");
INTEGER_COMMAND_SET_NOID_GET_ID(
rx_zmqhwm, getRxZmqHwm, setRxZmqHwm, StringTo<int>,
"[n_value]\n\tReceiver's zmq send high water mark. Default is the zmq "
"library's default (1000). This is a high number and can be set to 2 "
"for gui purposes. One must also set the client's receive high water "
"mark to similar value. Final effect is sum of them. Also restarts "
"receiver zmq streaming if enabled. Can set to -1 to set default "
"value.");
/* Eiger Specific */
TIME_COMMAND(subexptime, getSubExptime, setSubExptime,

View File

@ -643,7 +643,7 @@ Result<int> Detector::getNumberofUDPInterfaces(Positions pos) const {
}
void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
int previouslyClientStreaming = pimpl->getDataStreamingToClient();
bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
bool useReceiver = getUseReceiverFlag().squash(false);
bool previouslyReceiverStreaming = false;
if (useReceiver) {
@ -656,7 +656,7 @@ void Detector::setNumberofUDPInterfaces(int n, Positions pos) {
setRxZmqPort(startingPort, -1);
}
// redo the zmq sockets if enabled
if (previouslyClientStreaming != 0) {
if (previouslyClientStreaming) {
pimpl->setDataStreamingToClient(false);
pimpl->setDataStreamingToClient(true);
}
@ -1077,7 +1077,7 @@ Result<int> Detector::getClientZmqPort(Positions pos) const {
}
void Detector::setClientZmqPort(int port, int module_id) {
int previouslyClientStreaming = pimpl->getDataStreamingToClient();
bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
if (module_id == -1) {
std::vector<int> port_list = getPortNumbers(port);
for (int idet = 0; idet < size(); ++idet) {
@ -1087,7 +1087,7 @@ void Detector::setClientZmqPort(int port, int module_id) {
} else {
pimpl->Parallel(&Module::setClientStreamingPort, {module_id}, port);
}
if (previouslyClientStreaming != 0) {
if (previouslyClientStreaming) {
pimpl->setDataStreamingToClient(false);
pimpl->setDataStreamingToClient(true);
}
@ -1098,14 +1098,33 @@ Result<IpAddr> Detector::getClientZmqIp(Positions pos) const {
}
void Detector::setClientZmqIp(const IpAddr ip, Positions pos) {
int previouslyClientStreaming = pimpl->getDataStreamingToClient();
bool previouslyClientStreaming = pimpl->getDataStreamingToClient();
pimpl->Parallel(&Module::setClientStreamingIP, pos, ip);
if (previouslyClientStreaming != 0) {
if (previouslyClientStreaming) {
pimpl->setDataStreamingToClient(false);
pimpl->setDataStreamingToClient(true);
}
}
int Detector::getClientZmqHwm() const { return pimpl->getClientStreamingHwm(); }
void Detector::setClientZmqHwm(const int limit) {
pimpl->setClientStreamingHwm(limit);
}
Result<int> Detector::getRxZmqHwm(Positions pos) const {
return pimpl->Parallel(&Module::getReceiverStreamingHwm, pos);
}
void Detector::setRxZmqHwm(const int limit) {
bool previouslyReceiverStreaming = getRxZmqDataStream().squash(false);
pimpl->Parallel(&Module::setReceiverStreamingHwm, {}, limit);
if (previouslyReceiverStreaming) {
setRxZmqDataStream(false, {});
setRxZmqDataStream(true, {});
}
}
// Eiger Specific
Result<ns> Detector::getSubExptime(Positions pos) const {

View File

@ -158,6 +158,8 @@ void DetectorImpl::initializeDetectorStructure() {
multi_shm()->acquiringFlag = false;
multi_shm()->initialChecks = true;
multi_shm()->gapPixels = false;
// zmqlib default
multi_shm()->zmqHwm = -1;
}
void DetectorImpl::initializeMembers(bool verify) {
@ -377,16 +379,17 @@ void DetectorImpl::setGapPixelsinCallback(const bool enable) {
multi_shm()->gapPixels = enable;
}
int DetectorImpl::createReceivingDataSockets(const bool destroy) {
if (destroy) {
LOG(logINFO) << "Going to destroy data sockets";
// close socket
zmqSocket.clear();
int DetectorImpl::destroyReceivingDataSockets() {
LOG(logINFO) << "Going to destroy data sockets";
// close socket
zmqSocket.clear();
client_downstream = false;
LOG(logINFO) << "Destroyed Receiving Data Socket(s)";
return OK;
}
client_downstream = false;
LOG(logINFO) << "Destroyed Receiving Data Socket(s)";
return OK;
}
int DetectorImpl::createReceivingDataSockets() {
if (client_downstream) {
return OK;
}
@ -417,11 +420,21 @@ int DetectorImpl::createReceivingDataSockets(const bool destroy) {
.str()
.c_str(),
portnum));
// set high water mark
int hwm = multi_shm()->zmqHwm;
if (hwm >= 0) {
zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm);
if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) {
throw sls::ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(hwm));
}
}
LOG(logINFO) << "Zmq Client[" << iSocket << "] at "
<< zmqSocket.back()->GetZmqServerAddress();
<< zmqSocket.back()->GetZmqServerAddress() << "[hwm: "
<< zmqSocket.back()->GetReceiveHighWaterMark() << "]";
} catch (...) {
LOG(logERROR) << "Could not create Zmq socket on port " << portnum;
createReceivingDataSockets(true);
destroyReceivingDataSockets();
return FAIL;
}
}
@ -449,12 +462,12 @@ void DetectorImpl::readFrameFromReceiver() {
}
std::vector<bool> runningList(zmqSocket.size());
std::vector<bool> connectList(zmqSocket.size());
int numRunning = 0;
numZmqRunning = 0;
for (size_t i = 0; i < zmqSocket.size(); ++i) {
if (zmqSocket[i]->Connect() == 0) {
connectList[i] = true;
runningList[i] = true;
++numRunning;
++numZmqRunning;
} else {
// to remember the list it connected to, to disconnect later
connectList[i] = false;
@ -480,14 +493,14 @@ void DetectorImpl::readFrameFromReceiver() {
uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1,
flippedDataX = -1;
while (numRunning != 0) {
while (numZmqRunning != 0) {
// reset data
data = false;
if (multiframe != nullptr) {
memset(multiframe.get(), 0xFF, multisize);
}
completeImage = (numRunning == (int)zmqSocket.size());
completeImage = (numZmqRunning == (int)zmqSocket.size());
// get each frame
for (unsigned int isocket = 0; isocket < zmqSocket.size(); ++isocket) {
@ -505,7 +518,7 @@ void DetectorImpl::readFrameFromReceiver() {
// socket
runningList[isocket] = false;
completeImage = false;
--numRunning;
--numZmqRunning;
continue;
}
@ -967,7 +980,7 @@ bool DetectorImpl::getDataStreamingToClient() { return client_downstream; }
void DetectorImpl::setDataStreamingToClient(bool enable) {
// destroy data threads
if (!enable) {
createReceivingDataSockets(true);
destroyReceivingDataSockets();
// create data threads
} else {
if (createReceivingDataSockets() == FAIL) {
@ -976,6 +989,51 @@ void DetectorImpl::setDataStreamingToClient(bool enable) {
}
}
int DetectorImpl::getClientStreamingHwm() const {
// disabled
if (!client_downstream) {
return multi_shm()->zmqHwm;
}
// enabled
sls::Result<int> result;
result.reserve(zmqSocket.size());
for (auto &it : zmqSocket) {
result.push_back(it->GetReceiveHighWaterMark());
}
int res = result.tsquash("Inconsistent zmq receive hwm values");
return res;
}
void DetectorImpl::setClientStreamingHwm(const int limit) {
if (limit < -1) {
throw sls::RuntimeError(
"Cannot set hwm to less than -1 (-1 is lib default).");
}
// update shm
multi_shm()->zmqHwm = limit;
// streaming enabled
if (client_downstream) {
// custom limit, set it directly
if (limit >= 0) {
for (auto &it : zmqSocket) {
it->SetReceiveHighWaterMark(limit);
if (it->GetReceiveHighWaterMark() != limit) {
multi_shm()->zmqHwm = -1;
throw sls::ZmqSocketError("Could not set zmq rcv hwm to " +
std::to_string(limit));
}
}
LOG(logINFO) << "Setting Client Zmq socket rcv hwm to " << limit;
}
// default, disable and enable to get default
else {
setDataStreamingToClient(false);
setDataStreamingToClient(true);
}
}
}
void DetectorImpl::registerAcquisitionFinishedCallback(void (*func)(double, int,
void *),
void *pArg) {
@ -1042,6 +1100,12 @@ int DetectorImpl::acquire() {
if (dataReady == nullptr) {
setJoinThreadFlag(true);
}
if (receiver) {
while (numZmqRunning != 0) {
Parallel(&Module::restreamStopFromReceiver, {});
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
dataProcessingThread.join();
if (acquisition_finished != nullptr) {

View File

@ -16,7 +16,7 @@ class detectorData;
#include <vector>
#define MULTI_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x200319
#define MULTI_SHMVERSION 0x201007
#define SHORT_STRING_LENGTH 50
#include <future>
@ -62,6 +62,8 @@ struct sharedMultiSlsDetector {
bool acquiringFlag;
bool initialChecks;
bool gapPixels;
/** high water mark of listening tcp port (only data) */
int zmqHwm;
};
class DetectorImpl : public virtual slsDetectorDefs {
@ -240,6 +242,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
bool getDataStreamingToClient();
void setDataStreamingToClient(bool enable);
int getClientStreamingHwm() const;
void setClientStreamingHwm(const int limit);
/**
* register callback for accessing acquisition final data
@ -324,12 +328,8 @@ class DetectorImpl : public virtual slsDetectorDefs {
void updateDetectorSize();
/**
* Create Receiving Data Sockets
* @param destroy is true to destroy all the sockets
* @returns OK or FAIL
*/
int createReceivingDataSockets(const bool destroy = false);
int destroyReceivingDataSockets();
int createReceivingDataSockets();
/**
* Reads frames from receiver through a constant socket
@ -387,6 +387,9 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** ZMQ Socket - Receiver to Client */
std::vector<std::unique_ptr<ZmqSocket>> zmqSocket;
/** number of zmq sockets running currently */
volatile int numZmqRunning{0};
/** mutex to synchronize main and data processing threads */
mutable std::mutex mp;

View File

@ -431,6 +431,10 @@ void Module::stopAcquisition() {
}
}
void Module::restreamStopFromReceiver() {
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER);
}
void Module::startAndReadAll() {
shm()->stoppedFlag = false;
sendToDetector(F_START_AND_READ_ALL);
@ -1041,6 +1045,14 @@ void Module::setClientStreamingIP(const sls::IpAddr ip) {
shm()->zmqip = ip;
}
int Module::getReceiverStreamingHwm() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_HWM);
}
void Module::setReceiverStreamingHwm(const int limit) {
sendToReceiver(F_SET_RECEIVER_STREAMING_HWM, limit, nullptr);
}
// Eiger Specific
int64_t Module::getSubExptime() const {
@ -2781,10 +2793,6 @@ void Module::checkReceiverVersionCompatibility() {
sendToReceiver(F_RECEIVER_CHECK_VERSION, int64_t(APIRECEIVER), nullptr);
}
void Module::restreamStopFromReceiver() {
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER);
}
int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
constexpr TLogLevel level = logDEBUG1;
LOG(level) << "Sending Module";

View File

@ -161,6 +161,7 @@ class Module : public virtual slsDetectorDefs {
void stopReceiver();
void startAcquisition();
void stopAcquisition();
void restreamStopFromReceiver();
void startAndReadAll();
runStatus getRunStatus() const;
runStatus getReceiverStatus() const;
@ -290,6 +291,8 @@ class Module : public virtual slsDetectorDefs {
void setClientStreamingPort(int port);
sls::IpAddr getClientStreamingIP() const;
void setClientStreamingIP(const sls::IpAddr ip);
int getReceiverStreamingHwm() const;
void setReceiverStreamingHwm(const int limit);
/**************************************************
* *
@ -665,7 +668,6 @@ class Module : public virtual slsDetectorDefs {
void checkDetectorVersionCompatibility();
void checkReceiverVersionCompatibility();
void restreamStopFromReceiver();
void setModule(sls_detector_module &module, bool trimbits = true);
int sendModule(sls_detector_module *myMod, sls::ClientSocket &client);
void updateReceiverStreamingIP();