From: Shane Synan Date: Wed, 1 Jun 2016 23:00:38 +0000 (-0400) Subject: Add command queue prepend, prioritize PING/PONG X-Git-Tag: 0.12.5~100 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=106d151d994fb26fd4586c6adf60a165075961a9 Add command queue prepend, prioritize PING/PONG Add optional flag to putRawLine and putCmd to put any given lines or commands to the front of the queue (prepend instead of append). Enable queue prepend for sending PINGs and PONG replies. This fixes the issue where Quassel will ping-timeout when trying to send huge messages (e.g. 40 lines at once), or multiple commands. Unfortunately, some IRC servers don't behave properly so Quassel may still get disconnected. Hopefully other servers will get fixed soon. Add more documentation, of course. Document all the things! (cherry picked from commit 45a0d954542db252ceb62b61243ee5c2253383de) --- diff --git a/src/core/corebasichandler.cpp b/src/core/corebasichandler.cpp index fbfc76c2..416d8ecc 100644 --- a/src/core/corebasichandler.cpp +++ b/src/core/corebasichandler.cpp @@ -30,14 +30,14 @@ CoreBasicHandler::CoreBasicHandler(CoreNetwork *parent) connect(this, SIGNAL(displayMsg(Message::Type, BufferInfo::Type, const QString &, const QString &, const QString &, Message::Flags)), network(), SLOT(displayMsg(Message::Type, BufferInfo::Type, const QString &, const QString &, const QString &, Message::Flags))); - connect(this, SIGNAL(putCmd(QString, const QList &, const QByteArray &)), - network(), SLOT(putCmd(QString, const QList &, const QByteArray &))); + connect(this, SIGNAL(putCmd(QString, const QList &, const QByteArray &, const bool)), + network(), SLOT(putCmd(QString, const QList &, const QByteArray &, const bool))); - connect(this, SIGNAL(putCmd(QString, const QList> &, const QByteArray &)), - network(), SLOT(putCmd(QString, const QList> &, const QByteArray &))); + connect(this, SIGNAL(putCmd(QString, const QList> &, const QByteArray &, const bool)), + network(), SLOT(putCmd(QString, const QList> &, const QByteArray &, const bool))); - connect(this, SIGNAL(putRawLine(const QByteArray &)), - network(), SLOT(putRawLine(const QByteArray &))); + connect(this, SIGNAL(putRawLine(const QByteArray &, const bool)), + network(), SLOT(putRawLine(const QByteArray &, const bool))); } @@ -142,9 +142,9 @@ BufferInfo::Type CoreBasicHandler::typeByTarget(const QString &target) const } -void CoreBasicHandler::putCmd(const QString &cmd, const QByteArray ¶m, const QByteArray &prefix) +void CoreBasicHandler::putCmd(const QString &cmd, const QByteArray ¶m, const QByteArray &prefix, const bool prepend) { QList list; list << param; - emit putCmd(cmd, list, prefix); + emit putCmd(cmd, list, prefix, prepend); } diff --git a/src/core/corebasichandler.h b/src/core/corebasichandler.h index a4b5a7f1..4c41dded 100644 --- a/src/core/corebasichandler.h +++ b/src/core/corebasichandler.h @@ -54,12 +54,43 @@ public: signals: void displayMsg(Message::Type, BufferInfo::Type, const QString &target, const QString &text, const QString &sender = "", Message::Flags flags = Message::None); - void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); - void putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix = QByteArray()); - void putRawLine(const QByteArray &msg); + + /** + * Sends the raw (encoded) line, adding to the queue if needed, optionally with higher priority. + * + * @see CoreNetwork::putRawLine() + */ + void putRawLine(const QByteArray &msg, const bool prepend = false); + + /** + * Sends the command with encoded parameters, with optional prefix or high priority. + * + * @see CoreNetwork::putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray(), const bool prepend = false) + */ + void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray(), const bool prepend = false); + + /** + * Sends the command for each set of encoded parameters, with optional prefix or high priority. + * + * @see CoreNetwork::putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix = QByteArray(), const bool prepend = false) + */ + void putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix = QByteArray(), const bool prepend = false); protected: - void putCmd(const QString &cmd, const QByteArray ¶m, const QByteArray &prefix = QByteArray()); + /** + * Sends the command with one parameter, with optional prefix or high priority. + * + * @param[in] cmd Command to send, ignoring capitalization + * @param[in] param Parameter for the command, encoded within a QByteArray + * @param[in] prefix Optional command prefix + * @param[in] prepend + * @parmblock + * If true, the command is prepended into the start of the queue, otherwise, it's appended to + * the end. This should be used sparingly, for if either the core or the IRC server cannot + * maintain PING/PONG replies, the other side will close the connection. + * @endparmblock + */ + void putCmd(const QString &cmd, const QByteArray ¶m, const QByteArray &prefix = QByteArray(), const bool prepend = false); inline CoreNetwork *network() const { return _network; } inline CoreSession *coreSession() const { return _network->coreSession(); } diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index a6dc7855..cab2a447 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -253,16 +253,21 @@ void CoreNetwork::userInput(BufferInfo buf, QString msg) } -void CoreNetwork::putRawLine(QByteArray s) +void CoreNetwork::putRawLine(const QByteArray s, const bool prepend) { - if (_tokenBucket > 0) + if (_tokenBucket > 0) { writeToSocket(s); - else - _msgQueue.append(s); + } else { + if (prepend) { + _msgQueue.prepend(s); + } else { + _msgQueue.append(s); + } + } } -void CoreNetwork::putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix) +void CoreNetwork::putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix, const bool prepend) { QByteArray msg; @@ -279,16 +284,16 @@ void CoreNetwork::putCmd(const QString &cmd, const QList ¶ms, co msg += params[i]; } - putRawLine(msg); + putRawLine(msg, prepend); } -void CoreNetwork::putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix) +void CoreNetwork::putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix, const bool prependAll) { QListIterator> i(params); while (i.hasNext()) { QList msg = i.next(); - putCmd(cmd, msg, prefix); + putCmd(cmd, msg, prefix, prependAll); } } diff --git a/src/core/corenetwork.h b/src/core/corenetwork.h index 359d032e..e7e7836d 100644 --- a/src/core/corenetwork.h +++ b/src/core/corenetwork.h @@ -117,9 +117,53 @@ public slots: void disconnectFromIrc(bool requested = true, const QString &reason = QString(), bool withReconnect = false); void userInput(BufferInfo bufferInfo, QString msg); - void putRawLine(QByteArray input); - void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray()); - void putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix = QByteArray()); + + /** + * Sends the raw (encoded) line, adding to the queue if needed, optionally with higher priority. + * + * @param[in] input QByteArray of encoded characters + * @param[in] prepend + * @parmblock + * If true, the line is prepended into the start of the queue, otherwise, it's appended to the + * end. This should be used sparingly, for if either the core or the IRC server cannot maintain + * PING/PONG replies, the other side will close the connection. + * @endparmblock + */ + void putRawLine(const QByteArray input, const bool prepend = false); + + /** + * Sends the command with encoded parameters, with optional prefix or high priority. + * + * @param[in] cmd Command to send, ignoring capitalization + * @param[in] params Parameters for the command, encoded within a QByteArray + * @param[in] prefix Optional command prefix + * @param[in] prepend + * @parmblock + * If true, the command is prepended into the start of the queue, otherwise, it's appended to + * the end. This should be used sparingly, for if either the core or the IRC server cannot + * maintain PING/PONG replies, the other side will close the connection. + * @endparmblock + */ + void putCmd(const QString &cmd, const QList ¶ms, const QByteArray &prefix = QByteArray(), const bool prepend = false); + + /** + * Sends the command for each set of encoded parameters, with optional prefix or high priority. + * + * @param[in] cmd Command to send, ignoring capitalization + * @param[in] params + * @parmblock + * List of parameter lists for the command, encoded within a QByteArray. The command will be + * sent multiple times, once for each set of params stored within the outer list. + * @endparmblock + * @param[in] prefix Optional command prefix + * @param[in] prependAll + * @parmblock + * If true, ALL of the commands are prepended into the start of the queue, otherwise, they're + * appended to the end. This should be used sparingly, for if either the core or the IRC server + * cannot maintain PING/PONG replies, the other side will close the connection. + * @endparmblock + */ + void putCmd(const QString &cmd, const QList> ¶ms, const QByteArray &prefix = QByteArray(), const bool prependAll = false); void setChannelJoined(const QString &channel); void setChannelParted(const QString &channel); diff --git a/src/core/coresessioneventprocessor.cpp b/src/core/coresessioneventprocessor.cpp index 41e24039..ad598903 100644 --- a/src/core/coresessioneventprocessor.cpp +++ b/src/core/coresessioneventprocessor.cpp @@ -373,7 +373,8 @@ void CoreSessionEventProcessor::processIrcEventPing(IrcEvent *e) { QString param = e->params().count() ? e->params().first() : QString(); // FIXME use events - coreNetwork(e)->putRawLine("PONG " + coreNetwork(e)->serverEncode(param)); + // Take priority so this won't get stuck behind other queued messages. + coreNetwork(e)->putRawLine("PONG " + coreNetwork(e)->serverEncode(param), true); } diff --git a/src/core/coreuserinputhandler.cpp b/src/core/coreuserinputhandler.cpp index 73aac48a..8ba7639b 100644 --- a/src/core/coreuserinputhandler.cpp +++ b/src/core/coreuserinputhandler.cpp @@ -545,7 +545,8 @@ void CoreUserInputHandler::handlePing(const BufferInfo &bufferInfo, const QStrin if (param.isEmpty()) param = QTime::currentTime().toString("hh:mm:ss.zzz"); - putCmd("PING", serverEncode(param)); + // Take priority so this won't get stuck behind other queued messages. + putCmd("PING", serverEncode(param), QByteArray(), true); }