Proccessing long pull requests [i'm crying]
-
We need to realize web-server using c++(qt).
Our server get requests from client and push all descriptors into Queue. We proccess this Queue in four threads.
But we use two types of requests, one of them long pull requsts, other fast requests.
When we get four long pull requests in the threads, server is blocking for other fast requests.How we can solve this problem?
-
//webserver1.cpp
@
#include "webserver1.h"
#include "requesthandler1.h"
#include <QCoreApplication>
#include <QtConcurrentRun>
#include <QTime>WebServer1::WebServer1(QObject *parent) :
QTcpServer(parent)
{
QtConcurrent::run(this, &WebServer1::processQueue);
}void WebServer1::incomingConnection(int socketDescriptor)
{
sockets.append(socketDescriptor);
}void WebServer1::processQueue()
{
while (true) {
if (!sockets.isEmpty() && RequestHandler1::semaphore->tryAcquire()) {
RequestHandler1 *handler = new RequestHandler1(sockets.takeFirst());
connect(handler, SIGNAL(finished()), handler, SLOT(deleteLater()));
handler->start();
} else {
usleep(1000);
}
}
}
@@
#include "requesthandler1.h"
#include "httpserver.h"
#include <QtNetwork>
#include <QtGlobal>QSemaphore *RequestHandler1::semaphore = new QSemaphore (4);
QSemaphore *RequestHandler1::semaphoreLongPull = new QSemaphore (2);RequestHandler1::RequestHandler1(int socketDescriptor, QObject *parent) :
QThread(parent), socketDescriptor(socketDescriptor)
{
}void RequestHandler1::run()
{
QTcpSocket *tcpSocket = new QTcpSocket;
if (!tcpSocket->setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket->error());
return;
}
if (!tcpSocket->bytesAvailable()) {
tcpSocket->waitForReadyRead();
}
QString header = "";
bool flag = false;
int i = 0;
while (tcpSocket->canReadLine()) {
i++;
header += tcpSocket->readLine();
if (header.split(" ", QString::SkipEmptyParts).at(1) == "/test/" && i==1)
{
int descriptor = socketDescriptor;
test(header.split(" ", QString::SkipEmptyParts).at(1), descriptor);
flag = true;
}
}
if (!flag) {
qDebug()<<"not looong";
tcpSocket->write(QString("HTTP/1->0 200 Ok\r\n"
"Content-Type: text/html; charset="utf-8"\r\n"
"\r\n"
"<h1>" + QString::fromUtf8("Привет, мокапщик") + "</h1>\n"
+ QDateTime::currentDateTime().toString() + "\n").toUtf8());
if (tcpSocket->bytesToWrite()) {
tcpSocket->waitForBytesWritten();
}
}
tcpSocket->close();
delete tcpSocket;
semaphore->release();
}void RequestHandler1::test (QString link, int descriptor){
qDebug() <<"it was so loooong";
QTcpSocket * tcpSocket = new QTcpSocket;
tcpSocket->setSocketDescriptor(descriptor);
tcpSocket->write("get mockup", strlen("get mockup"));
tcpSocket->waitForBytesWritten();
usleep(1000000);
qDebug() <<"doooone";
}
@ -
Then i recomend you:
"video":http://voidrealms.com/viewtutorial.aspx?id=39
"source code":http://voidrealms.com/downloadtutorial.aspx?id=39
this solution tested and it works fine. -
[quote author="Andre" date="1361204431"]Is there a reason you limit yourself to 4 threads? I think I/O is going to be the blocking factor, not processing...
Would it be feasible to reserve one thread for your short requests?[/quote]
Yep, we test it with ab (-c 1000) and look that 4 help us to keep PIP's count and productivity on level (of, course it'll be customize in future).
We know is this long poll or short request only when we read headers, for this operation we need to initialize socket with request descriptor, but when we close socket connection lost (or we must to process this request).
Could we can reopen socket with the same descriptor, or how we can save number of PIPs?