Timer with Lambda function
-
I am sending JSON messages between processes and I want start a timer when the message is sent, if no acknowledge is received then the timer will timeout and the same message will be written again, at least that's the intention.
I have a structure:
typedef struct { QJsonObject objMsg; QTimer* pTimer; } tAckMsgTracking; typedef std::map<qulonglong, tAckMsgTracking*> mmpAck;
The map is keyed by a message transaction ID which is uniquely generated when the message is sent. The problem I'm having is that the lambda slot does not get called:
tAckMsgTracking* pAckMsgTrkr = new tAckMsgTracking; pAckMsgTrkr->objMsg = objJSON; pAckMsgTrkr->pTimer = new QTimer(this); QObject::connect(pAckMsgTrkr->pTimer, &QTimer::timeout, [this, pAckMsgTrkr]() { //Re-send message emit write(pAckMsgTrkr->objMsg); }); //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Insert entry into the map clsMsgSender::msmpAcks.insert(std::make_pair(clsMsgSender::msulnglngMsgID, pAckMsgTrkr)); //Start the timer that will resend message if ack. not received pAckMsgTrkr->pTimer->start(clsMsgSender::mscuint16AckTimeout);
The value of 'mscuint16AckTimeout' is 5000 (milliseconds). I've also tried:
pAckMsgTrkr->pTimer->start(std::chrono::milliseconds(clsMsgSender::mscuint16AckTimeout));
I have a break point in the lambda slot, it doesn't get hit.
-
I am sending JSON messages between processes and I want start a timer when the message is sent, if no acknowledge is received then the timer will timeout and the same message will be written again, at least that's the intention.
I have a structure:
typedef struct { QJsonObject objMsg; QTimer* pTimer; } tAckMsgTracking; typedef std::map<qulonglong, tAckMsgTracking*> mmpAck;
The map is keyed by a message transaction ID which is uniquely generated when the message is sent. The problem I'm having is that the lambda slot does not get called:
tAckMsgTracking* pAckMsgTrkr = new tAckMsgTracking; pAckMsgTrkr->objMsg = objJSON; pAckMsgTrkr->pTimer = new QTimer(this); QObject::connect(pAckMsgTrkr->pTimer, &QTimer::timeout, [this, pAckMsgTrkr]() { //Re-send message emit write(pAckMsgTrkr->objMsg); }); //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Insert entry into the map clsMsgSender::msmpAcks.insert(std::make_pair(clsMsgSender::msulnglngMsgID, pAckMsgTrkr)); //Start the timer that will resend message if ack. not received pAckMsgTrkr->pTimer->start(clsMsgSender::mscuint16AckTimeout);
The value of 'mscuint16AckTimeout' is 5000 (milliseconds). I've also tried:
pAckMsgTrkr->pTimer->start(std::chrono::milliseconds(clsMsgSender::mscuint16AckTimeout));
I have a break point in the lambda slot, it doesn't get hit.
@SPlatten said in Timer with Lambda function:
pAckMsgTrkr->pTimer = new QTimer(this);
Not related, but: why do you allocate timer on the heap?
So, you don't get acknowledge and timeout slot is not called?
-
@SPlatten said in Timer with Lambda function:
pAckMsgTrkr->pTimer = new QTimer(this);
Not related, but: why do you allocate timer on the heap?
So, you don't get acknowledge and timeout slot is not called?
-
@jsulm, I create a timeout for each message that is sent as the queue doesn't wait one message to be sent successfully, before it sends another. So the timeout is for each message sent, the same queue can send to different hosts.
-
@jsulm , what else would you suggest? I don't want to static allocate and I cannot use the stack.
@SPlatten said in Timer with Lambda function:
what else would you suggest?
Make it member instead of a pointer? What's the point to have it as pointer allocate memory on the heap (which is slower) and then care to not to forget to delete it?
-
I am sending JSON messages between processes and I want start a timer when the message is sent, if no acknowledge is received then the timer will timeout and the same message will be written again, at least that's the intention.
I have a structure:
typedef struct { QJsonObject objMsg; QTimer* pTimer; } tAckMsgTracking; typedef std::map<qulonglong, tAckMsgTracking*> mmpAck;
The map is keyed by a message transaction ID which is uniquely generated when the message is sent. The problem I'm having is that the lambda slot does not get called:
tAckMsgTracking* pAckMsgTrkr = new tAckMsgTracking; pAckMsgTrkr->objMsg = objJSON; pAckMsgTrkr->pTimer = new QTimer(this); QObject::connect(pAckMsgTrkr->pTimer, &QTimer::timeout, [this, pAckMsgTrkr]() { //Re-send message emit write(pAckMsgTrkr->objMsg); }); //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Insert entry into the map clsMsgSender::msmpAcks.insert(std::make_pair(clsMsgSender::msulnglngMsgID, pAckMsgTrkr)); //Start the timer that will resend message if ack. not received pAckMsgTrkr->pTimer->start(clsMsgSender::mscuint16AckTimeout);
The value of 'mscuint16AckTimeout' is 5000 (milliseconds). I've also tried:
pAckMsgTrkr->pTimer->start(std::chrono::milliseconds(clsMsgSender::mscuint16AckTimeout));
I have a break point in the lambda slot, it doesn't get hit.
-
I am sending JSON messages between processes and I want start a timer when the message is sent, if no acknowledge is received then the timer will timeout and the same message will be written again, at least that's the intention.
I have a structure:
typedef struct { QJsonObject objMsg; QTimer* pTimer; } tAckMsgTracking; typedef std::map<qulonglong, tAckMsgTracking*> mmpAck;
The map is keyed by a message transaction ID which is uniquely generated when the message is sent. The problem I'm having is that the lambda slot does not get called:
tAckMsgTracking* pAckMsgTrkr = new tAckMsgTracking; pAckMsgTrkr->objMsg = objJSON; pAckMsgTrkr->pTimer = new QTimer(this); QObject::connect(pAckMsgTrkr->pTimer, &QTimer::timeout, [this, pAckMsgTrkr]() { //Re-send message emit write(pAckMsgTrkr->objMsg); }); //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Insert entry into the map clsMsgSender::msmpAcks.insert(std::make_pair(clsMsgSender::msulnglngMsgID, pAckMsgTrkr)); //Start the timer that will resend message if ack. not received pAckMsgTrkr->pTimer->start(clsMsgSender::mscuint16AckTimeout);
The value of 'mscuint16AckTimeout' is 5000 (milliseconds). I've also tried:
pAckMsgTrkr->pTimer->start(std::chrono::milliseconds(clsMsgSender::mscuint16AckTimeout));
I have a break point in the lambda slot, it doesn't get hit.
@SPlatten said in Timer with Lambda function:
I have a break point in the lambda slot, it doesn't get hit.
There are only 2 things why slot is not called:
- the thread in which the
QTimer
in living does not have a running event loop - the event loop is locked (by a
QThread::sleep()
or a forever loop)
- the thread in which the
-
I've re-written the code instead of a structure:
class clsMsgTrkr : QTimer { private: static const quint16 mscuint16AckTimeout = 5000; static mmpAck msmpAcks; QJsonObject mobjMsg; clsMsgSender* mpMsgSndr; public: clsMsgTrkr(clsMsgSender* pMsgSndr, const QJsonObject& crobjJSON) { setInterval(mscuint16AckTimeout); mobjMsg = crobjJSON; mpMsgSndr = pMsgSndr; //Add tracker to list clsMsgTrkr::msmpAcks.insert(std::make_pair(clsMsgSender::ulnglngGetMsgID(), this)); QObject::connect(this, &QTimer::timeout, [this]() { qdbg() << "TIMEOUT!"; //Re-send message emit mpMsgSndr->write(mobjMsg); }); start(); } };
I can see in the debugger the constructor is getting called and processed the timer is started but I don't get anything in the slot.
-
I've re-written the code instead of a structure:
class clsMsgTrkr : QTimer { private: static const quint16 mscuint16AckTimeout = 5000; static mmpAck msmpAcks; QJsonObject mobjMsg; clsMsgSender* mpMsgSndr; public: clsMsgTrkr(clsMsgSender* pMsgSndr, const QJsonObject& crobjJSON) { setInterval(mscuint16AckTimeout); mobjMsg = crobjJSON; mpMsgSndr = pMsgSndr; //Add tracker to list clsMsgTrkr::msmpAcks.insert(std::make_pair(clsMsgSender::ulnglngGetMsgID(), this)); QObject::connect(this, &QTimer::timeout, [this]() { qdbg() << "TIMEOUT!"; //Re-send message emit mpMsgSndr->write(mobjMsg); }); start(); } };
I can see in the debugger the constructor is getting called and processed the timer is started but I don't get anything in the slot.
-
I've re-written the code instead of a structure:
class clsMsgTrkr : QTimer { private: static const quint16 mscuint16AckTimeout = 5000; static mmpAck msmpAcks; QJsonObject mobjMsg; clsMsgSender* mpMsgSndr; public: clsMsgTrkr(clsMsgSender* pMsgSndr, const QJsonObject& crobjJSON) { setInterval(mscuint16AckTimeout); mobjMsg = crobjJSON; mpMsgSndr = pMsgSndr; //Add tracker to list clsMsgTrkr::msmpAcks.insert(std::make_pair(clsMsgSender::ulnglngGetMsgID(), this)); QObject::connect(this, &QTimer::timeout, [this]() { qdbg() << "TIMEOUT!"; //Re-send message emit mpMsgSndr->write(mobjMsg); }); start(); } };
I can see in the debugger the constructor is getting called and processed the timer is started but I don't get anything in the slot.
-
I added a call after call:
start(); qdbg() << this->isActive();
qdbg is just a macro I use which is:
#define qdbg() qDebug().noquote().nospace()
In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.
-
I added a call after call:
start(); qdbg() << this->isActive();
qdbg is just a macro I use which is:
#define qdbg() qDebug().noquote().nospace()
In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.
@SPlatten said in Timer with Lambda function:
In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.
Do you have a forever loop in your code or do you use
QThread::sleep()
?
Are you sureQEventLoop
of the used thread is working? -
@SPlatten said in Timer with Lambda function:
In the Application Output I see true so the timer is active, but doesn't timeout. Also, I just set the timer interval to 0, still no change, no timeout signal occurs.
Do you have a forever loop in your code or do you use
QThread::sleep()
?
Are you sureQEventLoop
of the used thread is working?@KroMignon, the message transmission is in a thread and there very short sleep in the thread loop:
void clsMsgSender::run() { QJsonObject objJSON; while( blnAnythingToDo(objJSON) == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); //Look for a module name in the message QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType); if ( itrFound != objJSON.end() ) { const QJsonValueRef crobjMsgType = itrFound.value(); QString strMsgType(crobjMsgType.toString()); if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) { //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Create entry to monitor status of this message new clsMsgTrkr(this, objJSON); } } //Writes message to socket emit write(objJSON); } emit queueEmpty(); }
-
@KroMignon, the message transmission is in a thread and there very short sleep in the thread loop:
void clsMsgSender::run() { QJsonObject objJSON; while( blnAnythingToDo(objJSON) == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); //Look for a module name in the message QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType); if ( itrFound != objJSON.end() ) { const QJsonValueRef crobjMsgType = itrFound.value(); QString strMsgType(crobjMsgType.toString()); if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) { //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Create entry to monitor status of this message new clsMsgTrkr(this, objJSON); } } //Writes message to socket emit write(objJSON); } emit queueEmpty(); }
-
@KroMignon, the message transmission is in a thread and there very short sleep in the thread loop:
void clsMsgSender::run() { QJsonObject objJSON; while( blnAnythingToDo(objJSON) == true ) { //Sleep to allow a small cap between transmission QThread::usleep(100); //Look for a module name in the message QJsonObject::iterator itrFound = objJSON.find(clsJSON::mscszMsgType); if ( itrFound != objJSON.end() ) { const QJsonValueRef crobjMsgType = itrFound.value(); QString strMsgType(crobjMsgType.toString()); if ( strMsgType.compare(clsJSON::mscszAck) != 0 ) { //Insert a unique message ID into the message objJSON.insert(clsJSON::mscszMsgID, QString::number(++clsMsgSender::msulnglngMsgID)); //Create entry to monitor status of this message new clsMsgTrkr(this, objJSON); } } //Writes message to socket emit write(objJSON); } emit queueEmpty(); }
@SPlatten I've told you many times to read basic Qt documentation.
this cannot work!!!
First, I suppose clsMsgSender is subclassing
QThread
. And you have create your ownrun()
implementation. So there is no running QEventLoop. This means, all QObject which are running in this thread can NOT receive/emit signals.Second, you have a forever loop, so even if there where a running
QEventLoop
, it will not be called! -
@SPlatten I've told you many times to read basic Qt documentation.
this cannot work!!!
First, I suppose clsMsgSender is subclassing
QThread
. And you have create your ownrun()
implementation. So there is no running QEventLoop. This means, all QObject which are running in this thread can NOT receive/emit signals.Second, you have a forever loop, so even if there where a running
QEventLoop
, it will not be called!@KroMignon , I'm impatient, I know there is benefit from reading the documentation, I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation.
-
@KroMignon , I'm impatient, I know there is benefit from reading the documentation, I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation.
@SPlatten said in Timer with Lambda function:
I'm impatient,
Perhaps you are impatient, but in fact you are losing days doing nonsense code which not working.
If that is the best way to work, I am pretty sure NO.Reading this document would take you 1 or 2 hours, how many hours have you spend to create those non working code?
-
@KroMignon , I'm impatient, I know there is benefit from reading the documentation, I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation.
@SPlatten said in Timer with Lambda function:
I just don't want to stop what I'm doing to spend what would seem a long time to digest the documentation
So, instead you waste your time here?
I really don't get the logic...