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; }
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; }
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()); } }
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()); } } }
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; }
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; }
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; }
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; }