void NetworkServer::serve(){ writer = new ProcWorkerPool("writer"); writer->start(num_writers); reader = new ProcWorkerPool("reader"); reader->start(num_readers); ready_list_t ready_list; ready_list_t ready_list_2; ready_list_t::iterator it; const Fdevents::events_t *events; fdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link); fdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader); fdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer); uint32_t last_ticks = g_ticks; while(!quit){ double loop_stime = millitime(); // status report if((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){ last_ticks = g_ticks; log_info("server running, links: %d", this->link_count); } ready_list.swap(ready_list_2); ready_list_2.clear(); if(!ready_list.empty()){ // ready_list not empty, so we should return immediately events = fdes->wait(0); }else{ events = fdes->wait(50); } if(events == NULL){ log_fatal("events.wait error: %s", strerror(errno)); break; } for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); if(fde->data.ptr == serv_link){ Link *link = accept_link(); if(link){ this->link_count ++; log_debug("new link from %s:%d, fd: %d, links: %d", link->remote_ip, link->remote_port, link->fd(), this->link_count); fdes->set(link->fd(), FDEVENT_IN, 1, link); }else{ log_debug("accept return NULL"); } }else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){ ProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr; ProcJob *job = NULL; if(worker->pop(&job) == 0){ log_fatal("reading result from workers error!"); exit(0); } proc_result(job, &ready_list); }else{ proc_client_event(fde, &ready_list); } } for(it = ready_list.begin(); it != ready_list.end(); it ++){ Link *link = *it; fdes->del(link->fd()); if(link->error()){ this->link_count --; delete link; continue; } const Request *req = link->recv(); if(req == NULL){ log_warn("fd: %d, link parse error, delete link", link->fd()); link->mark_error(); ready_list_2.push_back(link); continue; } if(req->empty()){ fdes->set(link->fd(), FDEVENT_IN, 1, link); continue; } link->active_time = millitime(); ProcJob *job = new ProcJob(); job->link = link; job->req = link->last_recv(); int result = this->proc(job); if(result == PROC_THREAD){ // }else if(result == PROC_BACKEND){ // link_count does not include backend links this->link_count --; }else{ proc_result(job, &ready_list_2); } } // end foreach ready link double loop_time = millitime() - loop_stime; if(loop_time > 0.5){ log_warn("long loop time: %.3f", loop_time); } } }
void NetworkServer::serve(){ writer = new ProcWorkerPool("writer"); writer->start(WRITER_THREADS); reader = new ProcWorkerPool("reader"); reader->start(READER_THREADS); ready_list_t ready_list; ready_list_t ready_list_2; ready_list_t::iterator it; const Fdevents::events_t *events; fdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link); fdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader); fdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer); uint32_t last_ticks = g_ticks; while(!quit){ // status report if((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){ last_ticks = g_ticks; log_info("server running, links: %d", this->link_count); } ready_list.swap(ready_list_2); ready_list_2.clear(); if(!ready_list.empty()){ // ready_list not empty, so we should return immediately events = fdes->wait(0); }else{ events = fdes->wait(50); } if(events == NULL){ log_fatal("events.wait error: %s", strerror(errno)); break; } for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); if(fde->data.ptr == serv_link){ Link *link = accept_link(); if(link){ this->link_count ++; log_debug("new link from %s:%d, fd: %d, links: %d", link->remote_ip, link->remote_port, link->fd(), this->link_count); fdes->set(link->fd(), FDEVENT_IN, 1, link); } }else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){ ProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr; ProcJob job; if(worker->pop(&job) == 0){ log_fatal("reading result from workers error!"); exit(0); } if(proc_result(&job, &ready_list) == PROC_ERROR){ // } }else{ proc_client_event(fde, &ready_list); } } for(it = ready_list.begin(); it != ready_list.end(); it ++){ Link *link = *it; if(link->error()){ destroy_link(link); continue; } const Request *req = link->recv(); if(req == NULL){ log_warn("fd: %d, link parse error, delete link", link->fd()); destroy_link(link); continue; } if(req->empty()){ link->unRef(); fdes->set(link->fd(), FDEVENT_IN, 1, link); log_debug("serve parse incomplete request, remote_ip: %s ref: %d", link->remote_ip, link->ref_count); continue; } link->active_time = millitime(); //FIXME char remote_ip_port[32]; snprintf(remote_ip_port, 32, "%s:%d", link->remote_ip, link->remote_port); this->active_links.add(remote_ip_port,(int64_t)link->active_time); ProcJob job; job.link = link; this->proc(&job); if(job.result == PROC_THREAD){ fdes->del(link->fd()); continue; } if(job.result == PROC_BACKEND){ fdes->del(link->fd()); this->link_count --; char remote_ip_port[32]; snprintf(remote_ip_port, 32, "%s:%d", link->remote_ip, link->remote_port); this->link_map.erase(remote_ip_port); this->active_links.del(remote_ip_port); // don't delete link continue; } if(proc_result(&job, &ready_list_2) == PROC_ERROR){ // } } // end foreach ready link //every event loop destroy_idle_link(); } }
void NetworkServer::serve(){ { auto_mask mask(3, SIGPIPE, SIGINT, SIGTERM, SIGQUIT); writer = new (std::nothrow)ProcWorkerPool("writer"); ASSERT_SYS(NULL != writer, "try to new ProcWorkerPool failed, no memory"); writer->start(num_writers); reader = new (std::nothrow)ProcWorkerPool("reader"); ASSERT_SYS(NULL != reader, "try to new ProcWorkerPool failed, no memory"); reader->start(num_readers); } ready_list_t ready_list; ready_list_t ready_list_2; ready_list_t::iterator it; const Fdevents::events_t *events; fdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link); fdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader); fdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer); uint32_t last_ticks = g_ticks; while(!quit){ if((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){ last_ticks = g_ticks; log_info("server is running, links: %d", this->link_count); } ready_list.swap(ready_list_2); ready_list_2.clear(); if(!ready_list.empty()){ events = fdes->wait(0); }else{ events = fdes->wait(50); } if(events == NULL){ log_fatal("events.wait error: %s", strerror(errno)); break; } for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); if(fde->data.ptr == serv_link){ Link *link = accept_link(); if(link){ this->link_count ++; log_debug("new link from %s:%d, fd: %d, links count: %d", link->remote_ip, link->remote_port, link->fd(), this->link_count); fdes->set(link->fd(), FDEVENT_IN, 1, link); } }else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){ ProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr; ProcJob *job = NULL; if(worker->pop(&job) == 0){ log_fatal("reading result from workers error!"); exit(0); } if(proc_result(job, &ready_list) == PROC_ERROR){ // } }else{ proc_client_event(fde, &ready_list); } } for(it = ready_list.begin(); it != ready_list.end(); it ++){ Link *link = *it; if(link->error()){ this->link_count --; fdes->del(link->fd()); SAFE_DELETE(link); continue; } if(link->readed >= sizeof(head_t) && 0x00 == link->get_basic_string()[0]){ if(0 == link->request.head.logid){ link->request.head.logid = pow(2, 64) * (rand() / (RAND_MAX + 1.0)); } link->add_basic_info("client_ip", link->remote_ip); link->add_basic_info("client_port", link->remote_port); link->add_basic_info("logid", link->request.head.logid); link->add_basic_info("method", link->request.head.method); link->add_basic_info("magic_num", link->request.head.magic_num); } if(link->readed >= sizeof(head_t) && link->request.head.bodylen > MAX_PACKAGE_SIZE){ log_frame("[ %s ]fd: %d, body len is too big, give up reading[ body len: %u, max: %u ].", link->get_basic_string(), link->request.head.bodylen, MAX_PACKAGE_SIZE); fdes->del(link->fd()); }else if(link->readed < sizeof(head_t) || link->request.head.bodylen + sizeof(head_t) > link->readed){ //head has not been read over or body has not been read over, continue to read log_frame("[ %s ]fd: %d, readed: %d, bodylen: %u, continue to read", (link->readed >= sizeof(head_t) ? link->get_basic_string() : ""), link->fd(), link->readed, link->request.head.bodylen); fdes->set(link->fd(), FDEVENT_IN, 1, link); continue; }else{ log_frame("[ %s ]fd: %d, readed: %d, bodylen: %u, read data finished", link->get_basic_string(), link->fd(), link->readed, link->request.head.bodylen); fdes->del(link->fd()); } link->active_time = millitime(); //prepare response head first link->response.head = link->request.head; snprintf(link->response.head.provider, sizeof(link->response.head.provider), "%s", provider); link->response.head.bodylen = 0; ProcJob *job = new (std::nothrow)ProcJob(); ASSERT_SYS(NULL != job, "try to new ProcJob failed, no memory"); job->link = link; job->req = &link->request; int result = this->proc(job); if(result == PROC_THREAD){ fdes->del(link->fd()); continue; } if(result == PROC_BACKEND){ job->req = &link->request; this->link_count --; continue; } if(proc_result(job, &ready_list_2) == PROC_ERROR){ // } } // end foreach ready link } }
void NetworkServer::serve(){ writer = new ProcWorkerPool("writer"); writer->start(num_writers); reader = new ProcWorkerPool("reader"); reader->start(num_readers); pthread_t tid; int err = pthread_create(&tid, NULL, &NetworkServer::_ops_timer_thread, this); if (err != 0) { log_error("can't start ops timer thread: %s", strerror(err)); exit(-1); } link_dict_t ready_dict; link_dict_t tmp_dict; link_dict_t blocked_dict; link_dict_t::iterator it; const Fdevents::events_t *events; fdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link); fdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader); fdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer); uint32_t last_ticks = g_ticks; while(!quit){ // status report if((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){ last_ticks = g_ticks; log_debug("server running, links: %d", this->link_count); } ready_dict.swap(tmp_dict); tmp_dict.clear(); if(!ready_dict.empty()){ /* ready_dict not empty, so we should return immediately */ events = fdes->wait(0); }else{ events = fdes->wait(50); } if(events == NULL){ log_fatal("events.wait error: %s", strerror(errno)); break; } for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); if(fde->data.ptr == serv_link){ Link *link = accept_link(); if(link){ this->link_count ++; log_debug("new link from %s:%d, fd: %d, links: %d", link->remote_ip, link->remote_port, link->fd(), this->link_count); fdes->set(link->fd(), FDEVENT_IN, 1, link); } }else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){ ProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr; ProcJob job; if(worker->pop(&job) == 0){ log_fatal("reading result from workers error!"); exit(0); } if(proc_result(&job, &ready_dict) == PROC_ERROR){ // } }else{ proc_client_event(fde, &ready_dict); } } /* if clients paused, add specified link into blocked_list and disable parsing request */ if(NetworkServer::clients_paused) { if(NetworkServer::clients_pause_end_time < time_ms()) { NetworkServer::clients_paused = 0; NetworkServer::clients_pause_end_time = 0; ready_dict.insert(blocked_dict.begin(), blocked_dict.end()); blocked_dict.clear(); } else { blocked_dict.insert(ready_dict.begin(), ready_dict.end()); ready_dict.clear(); continue; } } for(it = ready_dict.begin(); it != ready_dict.end(); it ++){ Link *link = it->second; if(link->error()){ this->link_count --; fdes->del(link->fd()); delete link; continue; } const Request *req = link->recv(); if(req == NULL){ log_warn("fd: %d, link parse error, delete link", link->fd()); this->link_count --; fdes->del(link->fd()); delete link; continue; } if(req->empty()){ fdes->set(link->fd(), FDEVENT_IN, 1, link); continue; } link->active_time = millitime(); ProcJob job; job.link = link; this->proc(&job); if(job.result == PROC_THREAD){ fdes->del(link->fd()); continue; } if(job.result == PROC_BACKEND){ fdes->del(link->fd()); this->link_count --; continue; } if(proc_result(&job, &tmp_dict) == PROC_ERROR){ // } } // end foreach ready link } }