mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-22 09:37:59 +02:00
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:
@ -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});
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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();
|
||||
|
Reference in New Issue
Block a user