Example #1
0
static void handleReply(redisAsyncContext *context, void *_reply, void *privdata) {
    REDIS_NOTUSED(privdata);
    redisReply *reply = (redisReply*)_reply;
    client c = (client)context->data;
    long long latency = (microseconds() - c->start) / 1000;

    if (reply == NULL && context->err) {
        fprintf(stderr,"Error: %s\n", context->errstr);
        exit(1);
    } else {
        assert(reply != NULL);
        if (reply->type == REDIS_REPLY_ERROR) {
            fprintf(stderr,"Error: %s\n", reply->str);
            exit(1);
        }
    }

    if (latency > MAX_LATENCY) latency = MAX_LATENCY;
    config.latency[latency]++;

    if (config.check) checkDataIntegrity(c,reply);
    freeReplyObject(reply);

    if (config.done || config.ctrlc) {
        redisAsyncDisconnect(c->context);
        return;
    }

    if (config.keepalive) {
        issueRequest(c);
    } else {
        /* createMissingClients will be called in the disconnection callback */
        redisAsyncDisconnect(c->context);
    }
}
void ServerCatchcopy::readyRead()
{
    QLocalSocket *socket=qobject_cast<QLocalSocket *>(QObject::sender());
    if(socket==NULL)
    {
        qWarning() << "Unlocated client socket!";
        return;
    }
    int index=0;
    while(index<clientList.size())
    {
        if(clientList.at(index).socket==socket)
        {
            while(socket->bytesAvailable()>0)
            {
                if(!clientList.at(index).haveData)
                {
                    if(socket->bytesAvailable()<(int)sizeof(int))//ignore because first int is cuted!
                    {
                        /*error_string="Bytes available is not sufficient to do a int";
                        emit error(error_string);
                        disconnectClient(ClientList.at(index).id);*/
                        return;
                    }
                    QDataStream in(socket);
                    in.setVersion(QDataStream::Qt_4_4);
                    in >> clientList[index].dataSize;
                    clientList[index].dataSize-=sizeof(int);
                    if(clientList.at(index).dataSize>64*1024*1024) // 64MB
                    {
                        error_string="Reply size is >64MB, seam corrupted";
                        emit communicationError(error_string);
                        disconnectClient(clientList.at(index).id);
                        return;
                    }
                    if(clientList.at(index).dataSize<(int)(sizeof(int) //orderId
                             + sizeof(uint32_t) //returnCode
                             + sizeof(uint32_t) //string list size
                                ))
                    {
                        error_string="Reply size is too small to have correct code";
                        emit communicationError(error_string);
                        disconnectClient(clientList.at(index).id);
                        return;
                    }
                    clientList[index].haveData=true;
                }
                if(clientList.at(index).dataSize<(clientList.at(index).data.size()+socket->bytesAvailable()))
                    clientList[index].data.append(socket->read(clientList.at(index).dataSize-clientList.at(index).data.size()));
                else
                    clientList[index].data.append(socket->readAll());
                if(clientList.at(index).dataSize==(uint32_t)clientList.at(index).data.size())
                {
                    if(!checkDataIntegrity(clientList.at(index).data))
                    {
                        emit communicationError("Data integrity wrong: "+QString(clientList.at(index).data.toHex()).toStdString());
                        clientList[index].data.clear();
                        clientList[index].haveData=false;
                        qWarning() << "Data integrity wrong";
                        return;
                    }
                    std::vector<std::string> returnList;
                    QStringList returnListQt;
                    uint32_t orderId;
                    QDataStream in(clientList.at(index).data);
                    in.setVersion(QDataStream::Qt_4_4);
                    in >> orderId;
                    in >> returnListQt;
                    {
                        int index=0;
                        while(index<returnListQt.size())
                        {
                            returnList.push_back(returnListQt.at(index).toStdString());
                            index++;
                        }
                    }
                    clientList[index].data.clear();
                    clientList[index].haveData=false;
                    if(clientList.at(index).queryNoReplied.contains(orderId))
                    {
                        emit communicationError("Duplicate query id");
                        qWarning() << "Duplicate query id";
                        return;
                    }
                    clientList[index].queryNoReplied << orderId;
                    if(!clientList.at(index).firstProtocolReplied && returnList.size()==2 && returnList.front()=="protocol")
                    {
                        clientList[index].firstProtocolReplied=true;
                        protocolSupported(clientList.at(index).id,orderId,(returnList.back()==CATCHCOPY_PROTOCOL_VERSION));
                    }
                    else
                        parseInput(clientList.at(index).id,orderId,returnList);
                }
            }
            if(clientList.at(index).haveData)
                clientList.at(index).detectTimeOut->start();
            else
                clientList.at(index).detectTimeOut->stop();
            return;
        }
        index++;
    }
    emit error("Unallocated client!");
    qWarning() << "Unallocated client!";
}