implement flow frame handling support
Fleshed out the previously unimplemented flow control frame handling, added an auto test for it. Also refactored out the stateChanged ChannelPrivate method, if we need proper state support in the future it will be added with a better implementation
This commit is contained in:
parent
fb93bd8096
commit
1ebe3bd667
|
|
@ -34,25 +34,6 @@ void ChannelPrivate::init(int channel, Client *c)
|
||||||
nextChannelNumber = qMax(channelNumber, (nextChannelNumber + 1));
|
nextChannelNumber = qMax(channelNumber, (nextChannelNumber + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelPrivate::stateChanged(State state)
|
|
||||||
{
|
|
||||||
Q_Q(Channel);
|
|
||||||
switch(ChannelPrivate::State(state)) {
|
|
||||||
case ChannelPrivate::csOpened:
|
|
||||||
Q_EMIT q->opened();
|
|
||||||
break;
|
|
||||||
case ChannelPrivate::csClosed:
|
|
||||||
Q_EMIT q->closed();
|
|
||||||
break;
|
|
||||||
case ChannelPrivate::csIdle:
|
|
||||||
Q_EMIT q->flowChanged(false);
|
|
||||||
break;
|
|
||||||
case ChannelPrivate::csRunning:
|
|
||||||
Q_EMIT q->flowChanged(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ChannelPrivate::_q_method(const Frame::Method &frame)
|
bool ChannelPrivate::_q_method(const Frame::Method &frame)
|
||||||
{
|
{
|
||||||
Q_ASSERT(frame.channel() == channelNumber);
|
Q_ASSERT(frame.channel() == channelNumber);
|
||||||
|
|
@ -129,10 +110,21 @@ void ChannelPrivate::open()
|
||||||
sendFrame(frame);
|
sendFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelPrivate::flow()
|
void ChannelPrivate::flow(bool active)
|
||||||
{
|
{
|
||||||
|
QByteArray arguments;
|
||||||
|
QDataStream stream(&arguments, QIODevice::WriteOnly);
|
||||||
|
Frame::writeAmqpField(stream, ShortShortUint, (active ? 1 : 0));
|
||||||
|
|
||||||
|
Frame::Method frame(Frame::fcChannel, miFlow);
|
||||||
|
frame.setChannel(channelNumber);
|
||||||
|
frame.setArguments(arguments);
|
||||||
|
sendFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: not implemented until I can figure out a good way to force the server
|
||||||
|
// to pause the channel in a test. It seems like RabbitMQ just doesn't
|
||||||
|
// care about flow control, preferring rather to use basic.qos
|
||||||
void ChannelPrivate::flow(const Frame::Method &frame)
|
void ChannelPrivate::flow(const Frame::Method &frame)
|
||||||
{
|
{
|
||||||
Q_UNUSED(frame);
|
Q_UNUSED(frame);
|
||||||
|
|
@ -146,8 +138,14 @@ void ChannelPrivate::flowOk()
|
||||||
|
|
||||||
void ChannelPrivate::flowOk(const Frame::Method &frame)
|
void ChannelPrivate::flowOk(const Frame::Method &frame)
|
||||||
{
|
{
|
||||||
Q_UNUSED(frame);
|
Q_Q(Channel);
|
||||||
qAmqpDebug() << Q_FUNC_INFO;
|
QByteArray data = frame.arguments();
|
||||||
|
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||||
|
bool active = Frame::readAmqpField(stream, Boolean).toBool();
|
||||||
|
if (active)
|
||||||
|
Q_EMIT q->resumed();
|
||||||
|
else
|
||||||
|
Q_EMIT q->paused();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelPrivate::close(int code, const QString &text, int classId, int methodId)
|
void ChannelPrivate::close(int code, const QString &text, int classId, int methodId)
|
||||||
|
|
@ -176,7 +174,6 @@ void ChannelPrivate::close(const Frame::Method &frame)
|
||||||
{
|
{
|
||||||
Q_Q(Channel);
|
Q_Q(Channel);
|
||||||
qAmqpDebug(">> CLOSE");
|
qAmqpDebug(">> CLOSE");
|
||||||
stateChanged(csClosed);
|
|
||||||
QByteArray data = frame.arguments();
|
QByteArray data = frame.arguments();
|
||||||
QDataStream stream(&data, QIODevice::ReadOnly);
|
QDataStream stream(&data, QIODevice::ReadOnly);
|
||||||
qint16 code = 0, classId, methodId;
|
qint16 code = 0, classId, methodId;
|
||||||
|
|
@ -197,6 +194,7 @@ void ChannelPrivate::close(const Frame::Method &frame)
|
||||||
qAmqpDebug(">> text: %s", qPrintable(text));
|
qAmqpDebug(">> text: %s", qPrintable(text));
|
||||||
qAmqpDebug(">> class-id: %d", classId);
|
qAmqpDebug(">> class-id: %d", classId);
|
||||||
qAmqpDebug(">> method-id: %d", methodId);
|
qAmqpDebug(">> method-id: %d", methodId);
|
||||||
|
Q_EMIT q->closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelPrivate::closeOk()
|
void ChannelPrivate::closeOk()
|
||||||
|
|
@ -205,24 +203,20 @@ void ChannelPrivate::closeOk()
|
||||||
sendFrame(frame);
|
sendFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelPrivate::closeOk(const Frame::Method &frame)
|
void ChannelPrivate::closeOk(const Frame::Method &)
|
||||||
{
|
{
|
||||||
Q_UNUSED(frame)
|
|
||||||
Q_Q(Channel);
|
Q_Q(Channel);
|
||||||
|
Q_EMIT q->closed();
|
||||||
stateChanged(csClosed);
|
|
||||||
q->channelClosed();
|
q->channelClosed();
|
||||||
opened = false;
|
opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelPrivate::openOk(const Frame::Method &frame)
|
void ChannelPrivate::openOk(const Frame::Method &)
|
||||||
{
|
{
|
||||||
Q_UNUSED(frame)
|
|
||||||
Q_Q(Channel);
|
Q_Q(Channel);
|
||||||
|
|
||||||
qAmqpDebug(">> OpenOK");
|
qAmqpDebug(">> OpenOK");
|
||||||
opened = true;
|
opened = true;
|
||||||
stateChanged(csOpened);
|
Q_EMIT q->opened();
|
||||||
q->channelOpened();
|
q->channelOpened();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,4 +340,10 @@ QString Channel::errorString() const
|
||||||
return d->errorString;
|
return d->errorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Channel::resume()
|
||||||
|
{
|
||||||
|
Q_D(Channel);
|
||||||
|
d->flow(true);
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_amqp_channel.cpp"
|
#include "moc_amqp_channel.cpp"
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,13 @@ public:
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void closeChannel();
|
void closeChannel();
|
||||||
void reopen();
|
void reopen();
|
||||||
|
void resume();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void opened();
|
void opened();
|
||||||
void closed();
|
void closed();
|
||||||
void flowChanged(bool enabled);
|
void resumed();
|
||||||
|
void paused();
|
||||||
void error(QAMQP::Error error);
|
void error(QAMQP::Error error);
|
||||||
void qosDefined();
|
void qosDefined();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,6 @@ public:
|
||||||
METHOD_ID_ENUM(miClose, 40)
|
METHOD_ID_ENUM(miClose, 40)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum State {
|
|
||||||
csOpened,
|
|
||||||
csClosed,
|
|
||||||
csIdle,
|
|
||||||
csRunning
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BasicMethod {
|
enum BasicMethod {
|
||||||
METHOD_ID_ENUM(bmQos, 10),
|
METHOD_ID_ENUM(bmQos, 10),
|
||||||
METHOD_ID_ENUM(bmConsume, 20),
|
METHOD_ID_ENUM(bmConsume, 20),
|
||||||
|
|
@ -47,12 +40,10 @@ public:
|
||||||
virtual ~ChannelPrivate();
|
virtual ~ChannelPrivate();
|
||||||
|
|
||||||
void init(int channel, Client *client);
|
void init(int channel, Client *client);
|
||||||
void stateChanged(State state);
|
|
||||||
|
|
||||||
void sendFrame(const Frame::Base &frame);
|
void sendFrame(const Frame::Base &frame);
|
||||||
|
|
||||||
void open();
|
void open();
|
||||||
void flow();
|
void flow(bool active);
|
||||||
void flowOk();
|
void flowOk();
|
||||||
void close(int code, const QString &text, int classId, int methodId);
|
void close(int code, const QString &text, int classId, int methodId);
|
||||||
void closeOk();
|
void closeOk();
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ private Q_SLOTS:
|
||||||
void tableFieldDataTypes();
|
void tableFieldDataTypes();
|
||||||
void messageProperties();
|
void messageProperties();
|
||||||
void closeChannel();
|
void closeChannel();
|
||||||
|
void resumeChannel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void declareQueueAndVerifyConsuming(Queue *queue);
|
void declareQueueAndVerifyConsuming(Queue *queue);
|
||||||
|
|
@ -675,5 +676,15 @@ void tst_QAMQPQueue::closeChannel()
|
||||||
QVERIFY(waitForSignal(queue, SIGNAL(closed())));
|
QVERIFY(waitForSignal(queue, SIGNAL(closed())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QAMQPQueue::resumeChannel()
|
||||||
|
{
|
||||||
|
Queue *queue = client->createQueue("test-resume");
|
||||||
|
QVERIFY(waitForSignal(queue, SIGNAL(opened())));
|
||||||
|
declareQueueAndVerifyConsuming(queue);
|
||||||
|
|
||||||
|
queue->resume();
|
||||||
|
QVERIFY(waitForSignal(queue, SIGNAL(resumed())));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QAMQPQueue)
|
QTEST_MAIN(tst_QAMQPQueue)
|
||||||
#include "tst_qamqpqueue.moc"
|
#include "tst_qamqpqueue.moc"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue