/** This would get called when idel time watcher goes timeout */ static void wr_wkr_wait_cb(struct ev_loop *loop, ev_timer *w, int revents) { LOG_FUNCTION wr_wkr_t *worker = (wr_wkr_t*)w->data; //ev_timer_stop(loop, &worker->t_idle); ev_timer_stop(loop, &worker->t_wait); if(worker->app == NULL) { LOG_INFO("wr_wkr_wait_cb: Worker removed with pid %d", worker->pid); wr_wkr_free(worker); } else if(worker->trials_done < WR_PING_TRIALS) { worker->trials_done++; LOG_INFO("Worker %d with pid %u ping for trial no %d", worker->id, worker->pid, worker->trials_done); worker->t_wait.repeat = WR_PING_WAIT_TIME; worker->state |= (WR_WKR_HANG | WR_WKR_PING_SENT); if(worker->state & WR_WKR_PING_REPLIED) { worker->state ^= WR_WKR_PING_REPLIED; } scgi_t *scgi = scgi_new(); scgi_header_add(scgi, "COMPONENT", strlen("COMPONENT"), "WORKER", strlen("WORKER")); scgi_header_add(scgi, "METHOD", strlen("METHOD"), "PING", strlen("PING")); if(scgi_build(scgi)!=0) { LOG_ERROR(WARN,"SCGI request build failed."); } worker->ctl->scgi = scgi; ev_io_start(loop, &worker->ctl->w_write); //ev_timer_again(loop, &worker->t_ping_wait); ev_timer_again(loop, &worker->t_wait); } else { //render 500 response to Request, kill the worker wr_wkr_recreate(worker); } }
void load_application(wkr_t* w){ LOG_FUNCTION w->ctl->scgi = scgi_new(); if(w->ctl->scgi == NULL) { LOG_ERROR(SEVERE,"Cannot create SCGI Request"); sigproc(); return; } w->http = http_new(w); if(w->http == NULL) { scgi_body_add(w->ctl->scgi, "unable to load application.", strlen("unable to load application.")); LOG_ERROR(SEVERE,"unable to load application."); }else if(worker_listen(w) < 0) { scgi_body_add(w->ctl->scgi, "Error Initializing Workers.", strlen("Error Initializing Workers.")); LOG_ERROR(WARN,"Error Initializing Workers."); }else{ worker_accept_requests(w); LOG_INFO("Worker ready for serving requests."); init_idle_watcher(w); LOG_INFO("Successfully loaded rack application=%s with environment=%s", w->tmp->path.str, w->tmp->env.str); } //loading adapter according to application type LOG_DEBUG(DEBUG,"webroar_root = %s", w->tmp->root_path.str); LOG_DEBUG(DEBUG,"path = %s, name = %s, type = %s, environment = %s, baseuri = %s, analytics = %c", w->tmp->path.str, w->tmp->name.str, w->tmp->type.str, w->tmp->env.str, w->tmp->resolver.str, w->tmp->profiler); // Send error or ok acknowledgement message if(w->ctl->scgi->body_length > 0){ // Send error response w->ctl->error = TRUE; get_worker_add_ctl_scgi(w, TRUE); ev_io_start(w->loop,&(w->ctl->w_write)); ev_timer_again(w->loop, &w->ctl->t_ack); }else{ // Send acknowledgement message get_worker_add_ctl_scgi(w, FALSE); ev_io_start(w->loop,&(w->ctl->w_write)); } wkr_tmp_free(&w->tmp); }
wr_ctl_msg_t* wr_ctl_msg_validate(scgi_t* request, wr_ctl_t* ctl) { LOG_FUNCTION wr_ctl_msg_t* ctl_msg = wr_malloc(wr_ctl_msg_t); char *val; char error[STR_SIZE64]; ctl->type = WR_CTL_MSG_NONE; ctl->scgi = scgi_new(); val = (char*) scgi_header_value_get(request,"COMPONENT"); if(val == NULL) { memcpy(error,"COMPONENT missing.", strlen("COMPONENT missing.")+1); goto ctl_msg_err; } scgi_header_add(ctl->scgi, "COMPONENT", strlen("COMPONENT"), val, strlen(val)); if(strcmp(val,"APPLICATION")==0) { val = (char*) scgi_header_value_get(request,"METHOD"); if(val == NULL) { memcpy(error,"METHOD missing.", strlen("METHOD missing.")+1); goto ctl_msg_err; } scgi_header_add(ctl->scgi, "METHOD", strlen("METHOD"), val, strlen(val)); ctl_msg->msg.app.app_name.str = (char*) scgi_header_value_get(request,"APP_NAME"); if(ctl_msg->msg.app.app_name.str) ctl_msg->msg.app.app_name.len = strlen(ctl_msg->msg.app.app_name.str); if(ctl_msg->msg.app.app_name.str == NULL) { memcpy(error,"Application name is missing.", strlen("Application name is missing.")+1); goto ctl_msg_err; } // Application Add if(strcmp(val,"ADD")==0) { ctl->type = WR_CTL_MSG_APPLICATION_ADD; } else if(strcmp(val,"REMOVE")==0) { ctl->type = WR_CTL_MSG_APPLICATION_REMOVE; } else if(strcmp(val,"RELOAD")==0) { ctl->type = WR_CTL_MSG_APPLICATION_RELOAD; }else { memcpy(error, "Invalid METHOD.", strlen("Invalid METHOD.")+1); goto ctl_msg_err; } } else if(strcmp(val,"WORKER")==0) { val = (char*) scgi_header_value_get(request,"METHOD"); if(val == NULL) { memcpy(error, "METHOD missing.", strlen("METHOD missing.")+1); goto ctl_msg_err; } if(strcmp(val,"ERROR")==0) { scgi_header_add(ctl->scgi, "METHOD", strlen("METHOD"), "ACK", strlen("ACK")); }else{ scgi_header_add(ctl->scgi, "METHOD", strlen("METHOD"), val, strlen(val)); } // Worker Add if(strcmp(val,"ADD")==0) { ctl->type = WR_CTL_MSG_WORKER_ADD; ctl_msg->msg.wkr.app_name.str = (char*) scgi_header_value_get(request,"APPLICATION"); if(ctl_msg->msg.wkr.app_name.str) ctl_msg->msg.wkr.app_name.len = strlen(ctl_msg->msg.wkr.app_name.str); ctl_msg->msg.wkr.pid.str = (char*) scgi_header_value_get(request,"PID"); if(ctl_msg->msg.wkr.pid.str) ctl_msg->msg.wkr.pid.len = strlen(ctl_msg->msg.wkr.pid.str); ctl_msg->msg.wkr.port.str = (char*) scgi_header_value_get(request,"PORT"); if(ctl_msg->msg.wkr.port.str) ctl_msg->msg.wkr.port.len = strlen(ctl_msg->msg.wkr.port.str); ctl_msg->msg.wkr.sock_path.str = (char*) scgi_header_value_get(request,"SOCK_PATH"); if(ctl_msg->msg.wkr.sock_path.str) ctl_msg->msg.wkr.sock_path.len = strlen(ctl_msg->msg.wkr.sock_path.str); ctl_msg->msg.wkr.uds.str = (char*) scgi_header_value_get(request,"UDS"); if(ctl_msg->msg.wkr.uds.str) ctl_msg->msg.wkr.uds.len = strlen(ctl_msg->msg.wkr.uds.str); if(ctl_msg->msg.wkr.app_name.str == NULL || ctl_msg->msg.wkr.pid.str == NULL || ctl_msg->msg.wkr.uds.str == NULL) { memcpy(error, "Missing some headers.", strlen("Missing some headers.")+1); goto ctl_msg_err; } } else if(strcmp(val,"REMOVE")==0) { ctl->type = WR_CTL_MSG_WORKER_REMOVE; } else if(strcmp(val,"PING") == 0) { ctl->type = WR_CTL_MSG_WORKER_PING; } else if(strcmp(val,"CONF_REQ") == 0){ ctl->type = WR_CTL_MSG_WORKER_CONF_REQ; ctl_msg->msg.wkr.app_name.str = (char*) scgi_header_value_get(request,"APPLICATION"); if(ctl_msg->msg.wkr.app_name.str) ctl_msg->msg.wkr.app_name.len = strlen(ctl_msg->msg.wkr.app_name.str); } else if(strcmp(val,"ERROR") == 0) { ctl->type = WR_CTL_MSG_WORKER_ADD_ERROR; ctl_msg->msg.wkr.app_name.str = (char*) scgi_header_value_get(request,"APPLICATION"); if(ctl_msg->msg.wkr.app_name.str) ctl_msg->msg.wkr.app_name.len = strlen(ctl_msg->msg.wkr.app_name.str); ctl_msg->msg.wkr.pid.str = (char*) scgi_header_value_get(request,"PID"); if(ctl_msg->msg.wkr.pid.str) ctl_msg->msg.wkr.pid.len = strlen(ctl_msg->msg.wkr.pid.str); ctl_msg->msg.wkr.port.str = (char*) scgi_header_value_get(request,"PORT"); if(ctl_msg->msg.wkr.port.str) ctl_msg->msg.wkr.port.len = strlen(ctl_msg->msg.wkr.port.str); ctl_msg->msg.wkr.sock_path.str = (char*) scgi_header_value_get(request,"SOCK_PATH"); if(ctl_msg->msg.wkr.sock_path.str) ctl_msg->msg.wkr.sock_path.len = strlen(ctl_msg->msg.wkr.sock_path.str); ctl_msg->msg.wkr.uds.str = (char*) scgi_header_value_get(request,"UDS"); if(ctl_msg->msg.wkr.uds.str) ctl_msg->msg.wkr.uds.len = strlen(ctl_msg->msg.wkr.uds.str); if(ctl_msg->msg.wkr.app_name.str == NULL || ctl_msg->msg.wkr.pid.str == NULL || ctl_msg->msg.wkr.uds.str == NULL) { memcpy(error, "Missing some headers.", strlen("Missing some headers.")+1); goto ctl_msg_err; } }else { memcpy(error,"Invalid METHOD.", strlen("Invalid METHOD.")+1); goto ctl_msg_err; } } else { memcpy(error,"Invalid COMPONENT.", strlen("Invalid COMPONENT.")+1); goto ctl_msg_err; } return ctl_msg; ctl_msg_err: LOG_ERROR(WARN,"Error found in controller message"); ctl->type = WR_CTL_MSG_TYPE_ERROR; scgi_body_add(ctl->scgi, error, strlen(error)); scgi_header_add(ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR")); return ctl_msg; }