Ejemplo n.º 1
0
void CommandService::_process_respond(Command* rpc_res) {
    const int64_t who =static_cast<int64_t>(rpc_res->getWho());
    const int64_t rpc_id =static_cast<int64_t>(rpc_res->getSn());
    bool done =true;
    do {
        RpcInfo* rpc =_get_rpc(rpc_id);
        if(rpc == 0) {
            WARN("service %s(%lld) who %lld rpc %lld respond, not exist", name(), (long long)m_id, (long long)who, (long long)rpc_id);
            break;
        }
        if(Command* cmd=rpc->getCommand()) {
            // check & prepare command
            Array* queue =static_cast< Array* >(m_queue_tb->get(who));
            if(queue == 0) {
                WARN("service %s(%lld) who %lld rpc %lld respond, command not exist", name(), (long long)m_id, (long long)who, (long long)rpc_id);
                break;
            }
            Command* front =static_cast< Command* >(queue->front());
            if(!front) {
                WARN("service %s(%lld) who %lld rpc %lld respond, command not exist", name(), (long long)m_id, (long long)who, (long long)rpc_id);
                break;
            }
            if(front != cmd) {
                WARN("service %s(%lld) who %lld rpc %lld respond, command mismatch", name(), (long long)m_id, (long long)who, (long long)rpc_id);
                break;
            }

            // call rpc
            m_processing_command =front;
            const int64_t result =rpc->invoke(rpc_res);
            m_processing_command =0;

            // done
            if(rpc->isDone() == false) {
                done =false;
            }

            // process result
            const int64_t cmd_id =front->getCommand();
            if(result == Command::STATE_COMPLETE) {
                front->setState(Command::STATE_COMPLETE);
                queue->pop_front();
                INFO("service %s(%lld) who %lld rpc %lld respond, command %lld complete", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)cmd_id);
            }
            else if(result > 0) {
                front->setState(Command::STATE_PROCESSING);
                INFO("service %s(%lld) who %lld rpc %lld respond, command %lld processing", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)cmd_id);
            }
            else {
                front->setState(Command::STATE_ERROR);
                queue->pop_front();
                ERROR("service %s(%lld) who %lld rpc %lld respond, command %lld error %lld", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)cmd_id, (long long)result);
            }

            // post process
            if(cmd_id==LOGOUT_REQUEST && queue->empty()) {
                m_queue_tb->remove(who);
            }
            else if(queue->size()) {
                _process_request(who);
            }
        }
        else {
            const int64_t result =rpc->invoke(rpc_res);
            if(result == Command::STATE_COMPLETE) {
                INFO("service %s(%lld) who %lld rpc %lld respond, complete", name(), (long long)m_id, (long long)who, (long long)rpc_id);
            }
            else if(result > 0) {
                INFO("service %s(%lld) who %lld rpc %lld respond, processing", name(), (long long)m_id, (long long)who, (long long)rpc_id);
            }
            else {
                ERROR("service %s(%lld) who %lld rpc %lld respond, error %lld", name(), (long long)m_id, (long long)who, (long long)rpc_id, (long long)result);
            }
        }
    } while(0);
    // remove rpc info
    if(done) {
        m_rpc_tb->remove(rpc_id);
    }
}