Пример #1
0
void CommandService::_process_timeout(const int64_t now) {
    /* clear timeout command */
    if(m_queue_tb->size()>0) {
        Int64Array* ls =0;
        HashIterator* it =static_cast< HashIterator* >(m_queue_tb->iterator());
        while(it->next()) {
            const int64_t who =static_cast< Int64* >(it->getKey())->getValue();
            Array* queue =static_cast< Array* >(it->getValue());
            while(Command* cmd =dynamic_cast< Command* >(queue->front())) {
                if(cmd->isTimeout(now)) {
                    if(cmd->isProcessing()) {
                        WARN("service %s(%lld) who %lld command %lld cancel", name(), (long long)m_id, (long long)cmd->getWho(), (long long)cmd->getCommand());
                    }
                    queue->pop_front();
                }
                else {
                    break;
                }
            }
            if(Command* cmd =dynamic_cast< Command* >(queue->front())) {
                if(cmd->isProcessing()) {
                    continue;
                }
                ASSERT(cmd->isInit());
                if(!ls) {
                    ls =SafeNew<Int64Array>();
                }
                ls->push_back(who);
            }
        }
        const int64_t n= ls ? ls->size() : 0;
        for(int64_t i=0; i<n; ++i) {
            _process_request(ls->get(i));
        }
    }
    /* clear timeout rpc */
    if(m_rpc_tb->size()>0) {
        Array* ls =0;
        HashIterator* it =static_cast< HashIterator* >(m_rpc_tb->iterator());
        while(it->next()) {
            RpcInfo* ri =static_cast< RpcInfo* >(it->getValue());
            if(now >= ri->getExpireTime()) {
                if(!ls) {
                    ls =SafeNew<Array>();
                }
                ls->push_back(ri);
                it->remove();
            }
        }
        const int64_t n =ls ? ls->size() : 0;
        for(int64_t i=0; i<n; ++i) {
            RpcInfo* ri =static_cast< RpcInfo* >(ls->get(i));
            WARN("service %s(%lld) rpc %lld cancel", name(), (long long)m_id, (long long)ri->getId());
            ri->timeout();
        }
    }
}
Пример #2
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);
    }
}