Example #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->invoke(SafeNew<Error>(ErrorCode::TIMEOUT));
			}
		}
	}
Example #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);
    }
}