Beispiel #1
0
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);
		}
	}
}
Beispiel #2
0
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();
	}
}
Beispiel #3
0
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
	}
}
Beispiel #4
0
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
	}
}