Example #1
0
int ProcWorker::proc(ProcJob *job){
	const Request *req = job->link->last_recv();
	Response resp;
	
	proc_t p = job->cmd->proc;
	job->time_wait = 1000 * (millitime() - job->stime);
	job->result = (*p)(job->serv, job->link, *req, &resp);
	job->time_proc = 1000 * (millitime() - job->stime) - job->time_wait;

	if(job->link->send(resp.resp) == -1){
		job->result = PROC_ERROR;
	}else{
		if(job->cmd->flags & Command::FLAG_READ){
			int len = job->link->write();
			if(len < 0){
				job->result = PROC_ERROR;
			}
		}
		log_debug("w:%.3f,p:%.3f, req: %s, resp: %s",
			job->time_wait, job->time_proc,
			serialize_req(*req).c_str(),
			serialize_req(resp.resp).c_str());
	}
	return 0;
}
Example #2
0
int CommandProc::proc(const Link &link, const Request &req, Response *resp){
	if(req.size() <= 0){
		return -1;
	}
	if(log_level() >= Logger::LEVEL_DEBUG){
		std::string log_buf = serialize_req(req);
		log_debug("req: %s", log_buf.c_str());
	}

	int ret = 0;
	proc_map_t::iterator it = proc_map.find(req[0]);
	if(it == proc_map.end()){
		resp->push_back("client_error");
		resp->push_back("Unknown Command: " + req[0].String());
	}else{
		proc_t p = it->second;
		ret = (this->*p)(link, req, resp);
	}

	if(log_level() >= Logger::LEVEL_DEBUG){
		std::string log_buf = serialize_req(*resp);
		log_debug("resp: %s", log_buf.c_str());
	}

	return ret;
}
Example #3
0
void Server::proc(ProcJob *job){
	job->serv = this;
	job->result = PROC_OK;
	job->stime = millitime();
	const Request *req = job->link->last_recv();
	
	Response resp;
	proc_map_t::iterator it = proc_map.find(req->at(0));
	if(it == proc_map.end()){
		resp.push_back("client_error");
		resp.push_back("Unknown Command: " + req->at(0).String());
	}else{
		Command *cmd = it->second;
		job->cmd = cmd;
		if(cmd->flags & Command::FLAG_WRITE){
			job->result = PROC_BACKEND;
			writer.push(*job);
			return; /////
		}
		proc_t p = cmd->proc;
		job->time_wait = 1000 *(millitime() - job->stime);
		job->result = (*p)(this, job->link, *req, &resp);
		job->time_proc = 1000 *(millitime() - job->stime);
	}
	
	if(job->link->send(resp) == -1){
		job->result = PROC_ERROR;
	}else{
		log_debug("w:%.3f,p:%.3f, req: %s, resp: %s",
			job->time_wait, job->time_proc,
			serialize_req(*req).c_str(),
			serialize_req(resp).c_str());
	}
}
Example #4
0
void NetworkServer::proc(ProcJob *job){
	job->serv = this;
	job->result = PROC_OK;
	job->stime = millitime();

	const Request *req = job->link->last_recv();
	Response resp;

	do{
		// AUTH
		if(this->need_auth && job->link->auth == false && req->at(0) != "auth"){
			resp.push_back("noauth");
			resp.push_back("authentication required");
			break;
		}
		
		Command *cmd = proc_map.get_proc(req->at(0));
		if(!cmd){
			resp.push_back("client_error");
			resp.push_back("Unknown Command: " + req->at(0).String());
			break;
		}
		job->cmd = cmd;
		if (cmd->name != "client") {
			job->link->last_cmd = cmd->name;
        }

		if(cmd->flags & Command::FLAG_THREAD){
			if(cmd->flags & Command::FLAG_WRITE){
				if (this->readonly) {
				    resp.reply_status(-1, "server is readonly");
				    break;
				}
				job->result = PROC_THREAD;
				writer->push(*job);
			}else{
				job->result = PROC_THREAD;
				reader->push(*job);
			}
			return;
		}

		proc_t p = cmd->proc;
		job->time_wait = 1000 * (millitime() - job->stime);
		job->result = (*p)(this, job->link, *req, &resp);
		job->time_proc = 1000 * (millitime() - job->stime) - job->time_wait;
	}while(0);
	
	if(job->link->send(resp.resp) == -1){
		job->result = PROC_ERROR;
	}else{
		if(log_level() >= Logger::LEVEL_DEBUG){
			log_debug("w:%.3f,p:%.3f, req: %s, resp: %s",
				job->time_wait, job->time_proc,
				serialize_req(*req).c_str(),
				serialize_req(resp.resp).c_str());
		}
	}
}
Example #5
0
int Server::ProcWorker::proc(ProcJob *job){
	const Request *req = job->link->last_recv();
	Response resp;
	
	double stime = millitime();
	proc_t p = job->cmd->proc;
	job->result = (*p)(job->serv, job->link, *req, &resp);
	double etime = millitime();
	job->time_wait = 1000 * (stime - job->stime);
	job->time_proc = 1000 *(etime - stime);

	if(job->link->send(resp) == -1){
		job->result = PROC_ERROR;
	}else{
		log_debug("w:%.3f,p:%.3f, req: %s, resp: %s",
			job->time_wait, job->time_proc,
			serialize_req(*req).c_str(),
			serialize_req(resp).c_str());
	}
	return 0;
}
Example #6
0
int NetworkServer::proc_result(ProcJob *job, ready_list_t *ready_list){
	Link *link = job->link;
	int len;
			
	if(job->cmd){
		job->cmd->calls += 1;
		job->cmd->time_wait += job->time_wait;
		job->cmd->time_proc += job->time_proc;

		double total_time = job->time_wait + job->time_proc;
		if (total_time >= this->slow_time) {
		    slowlog_warn("proc slow, remote_ip: %s wait: %.3f proc: %.3f total: %.3f req: %s", 
                    link->remote_ip, job->time_wait, job->time_proc, total_time, 
			        serialize_req(*link->last_recv()).c_str());
		}
	}
	if(job->result == PROC_ERROR){
		log_info("fd: %d, proc error, delete link", link->fd());
		goto proc_err;
	}
    if(link->error()){
		log_debug("fd: %d, link error, delete link", link->fd());
		goto proc_err;
    }
	
	len = link->write();
	//log_debug("write: %d", len);
	if(len < 0){
		log_debug("fd: %d, write: %d, delete link", link->fd(), len);
		goto proc_err;
	}
	this->bytes_written += len;

	if(!link->output->empty()){
		fdes->set(link->fd(), FDEVENT_OUT, 1, link);
	}
	if(link->input->empty()){
		fdes->set(link->fd(), FDEVENT_IN, 1, link);
        link->unRef();
        log_debug("proc_result remote_ip: %s ref: %d", link->remote_ip, link->ref_count);
	}else{
		fdes->clr(link->fd(), FDEVENT_IN);
		ready_list->push_back(link);
	}
	return PROC_OK;

proc_err:
    destroy_link(link);
	return PROC_ERROR;
}
Example #7
0
int NetworkServer::proc(ProcJob *job){
	job->serv = this;
	job->result = PROC_OK;
	job->stime = millitime();

	const Request *req = job->req;

	do{
		// AUTH
		if(this->need_auth && job->link->auth == false && req->at(0) != "auth"){
			job->resp.push_back("noauth");
			job->resp.push_back("authentication required.");
			break;
		}
		
		job->cmd = proc_map.get_proc(req->at(0));
		if(!job->cmd){
			job->resp.push_back("client_error");
			job->resp.push_back("Unknown Command: " + req->at(0).String());
			break;
		}

		if(this->readonly && (job->cmd->flags & Command::FLAG_WRITE)){
			job->resp.push_back("client_error");
			job->resp.push_back("Forbidden Command: " + req->at(0).String());
			break;
		}
		
		if(job->cmd->flags & Command::FLAG_THREAD){
			if(job->cmd->flags & Command::FLAG_WRITE){
				writer->push(job);
			}else{
				reader->push(job);
			}
			return PROC_THREAD;
		}

		proc_t p = job->cmd->proc;
		job->time_wait = 1000 * (millitime() - job->stime);
		job->result = (*p)(this, job->link, *req, &job->resp);
		job->time_proc = 1000 * (millitime() - job->stime) - job->time_wait;
	}while(0);
	
	if(job->link->send(job->resp.resp) == -1){
		job->result = PROC_ERROR;
	}else{
		// try to write socket before it would be added to fdevents
		// socket is NONBLOCK, so it won't block.
		if(job->link->write() < 0){
			job->result = PROC_ERROR;
		}
	}

	if(log_level() >= Logger::LEVEL_DEBUG){ // serialize_req is expensive
		log_debug("w:%.3f,p:%.3f, req: %s, resp: %s",
			job->time_wait, job->time_proc,
			serialize_req(*job->req).c_str(),
			serialize_req(job->resp.resp).c_str());
	}

	return job->result;
}
Example #8
0
void* Slave::_run_thread(void *arg){
	Slave *slave = (Slave *)arg;
	const SSDB *ssdb = slave->ssdb;
	const char *ip = slave->master_ip.c_str();
	int port = slave->master_port;
	Link *link = NULL;

	int retry = 0;
	const std::vector<Bytes> *req;
	while(true){
		if(link == NULL){
			if(retry){
				int t = retry > 15? 15 : retry;
				usleep(t * 1000 * 1000);
				log_info("[%d] connecting to master at %s:%d...", retry, ip, port);
			}
			link = connect(ip, port, slave->next_seq, slave->last_key);
			if(link == NULL){
				retry ++;
				continue;
			}else{
				retry = 0;
			}
		}

		req = link->recv();
		if(req == NULL){
			retry = 1;
			delete link;
			link = NULL;
			log_info("recv error, reconnecting to master...");
			continue;
		}else if(req->empty()){
			if(link->read() <= 0){
				retry = 1;
				delete link;
				link = NULL;
				log_info("network error, reconnecting to master...");
			}
			continue;
		}

		Bytes cmd = req->at(0);
		if(cmd == "sync_set"){
			log_trace("recv sync: %s", serialize_req(*req).c_str());
			if(req->size() != 4){
				log_warn("invalid set params!");
				break;
			}
			uint64_t seq = req->at(1).Uint64();
			Bytes key = req->at(2);
			Bytes val = req->at(3);
			if(seq == 0){
				// dump
				slave->last_key = key.String();
			}else{
				// sync
				slave->next_seq = seq + 1;
			}

			int ret = ssdb->raw_set(key, val);
			if(ret == -1){
				log_error("ssdb.raw_set error!");
			}

			slave->save_status();
		}else if(cmd == "sync_del"){
			log_trace("recv sync: %s", serialize_req(*req).c_str());
			if(req->size() != 3){
				log_warn("invalid del params!");
				break;
			}
			uint64_t seq = req->at(1).Uint64();
			Bytes key = req->at(2);
			if(seq == 0){
				// dump
				slave->last_key = key.String();
			}else{
				// sync
				slave->next_seq = seq + 1;
			}

			int ret = ssdb->raw_del(key);
			if(ret == -1){
				log_error("ssdb.raw_del error!");
			}

			slave->save_status();
		}else if(cmd == "dump_end"){
			log_info("dump end, step in sync");
			slave->last_key = "";
		}else if(cmd == "noop"){
			//
		}else{
			log_warn("unknow sync command: %s", serialize_req(*req).c_str());
		}
	} // end while

	if(link){
		delete link;
	}
	log_info("Slave thread quit");
	return (void *)NULL;
}