webroar 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +48 -1
- data/README +11 -14
- data/Rakefile +1 -1
- data/conf/mime_type.yml +172 -166
- data/conf/server_internal_config.yml +30 -8
- data/doc/user-guide.html +294 -153
- data/doc/user-guide.txt +9 -13
- data/lib/command_runner.rb +1 -0
- data/lib/dependencies.rb +18 -15
- data/lib/installer.rb +115 -50
- data/src/admin_panel/app/controllers/admin_controller.rb +1 -15
- data/src/admin_panel/app/controllers/application_controller.rb +2 -2
- data/src/admin_panel/app/controllers/application_specification_controller.rb +2 -1
- data/src/admin_panel/app/controllers/headers_controller.rb +73 -0
- data/src/admin_panel/app/controllers/mail_specification_controller.rb +10 -0
- data/src/admin_panel/app/controllers/server_specification_controller.rb +14 -0
- data/src/admin_panel/app/helpers/admin_helper.rb +0 -85
- data/src/admin_panel/app/models/app.rb +1 -1
- data/src/admin_panel/app/models/application_specification.rb +33 -25
- data/src/admin_panel/app/models/headers.rb +116 -0
- data/src/admin_panel/app/models/mail_specification.rb +20 -5
- data/src/admin_panel/app/models/server_specification.rb +2 -7
- data/src/admin_panel/app/views/admin/configuration.html.erb +10 -5
- data/src/admin_panel/app/views/exceptions/_exception_list_partial.html.erb +4 -4
- data/src/admin_panel/app/views/graph/_graph_page.html.erb +3 -0
- data/src/admin_panel/app/views/headers/_add_expires_text_box.html.erb +35 -0
- data/src/admin_panel/app/views/headers/_expires_by_type_form.html.erb +65 -0
- data/src/admin_panel/app/views/headers/_headers_table.html.erb +113 -0
- data/src/admin_panel/app/views/mail_specification/_current_spec.html.erb +168 -0
- data/src/admin_panel/app/views/{admin → server_specification}/_add_div.html.erb +1 -1
- data/src/admin_panel/config/initializers/application_constants.rb +6 -0
- data/src/admin_panel/lib/control.rb +6 -3
- data/src/admin_panel/lib/scgi.rb +74 -21
- data/src/admin_panel/lib/yaml_writer.rb +51 -17
- data/src/admin_panel/public/javascripts/application.js +20 -1
- data/src/head/wr_access_log.c +2 -2
- data/src/head/wr_application.c +294 -236
- data/src/head/wr_application.h +8 -8
- data/src/head/wr_configurator.c +451 -517
- data/src/head/wr_configurator.h +10 -115
- data/src/head/wr_connection.c +26 -25
- data/src/head/wr_connection.h +2 -3
- data/src/head/wr_controller.c +110 -93
- data/src/head/wr_controller.h +6 -6
- data/src/head/wr_main.c +31 -24
- data/src/head/wr_request.c +70 -93
- data/src/head/wr_request.h +0 -4
- data/src/head/wr_resolver.c +21 -15
- data/src/head/wr_resolver.h +2 -2
- data/src/head/wr_server.c +36 -26
- data/src/head/wr_server.h +5 -5
- data/src/head/wr_worker.c +551 -512
- data/src/head/wr_worker.h +33 -20
- data/src/helper/wr_config.c +316 -0
- data/src/helper/wr_config.h +235 -0
- data/src/helper/wr_helper.h +1 -5
- data/src/helper/wr_logger.c +4 -4
- data/src/helper/wr_scgi.c +3 -4
- data/src/helper/wr_scgi.h +2 -0
- data/src/helper/wr_string.h +2 -2
- data/src/helper/wr_util.c +3 -1
- data/src/helper/wr_util.h +0 -0
- data/src/helper/wr_yaml_parser.c +30 -0
- data/src/helper/wr_yaml_parser.h +1 -0
- data/src/ruby_lib/exception_tracker/instrumentation/action_controller.rb +2 -1
- data/src/ruby_lib/mailer/smtpmail.rb +7 -4
- data/src/ruby_lib/profiler/instrumentation/action_controller.rb +2 -1
- data/src/ruby_lib/profiler/instrumentation/active_record.rb +3 -0
- data/src/ruby_lib/rack/adapter/rails.rb +14 -7
- data/src/ruby_lib/ruby_interface/client.rb +1 -1
- data/src/ruby_lib/ruby_interface/version.rb +2 -2
- data/src/ruby_lib/webroar_app_loader.rb +4 -2
- data/src/worker/wkr_controller.c +200 -140
- data/src/worker/wkr_http.c +14 -28
- data/src/worker/wkr_http.h +4 -4
- data/src/worker/wkr_http_request.c +12 -11
- data/src/worker/wkr_http_request.h +7 -8
- data/src/worker/wkr_http_response.c +10 -14
- data/src/worker/wkr_http_response.h +0 -1
- data/src/worker/wkr_main.c +74 -140
- data/src/worker/wkr_static.c +295 -108
- data/src/worker/wkr_static.h +20 -7
- data/src/worker/worker.c +245 -70
- data/src/worker/worker.h +46 -34
- data/tasks/compile.rake +128 -175
- data/tasks/test.rake +345 -469
- data/test/spec/webroar_command_spec.rb +23 -0
- metadata +173 -43
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/README +0 -34
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/Rakefile +0 -13
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/init.rb +0 -5
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/lib/action_mailer_tls.rb +0 -16
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/lib/smtp_tls.rb +0 -123
- data/src/admin_panel/vendor/plugins/action_mailer_optional_tls/test/tls_test.rb +0 -42
- data/src/head/wr_config.h +0 -165
- data/src/ruby_lib/mailer/action_mailer_tls.rb +0 -16
- data/src/ruby_lib/mailer/smtp_tls.rb +0 -123
data/src/head/wr_application.c
CHANGED
|
@@ -20,21 +20,20 @@
|
|
|
20
20
|
|
|
21
21
|
// Worker count
|
|
22
22
|
static unsigned int worker_count = 0;
|
|
23
|
+
extern config_t *Config;
|
|
23
24
|
|
|
24
25
|
/************** Private Functions ******************/
|
|
25
26
|
|
|
26
27
|
// Check whether application already exist
|
|
27
|
-
|
|
28
|
+
wr_app_t* wr_app_exist(wr_svr_t *server, const char *app_name){
|
|
28
29
|
wr_app_t* app = server->apps, *tmp_app = NULL;
|
|
29
|
-
|
|
30
30
|
while(app) {
|
|
31
31
|
if(strcmp(app_name, app->conf->name.str)==0)
|
|
32
32
|
return app;
|
|
33
33
|
tmp_app = app;
|
|
34
34
|
app = app->next;
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
if(strcmp(app_name, WR_STATIC_FILE_SERVER_NAME) == 0){
|
|
36
|
+
if(strcmp(app_name, Config->Application.Static_server.name.str) == 0){
|
|
38
37
|
return server->static_app;
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -42,7 +41,7 @@ static inline wr_app_t* wr_app_exist(wr_svr_t *server, const char *app_name){
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
// Check whether pending worker exist
|
|
45
|
-
|
|
44
|
+
wr_pending_wkr_t* wr_pending_worker_exist(wr_app_t *app, const int pid){
|
|
46
45
|
int i;
|
|
47
46
|
for(i = 0 ; i < WR_QUEUE_SIZE(app->q_pending_workers); i++){
|
|
48
47
|
wr_pending_wkr_t* pending = wr_queue_fetch(app->q_pending_workers);
|
|
@@ -64,69 +63,121 @@ void wr_app_wkr_add_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
|
|
66
|
+
/** Set flag to TRUE to kill single pending worker */
|
|
67
|
+
void wr_app_kill_pending_wkr(wr_app_t* app, const int flag){
|
|
68
|
+
int pid = 0;
|
|
69
|
+
wr_pending_wkr_t *pending;
|
|
70
|
+
|
|
71
|
+
while(WR_QUEUE_SIZE(app->q_pending_workers) > 0) {
|
|
72
|
+
pending = wr_queue_fetch(app->q_pending_workers);
|
|
73
|
+
if(pending){
|
|
74
|
+
pid = *pending;
|
|
75
|
+
free(pending);
|
|
76
|
+
}
|
|
77
|
+
LOG_INFO("wr_app_kill_pending_wkr: killing worker, pid = %d", pid);
|
|
78
|
+
if(pid > 0)
|
|
79
|
+
kill(pid ,SIGKILL);
|
|
80
|
+
if(flag) break;
|
|
81
|
+
}
|
|
82
|
+
app->high_ratio = TOTAL_WORKER_COUNT(app) * Config->Application.max_req_ratio;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
void wr_app_add_error_msg(wr_app_t* app){
|
|
86
|
+
int err_msg_len = 0;
|
|
87
|
+
char err_msg[512];
|
|
88
|
+
|
|
89
|
+
LOG_DEBUG(DEBUG,"Some problem occurred while starting Application %s.", app->conf->name.str);
|
|
90
|
+
if(app->ctl){
|
|
91
|
+
scgi_header_add(app->ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
92
|
+
err_msg_len = sprintf(err_msg,"The application could not be started due to the following error. Please refer '/var/log/webroar/%s.log' and the application log file for more details.", app->conf->name.str);
|
|
93
|
+
scgi_body_add(app->ctl->scgi, err_msg, err_msg_len);
|
|
94
|
+
wr_ctl_resp_write(app->ctl);
|
|
95
|
+
}
|
|
96
|
+
app->timeout_counter = 0;
|
|
97
|
+
app->ctl = NULL;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Remove application from application list */
|
|
101
|
+
int wr_app_remove(wr_svr_t* server, const char* app_name) {
|
|
102
|
+
LOG_FUNCTION
|
|
103
|
+
wr_app_t* app = server->apps, *tmp_app = NULL;
|
|
104
|
+
|
|
105
|
+
LOG_DEBUG(DEBUG, "Removing application %s", app_name);
|
|
106
|
+
|
|
107
|
+
while(app) {
|
|
108
|
+
if(strcmp(app_name, app->conf->name.str)==0)
|
|
109
|
+
break;
|
|
110
|
+
tmp_app = app;
|
|
111
|
+
app = app->next;
|
|
112
|
+
}
|
|
113
|
+
if(app) {
|
|
114
|
+
if(tmp_app) {
|
|
115
|
+
tmp_app->next = app->next;
|
|
116
|
+
} else {
|
|
117
|
+
server->apps = app->next;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
app->next = NULL;
|
|
121
|
+
wr_app_free(app);
|
|
122
|
+
wr_app_conf_remove(app_name);
|
|
123
|
+
return 0;
|
|
124
|
+
} else if(strcmp(app_name, Config->Application.Static_server.name.str) == 0){
|
|
125
|
+
wr_app_free(server->static_app);
|
|
126
|
+
server->static_app = NULL;
|
|
127
|
+
wr_app_conf_remove(app_name);
|
|
128
|
+
return 0;
|
|
129
|
+
} else {
|
|
130
|
+
LOG_ERROR(WARN,"Aapplication %s didn't found in list", app_name);
|
|
131
|
+
sprintf(server->err_msg, "Application '%s' is not found.", app_name);
|
|
132
|
+
return -1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
67
136
|
/** Callback function to add worker timeout */
|
|
68
137
|
void wr_app_wkr_add_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
69
138
|
LOG_FUNCTION
|
|
70
139
|
wr_app_t* app = (wr_app_t*) w->data;
|
|
71
|
-
char err_msg[512];
|
|
72
|
-
int err_msg_len = 0;
|
|
73
|
-
int pid = 0;
|
|
74
140
|
|
|
141
|
+
LOG_ERROR(SEVERE,"wr_app_wkr_add_timeout_cb");
|
|
142
|
+
|
|
75
143
|
// Stop add timeout timer and increament timeout counter
|
|
76
144
|
ev_timer_stop(loop, &app->t_add_timeout);
|
|
77
145
|
app->timeout_counter ++;
|
|
78
146
|
|
|
147
|
+
if(app->timeout_counter > Config->Server.Worker.add_trials){
|
|
148
|
+
LOG_ERROR(SEVERE,"Reset worker timeout counter for %s.", app->conf->name.str);
|
|
149
|
+
app->timeout_counter = 0;
|
|
150
|
+
return;
|
|
151
|
+
}else if(app->timeout_counter == Config->Server.Worker.add_trials){
|
|
152
|
+
LOG_ERROR(SEVERE,"worker timeout counter for %s exceeds limit.", app->conf->name.str);
|
|
153
|
+
|
|
154
|
+
app->timeout_counter ++;
|
|
155
|
+
|
|
156
|
+
wr_app_kill_pending_wkr(app, FALSE);
|
|
157
|
+
|
|
158
|
+
app->t_add_timeout.repeat = Config->Server.Worker.add_wait;
|
|
159
|
+
ev_timer_again(loop, &app->t_add_timeout);
|
|
160
|
+
}
|
|
161
|
+
|
|
79
162
|
// Kill oldest pending worker
|
|
80
|
-
|
|
81
|
-
wr_pending_wkr_t *pending = wr_queue_fetch(app->q_pending_workers);
|
|
82
|
-
if(pending){
|
|
83
|
-
pid = *pending;
|
|
84
|
-
free(pending);
|
|
85
|
-
}
|
|
86
|
-
LOG_INFO("wr_app_wkr_add_timeout_cb: killing worker, pid = %d", pid);
|
|
87
|
-
if(pid > 0)
|
|
88
|
-
kill(pid ,SIGKILL);
|
|
89
|
-
LOG_DEBUG(DEBUG,"app->pending_wkr = %d", WR_QUEUE_SIZE(app->q_pending_workers));
|
|
90
|
-
if(WR_QUEUE_SIZE(app->q_pending_workers) > 0) {
|
|
91
|
-
ev_timer_again(loop, &app->t_add_timeout);
|
|
92
|
-
}
|
|
163
|
+
wr_app_kill_pending_wkr(app, TRUE);
|
|
93
164
|
|
|
94
|
-
|
|
95
|
-
app->
|
|
165
|
+
if(WR_QUEUE_SIZE(app->q_pending_workers) > 0) {
|
|
166
|
+
ev_timer_again(loop, &app->t_add_timeout);
|
|
96
167
|
}
|
|
97
168
|
|
|
98
169
|
// If application restarted, rollback all the changes.
|
|
99
170
|
if(app->state == WR_APP_RESTART){
|
|
171
|
+
wr_application_list_free(app->conf->new);
|
|
172
|
+
app->conf->new = NULL;
|
|
100
173
|
app->state = WR_APP_ACTIVE;
|
|
101
174
|
// Send error response
|
|
102
|
-
|
|
103
|
-
if(app->ctl){
|
|
104
|
-
scgi_header_add(app->ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
105
|
-
err_msg_len = sprintf(err_msg,"The application could not be started due to the following error. Please refer '/var/log/webroar/%s.log' and the application log file for more details.", app->conf->name.str);
|
|
106
|
-
scgi_body_add(app->ctl->scgi, err_msg, err_msg_len);
|
|
107
|
-
wr_ctl_resp_write(app->ctl);
|
|
108
|
-
}
|
|
109
|
-
app->timeout_counter = 0;
|
|
110
|
-
app->ctl = NULL;
|
|
175
|
+
wr_app_add_error_msg(app);
|
|
111
176
|
return;
|
|
112
177
|
}else if(app->state == WR_APP_NEW){
|
|
113
|
-
// Try out upto MAX timeout count
|
|
114
|
-
/*
|
|
115
|
-
if(WR_QUEUE_SIZE(app->q_pending_workers) == 0 && app->timeout_counter < WR_MAX_ADD_TIMEOUT_COUNTER){
|
|
116
|
-
wr_app_wkr_add(app);
|
|
117
|
-
}else{
|
|
118
|
-
*/
|
|
119
178
|
if(WR_QUEUE_SIZE(app->q_pending_workers) == 0){
|
|
120
179
|
// Send error response
|
|
121
|
-
|
|
122
|
-
if(app->ctl){
|
|
123
|
-
scgi_header_add(app->ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
124
|
-
err_msg_len = sprintf(err_msg,"The application could not be started due to the following error. Please refer '/var/log/webroar/%s.log' and the application log file for more details.", app->conf->name.str);
|
|
125
|
-
scgi_body_add(app->ctl->scgi, err_msg, err_msg_len);
|
|
126
|
-
wr_ctl_resp_write(app->ctl);
|
|
127
|
-
}
|
|
128
|
-
app->timeout_counter = 0;
|
|
129
|
-
app->ctl = NULL;
|
|
180
|
+
wr_app_add_error_msg(app);
|
|
130
181
|
wr_app_remove(app->svr, app->conf->name.str);
|
|
131
182
|
}
|
|
132
183
|
return;
|
|
@@ -160,8 +211,8 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
160
211
|
LOG_DEBUG(DEBUG,"Pending_wkr = %d, app->q_workers->q_count = %d",
|
|
161
212
|
WR_QUEUE_SIZE(app->q_pending_workers), WR_QUEUE_SIZE(app->q_workers));
|
|
162
213
|
if(app->q_workers->q_count > app->conf->min_worker) {
|
|
163
|
-
char cmd[
|
|
164
|
-
char pid_list[
|
|
214
|
+
char cmd[STR_SIZE512];
|
|
215
|
+
char pid_list[STR_SIZE512], pid_c[STR_SIZE32];
|
|
165
216
|
int i,index;
|
|
166
217
|
i = 0;
|
|
167
218
|
index = (app->q_workers->q_front + i) % app->q_workers->q_max_size;
|
|
@@ -170,7 +221,7 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
170
221
|
|
|
171
222
|
// Get pid of the worker consuming more resident memory
|
|
172
223
|
#ifdef __APPLE__
|
|
173
|
-
//sprintf(cmd,"ps -o pid -m -p %s | head -n2 | tail -n1 | cut -c-6 > %s",pid_list,
|
|
224
|
+
//sprintf(cmd,"ps -o pid -m -p %s | head -n2 | tail -n1 | cut -c-6 > %s",pid_list, Config->Server.File.high_rss.str);
|
|
174
225
|
/* TODO: when any shell command is executed using system(), process goes into wait state. It is
|
|
175
226
|
observed on only Mac. When tried calling syste() at various interval like after port binding,
|
|
176
227
|
controller initialization, forking required worker, daemonizing, activating event loop etc, in all
|
|
@@ -178,7 +229,7 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
178
229
|
goes into infinite wait.
|
|
179
230
|
In this case we would simply pick the first worker from queue and remove it.
|
|
180
231
|
*/
|
|
181
|
-
FILE *wfp = fopen(
|
|
232
|
+
FILE *wfp = fopen(Config->Server.File.high_rss.str, "w");
|
|
182
233
|
if(wfp) {
|
|
183
234
|
fprintf(wfp,"%d", tmp_worker->pid);
|
|
184
235
|
fclose(wfp);
|
|
@@ -193,18 +244,18 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
193
244
|
sprintf(pid_c,",%d", tmp_worker->pid);
|
|
194
245
|
strcat(pid_list, pid_c);
|
|
195
246
|
}
|
|
196
|
-
sprintf(cmd,"ps -o pid --sort=rss -p %s | tail -n1 | cut -c-6 > %s",pid_list,
|
|
247
|
+
sprintf(cmd,"ps -o pid --sort=rss -p %s | tail -n1 | cut -c-6 > %s",pid_list, Config->Server.File.high_rss.str);
|
|
197
248
|
LOG_DEBUG(DEBUG,"Formed command to remove worker is %s",cmd);
|
|
198
249
|
system(cmd);
|
|
199
250
|
#endif
|
|
200
251
|
|
|
201
252
|
// Read pid from file
|
|
202
|
-
FILE *fp = fopen(
|
|
253
|
+
FILE *fp = fopen(Config->Server.File.high_rss.str, "r");
|
|
203
254
|
if(fp) {
|
|
204
255
|
unsigned pid = 0;
|
|
205
256
|
fscanf(fp, "%u", &pid);
|
|
206
257
|
fclose(fp);
|
|
207
|
-
remove(
|
|
258
|
+
remove(Config->Server.File.high_rss.str);
|
|
208
259
|
int flag = 1;
|
|
209
260
|
|
|
210
261
|
// Check for worker in list of free workers. If found remove it.
|
|
@@ -217,7 +268,8 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
217
268
|
if(tmp_worker->pid == pid) {
|
|
218
269
|
LOG_DEBUG(DEBUG,"Removing from free worker id=%d", tmp_worker->id);
|
|
219
270
|
forecasted_count--;
|
|
220
|
-
|
|
271
|
+
tmp_worker->state = WKR_STATE_ERROR;
|
|
272
|
+
wr_wkr_free(tmp_worker);
|
|
221
273
|
LOG_DEBUG(DEBUG,"Worker removed from free worker.");
|
|
222
274
|
flag = 0;
|
|
223
275
|
break;
|
|
@@ -236,8 +288,7 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
236
288
|
if(tmp_worker->pid == pid) {
|
|
237
289
|
forecasted_count--;
|
|
238
290
|
LOG_DEBUG(DEBUG,"Remove active status id = %d", tmp_worker->id);
|
|
239
|
-
|
|
240
|
-
tmp_worker->state -= WR_WKR_ACTIVE;
|
|
291
|
+
tmp_worker->state = WKR_STATE_EXPIRED;
|
|
241
292
|
break;
|
|
242
293
|
}
|
|
243
294
|
}
|
|
@@ -251,37 +302,19 @@ void wr_app_wkr_remove_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|
|
251
302
|
}
|
|
252
303
|
|
|
253
304
|
/** Reload the application */
|
|
254
|
-
|
|
305
|
+
int wr_app_reload(wr_app_t *app){
|
|
255
306
|
LOG_FUNCTION
|
|
256
307
|
wr_wkr_t *worker;
|
|
257
|
-
wr_app_conf_t *app_conf;
|
|
258
308
|
short count;
|
|
259
309
|
|
|
260
310
|
// Remove an old application from the resolver list.
|
|
261
311
|
wr_req_resolver_remove(app->svr, app);
|
|
262
312
|
|
|
263
313
|
// Update the application configuration.
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
app->svr->err_msg);
|
|
267
|
-
if(app_conf == NULL){
|
|
268
|
-
LOG_DEBUG(WARN, "Error: %s",app->svr->err_msg);
|
|
269
|
-
if(app->ctl){
|
|
270
|
-
scgi_body_add(app->ctl->scgi, app->svr->err_msg, strlen(app->svr->err_msg));
|
|
271
|
-
scgi_header_add(app->ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
272
|
-
wr_ctl_resp_write(app->ctl);
|
|
273
|
-
}
|
|
274
|
-
app->state = WR_APP_ACTIVE;
|
|
275
|
-
return FALSE;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Remove old application specification.
|
|
279
|
-
app->conf->next = NULL;
|
|
280
|
-
wr_conf_app_free(app->conf);
|
|
281
|
-
app->conf = app_conf;
|
|
282
|
-
|
|
314
|
+
wr_conf_app_update(app->conf);
|
|
315
|
+
|
|
283
316
|
// Add the updated application to resolver list.
|
|
284
|
-
wr_req_resolver_add(app->svr, app
|
|
317
|
+
wr_req_resolver_add(app->svr, app);
|
|
285
318
|
|
|
286
319
|
// Remove workers based on following logic:
|
|
287
320
|
// If all the workers are free keep a single worker to process the requests and remove all others.
|
|
@@ -291,85 +324,44 @@ static inline int wr_app_reload(wr_app_t *app){
|
|
|
291
324
|
while(WR_QUEUE_SIZE(app->q_free_workers) > 0){
|
|
292
325
|
worker = (wr_wkr_t*)wr_queue_fetch(app->q_free_workers);
|
|
293
326
|
// The worker is already removed from free workers list so do not pass the flag.
|
|
294
|
-
|
|
327
|
+
worker->state = WKR_STATE_ERROR;
|
|
328
|
+
wr_wkr_free(worker);
|
|
295
329
|
}
|
|
296
330
|
|
|
297
331
|
// Mark all existing workers to OLD worker.
|
|
298
332
|
for(count = 0; count < WR_QUEUE_SIZE(app->q_workers) ; count++) {
|
|
299
333
|
worker = (wr_wkr_t*)wr_queue_fetch(app->q_workers);
|
|
300
334
|
wr_queue_insert(app->q_workers, worker);
|
|
301
|
-
worker->state
|
|
302
|
-
worker->state -= WR_WKR_ACTIVE;
|
|
335
|
+
worker->state = WKR_STATE_EXPIRED;
|
|
303
336
|
}
|
|
304
337
|
|
|
305
338
|
app->state = WR_APP_RESTARTING;
|
|
306
339
|
return TRUE;
|
|
307
340
|
}
|
|
308
341
|
|
|
309
|
-
/*************** Application function definition *********/
|
|
310
|
-
|
|
311
|
-
/** Destroy application */
|
|
312
|
-
void wr_app_free(wr_app_t* app) {
|
|
313
|
-
LOG_FUNCTION
|
|
314
|
-
wr_app_t* tmp_app;
|
|
315
|
-
wr_wkr_t* worker;
|
|
316
|
-
|
|
317
|
-
while(app) {
|
|
318
|
-
tmp_app = app->next;
|
|
319
|
-
app->state = WR_APP_DESTROY;
|
|
320
|
-
LOG_DEBUG(4,"Destroying application %s...", app->conf->name.str);
|
|
321
|
-
LOG_DEBUG(DEBUG,"Worker count = %d", WR_QUEUE_SIZE(app->q_workers));
|
|
322
|
-
//Destroy workers
|
|
323
|
-
while(worker = (wr_wkr_t*)wr_queue_fetch(app->q_workers)) {
|
|
324
|
-
if(app->svr->is_running==0)
|
|
325
|
-
worker->state |= WR_WKR_HANG;
|
|
326
|
-
wr_wkr_free(worker);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
wr_queue_free(app->q_free_workers);
|
|
330
|
-
wr_queue_free(app->q_workers);
|
|
331
|
-
wr_queue_free(app->q_pending_workers);
|
|
332
|
-
|
|
333
|
-
wr_req_t *req;
|
|
334
|
-
WR_QUEUE_FETCH(app->q_messages, req) ;
|
|
335
|
-
while(req) {
|
|
336
|
-
wr_conn_err_resp(req->conn, WR_HTTP_STATUS_500);
|
|
337
|
-
WR_QUEUE_FETCH(app->q_messages, req) ;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
wr_queue_free(app->q_messages);
|
|
341
|
-
|
|
342
|
-
wr_req_resolver_remove(app->svr, app);
|
|
343
|
-
|
|
344
|
-
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_add);
|
|
345
|
-
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_remove);
|
|
346
|
-
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_add_timeout);
|
|
347
|
-
|
|
348
|
-
free(app);
|
|
349
|
-
app = tmp_app;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/** Display application structure */
|
|
354
|
-
void wr_app_print(wr_app_t*app) {
|
|
355
|
-
while(app) {
|
|
356
|
-
LOG_DEBUG(4,"Application %s", app->conf->name.str);
|
|
357
|
-
app = app->next;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
342
|
/** Create worker for application */
|
|
362
343
|
int wr_app_wkr_add(wr_app_t *app) {
|
|
363
344
|
if(WR_QUEUE_SIZE(app->q_pending_workers) < WR_QUEUE_MAX_SIZE(app->q_pending_workers)) {
|
|
364
|
-
|
|
345
|
+
if(app->timeout_counter >= Config->Server.Worker.add_trials){
|
|
346
|
+
LOG_ERROR(SEVERE, "Could not fork worker because previous %d workers got timed out.",
|
|
347
|
+
Config->Server.Worker.add_trials);
|
|
348
|
+
return FALSE;
|
|
349
|
+
}
|
|
350
|
+
config_application_list_t *conf = app->conf;
|
|
351
|
+
|
|
352
|
+
if(app->state == WR_APP_RESTART) conf = app->conf->new;
|
|
353
|
+
|
|
354
|
+
int retval = wr_wkr_create(app->svr, conf);
|
|
365
355
|
if(retval > 0){
|
|
366
356
|
wr_pending_wkr_t *pending = wr_malloc(wr_pending_wkr_t);
|
|
367
357
|
*pending = retval;
|
|
368
358
|
wr_queue_insert(app->q_pending_workers, pending);
|
|
369
|
-
app->high_ratio = TOTAL_WORKER_COUNT(app) *
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
359
|
+
app->high_ratio = TOTAL_WORKER_COUNT(app) * Config->Application.max_req_ratio;
|
|
360
|
+
if (Config->Server.Worker.add_timeout > 0) {
|
|
361
|
+
ev_timer_again(app->svr->ebb_svr.loop, &app->t_add_timeout);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
LOG_INFO("PID of created worker = %d", retval);
|
|
373
365
|
return TRUE;
|
|
374
366
|
}else{
|
|
375
367
|
LOG_ERROR(SEVERE,"Could not fork process to start new worker.");
|
|
@@ -379,23 +371,23 @@ int wr_app_wkr_add(wr_app_t *app) {
|
|
|
379
371
|
}
|
|
380
372
|
|
|
381
373
|
/** Insert application based on application configuration */
|
|
382
|
-
|
|
374
|
+
int wr_app_insert(wr_svr_t* server, config_application_list_t* config, wr_ctl_t *ctl) {
|
|
383
375
|
LOG_FUNCTION
|
|
384
376
|
wr_app_t* app = wr_malloc(wr_app_t);
|
|
385
|
-
|
|
377
|
+
|
|
386
378
|
if(!app) {
|
|
387
379
|
LOG_ERROR(WARN, "%s() application object allocation failed. Returning ...", __FUNCTION__);
|
|
388
380
|
return FALSE;
|
|
389
381
|
}
|
|
390
|
-
|
|
391
|
-
// Queue size is
|
|
382
|
+
|
|
383
|
+
// Queue size is Config->Server.Worker.max + 1 to accommodate temporary extra
|
|
392
384
|
// worker, created during application restart
|
|
393
|
-
app->q_free_workers = wr_queue_new(
|
|
394
|
-
app->q_workers = wr_queue_new(
|
|
395
|
-
app->q_pending_workers = wr_queue_new(
|
|
396
|
-
|
|
397
|
-
app->q_messages = wr_queue_new(
|
|
398
|
-
|
|
385
|
+
app->q_free_workers = wr_queue_new(Config->Server.Worker.max + 1);
|
|
386
|
+
app->q_workers = wr_queue_new(Config->Server.Worker.max + 1);
|
|
387
|
+
app->q_pending_workers = wr_queue_new(Config->Server.Worker.pending);
|
|
388
|
+
|
|
389
|
+
app->q_messages = wr_queue_new(Config->Application.msg_queue_size);
|
|
390
|
+
|
|
399
391
|
if(app->q_workers == NULL || app->q_pending_workers == NULL ||
|
|
400
392
|
app->q_free_workers == NULL || app->q_messages == NULL) {
|
|
401
393
|
free(app);
|
|
@@ -415,19 +407,21 @@ static int wr_app_insert(wr_svr_t* server, wr_app_conf_t* config, wr_ctl_t *ctl)
|
|
|
415
407
|
/* set application object in control, it would be used at time of freeing control object */
|
|
416
408
|
if(ctl) ctl->app = app;
|
|
417
409
|
|
|
418
|
-
if(strcmp(config->name.str,
|
|
410
|
+
if(strcmp(config->name.str, Config->Application.Static_server.name.str) == 0){
|
|
419
411
|
app->next = NULL;
|
|
420
412
|
server->static_app = app;
|
|
421
413
|
}else{
|
|
422
|
-
wr_req_resolver_add(server, app
|
|
414
|
+
wr_req_resolver_add(server, app);
|
|
423
415
|
app->next = server->apps;
|
|
424
416
|
server->apps = app;
|
|
425
417
|
}
|
|
426
|
-
|
|
427
|
-
ev_timer_init (&app->t_add, wr_app_wkr_add_cb, 0.,
|
|
428
|
-
ev_timer_init (&app->t_remove, wr_app_wkr_remove_cb, 0.,
|
|
429
|
-
|
|
430
|
-
|
|
418
|
+
|
|
419
|
+
ev_timer_init (&app->t_add, wr_app_wkr_add_cb, 0., Config->Application.high_load);
|
|
420
|
+
ev_timer_init (&app->t_remove, wr_app_wkr_remove_cb, 0., Config->Application.low_load);
|
|
421
|
+
if (Config->Server.Worker.add_timeout > 0) {
|
|
422
|
+
ev_timer_init (&app->t_add_timeout, wr_app_wkr_add_timeout_cb, 0., Config->Server.Worker.add_timeout);
|
|
423
|
+
}
|
|
424
|
+
|
|
431
425
|
LOG_DEBUG(4,"%s() Application Added:%s", __FUNCTION__, config->name.str);
|
|
432
426
|
|
|
433
427
|
wr_app_wkr_balance(app);
|
|
@@ -435,17 +429,73 @@ static int wr_app_insert(wr_svr_t* server, wr_app_conf_t* config, wr_ctl_t *ctl)
|
|
|
435
429
|
return TRUE;
|
|
436
430
|
}
|
|
437
431
|
|
|
432
|
+
/*************** Application function definition *********/
|
|
433
|
+
|
|
434
|
+
/** Destroy application */
|
|
435
|
+
void wr_app_free(wr_app_t* app) {
|
|
436
|
+
LOG_FUNCTION
|
|
437
|
+
wr_app_t* tmp_app;
|
|
438
|
+
wr_wkr_t* worker;
|
|
439
|
+
|
|
440
|
+
while(app) {
|
|
441
|
+
tmp_app = app->next;
|
|
442
|
+
app->state = WR_APP_DESTROY;
|
|
443
|
+
LOG_DEBUG(4,"Destroying application %s...", app->conf->name.str);
|
|
444
|
+
LOG_DEBUG(DEBUG,"Worker count = %d", WR_QUEUE_SIZE(app->q_workers));
|
|
445
|
+
//Destroy workers
|
|
446
|
+
while(worker = (wr_wkr_t*)wr_queue_fetch(app->q_workers)) {
|
|
447
|
+
if(app->svr->is_running == 0)
|
|
448
|
+
worker->state = WKR_STATE_ERROR;
|
|
449
|
+
wr_wkr_free(worker);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
wr_queue_free(app->q_free_workers);
|
|
453
|
+
wr_queue_free(app->q_workers);
|
|
454
|
+
wr_queue_free(app->q_pending_workers);
|
|
455
|
+
|
|
456
|
+
wr_req_t *req;
|
|
457
|
+
WR_QUEUE_FETCH(app->q_messages, req) ;
|
|
458
|
+
while(req) {
|
|
459
|
+
wr_conn_err_resp(req->conn, WR_HTTP_STATUS_500);
|
|
460
|
+
WR_QUEUE_FETCH(app->q_messages, req) ;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
wr_queue_free(app->q_messages);
|
|
464
|
+
|
|
465
|
+
wr_req_resolver_remove(app->svr, app);
|
|
466
|
+
|
|
467
|
+
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_add);
|
|
468
|
+
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_remove);
|
|
469
|
+
if (Config->Server.Worker.add_timeout > 0) {
|
|
470
|
+
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_add_timeout);
|
|
471
|
+
}
|
|
472
|
+
free(app);
|
|
473
|
+
app = tmp_app;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/** Display application structure */
|
|
478
|
+
void wr_app_print(wr_app_t*app) {
|
|
479
|
+
while(app) {
|
|
480
|
+
LOG_DEBUG(4,"Application %s", app->conf->name.str);
|
|
481
|
+
app = app->next;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
438
485
|
/** Balance number of workers */
|
|
439
486
|
void wr_app_wkr_balance(wr_app_t *app){
|
|
440
487
|
// Maintain minimum number of workers
|
|
441
|
-
//while(TOTAL_WORKER_COUNT(app) < app->conf->min_worker && app->timeout_counter <
|
|
488
|
+
//while(TOTAL_WORKER_COUNT(app) < app->conf->min_worker && app->timeout_counter < Config->Server.Worker.add_trials){
|
|
442
489
|
while(TOTAL_WORKER_COUNT(app) < app->conf->min_worker){
|
|
443
490
|
if(wr_app_wkr_add(app) == FALSE) break;
|
|
444
|
-
app->low_ratio = TOTAL_WORKER_COUNT(app) *
|
|
491
|
+
app->low_ratio = TOTAL_WORKER_COUNT(app) * Config->Application.min_req_ratio;
|
|
445
492
|
}
|
|
446
493
|
|
|
447
|
-
if(WR_QUEUE_SIZE(app->q_workers) >= app->conf->min_worker && app->state == WR_APP_RESTART)
|
|
448
|
-
app->state
|
|
494
|
+
if(WR_QUEUE_SIZE(app->q_workers) >= app->conf->min_worker && app->state == WR_APP_RESTART){
|
|
495
|
+
app->state = WR_APP_ACTIVE;
|
|
496
|
+
wr_application_list_free(app->conf->new);
|
|
497
|
+
app->conf->new = NULL;
|
|
498
|
+
}
|
|
449
499
|
|
|
450
500
|
// Create worker if application is high loaded
|
|
451
501
|
/*
|
|
@@ -455,6 +505,37 @@ void wr_app_wkr_balance(wr_app_t *app){
|
|
|
455
505
|
*/
|
|
456
506
|
}
|
|
457
507
|
|
|
508
|
+
/** Got worker add error */
|
|
509
|
+
int wr_app_wkr_error(wr_svr_t *server, const wr_ctl_msg_t *ctl_msg) {
|
|
510
|
+
LOG_FUNCTION
|
|
511
|
+
const char* app_name = ctl_msg->msg.wkr.app_name.str;
|
|
512
|
+
wr_app_t* app = wr_app_exist(server, app_name);
|
|
513
|
+
|
|
514
|
+
if(app == NULL){
|
|
515
|
+
return -1;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if(app->state == WR_APP_RESTART){
|
|
519
|
+
app->state = WR_APP_ACTIVE;
|
|
520
|
+
wr_application_list_free(app->conf->new);
|
|
521
|
+
app->conf->new = NULL;
|
|
522
|
+
// Send error response
|
|
523
|
+
wr_app_add_error_msg(app);
|
|
524
|
+
}else if(app->state == WR_APP_NEW){
|
|
525
|
+
// Send error response
|
|
526
|
+
wr_app_add_error_msg(app);
|
|
527
|
+
wr_app_remove(app->svr, app->conf->name.str);
|
|
528
|
+
}else{
|
|
529
|
+
wr_pending_wkr_t *pending = wr_pending_worker_exist(app, atoi(ctl_msg->msg.wkr.pid.str));
|
|
530
|
+
if(pending != NULL) free(pending);
|
|
531
|
+
app->timeout_counter = 0;
|
|
532
|
+
|
|
533
|
+
if(WR_QUEUE_SIZE(app->q_pending_workers) <= 0 && Config->Server.Worker.add_timeout > 0)
|
|
534
|
+
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_add_timeout);
|
|
535
|
+
}
|
|
536
|
+
return 0;
|
|
537
|
+
}
|
|
538
|
+
|
|
458
539
|
/** Add newly created worker to application */
|
|
459
540
|
int wr_app_wkr_insert(wr_svr_t *server, wr_wkr_t *worker,const wr_ctl_msg_t *ctl_msg) {
|
|
460
541
|
LOG_FUNCTION
|
|
@@ -478,15 +559,16 @@ int wr_app_wkr_insert(wr_svr_t *server, wr_wkr_t *worker,const wr_ctl_msg_t *ctl
|
|
|
478
559
|
scgi_body_add(worker->ctl->scgi, "Either worker add timeout or worker PID does not match.",
|
|
479
560
|
strlen("Either worker add timeout or worker PID does not match."));
|
|
480
561
|
return -1;
|
|
562
|
+
}else{
|
|
563
|
+
free(pending);
|
|
481
564
|
}
|
|
482
565
|
|
|
483
566
|
worker->id = ++worker_count;
|
|
484
567
|
worker->app = app;
|
|
485
|
-
|
|
486
|
-
|
|
568
|
+
|
|
487
569
|
app->timeout_counter = 0;
|
|
488
570
|
|
|
489
|
-
if(WR_QUEUE_SIZE(app->q_pending_workers) <= 0)
|
|
571
|
+
if(WR_QUEUE_SIZE(app->q_pending_workers) <= 0 && Config->Server.Worker.add_timeout > 0)
|
|
490
572
|
ev_timer_stop(app->svr->ebb_svr.loop, &app->t_add_timeout);
|
|
491
573
|
|
|
492
574
|
if(app->state == WR_APP_RESTART){
|
|
@@ -516,37 +598,6 @@ int wr_app_wkr_insert(wr_svr_t *server, wr_wkr_t *worker,const wr_ctl_msg_t *ctl
|
|
|
516
598
|
return -1;
|
|
517
599
|
}
|
|
518
600
|
|
|
519
|
-
/** Remove application from application list */
|
|
520
|
-
int wr_app_remove(wr_svr_t* server, const char* app_name) {
|
|
521
|
-
LOG_FUNCTION
|
|
522
|
-
wr_app_t* app = server->apps, *tmp_app = NULL;
|
|
523
|
-
|
|
524
|
-
LOG_DEBUG(DEBUG, "Removing application %s", app_name);
|
|
525
|
-
|
|
526
|
-
while(app) {
|
|
527
|
-
if(strcmp(app_name, app->conf->name.str)==0)
|
|
528
|
-
break;
|
|
529
|
-
tmp_app = app;
|
|
530
|
-
app = app->next;
|
|
531
|
-
}
|
|
532
|
-
if(app) {
|
|
533
|
-
if(tmp_app) {
|
|
534
|
-
tmp_app->next = app->next;
|
|
535
|
-
} else {
|
|
536
|
-
server->apps = app->next;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
app->next = NULL;
|
|
540
|
-
wr_app_free(app);
|
|
541
|
-
wr_app_conf_remove(server->conf, app_name);
|
|
542
|
-
return 0;
|
|
543
|
-
} else {
|
|
544
|
-
LOG_ERROR(WARN,"Aapplication %s didn't found in list", app_name);
|
|
545
|
-
sprintf(server->err_msg, "Application '%s' is not found.", app_name);
|
|
546
|
-
return -1;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
|
|
550
601
|
/** Check load balance to add the worker */
|
|
551
602
|
void wr_app_chk_load_to_add_wkr(wr_app_t *app) {
|
|
552
603
|
if(TOTAL_WORKER_COUNT(app) < app->conf->max_worker) {
|
|
@@ -581,7 +632,7 @@ void wr_app_chk_load_to_remove_wkr(wr_app_t *app) {
|
|
|
581
632
|
/** Initialize the applications */
|
|
582
633
|
void wr_app_init(wr_svr_t *server) {
|
|
583
634
|
LOG_FUNCTION
|
|
584
|
-
|
|
635
|
+
config_application_list_t *app = Config->Application.list;
|
|
585
636
|
|
|
586
637
|
while(app) {
|
|
587
638
|
wr_app_insert(server, app, NULL);
|
|
@@ -595,7 +646,7 @@ void wr_app_add_cb(wr_ctl_t *ctl, const wr_ctl_msg_t *ctl_msg) {
|
|
|
595
646
|
LOG_FUNCTION
|
|
596
647
|
|
|
597
648
|
wr_svr_t* server = ctl->svr;
|
|
598
|
-
|
|
649
|
+
config_application_list_t* app_conf = NULL;
|
|
599
650
|
wr_app_t* app = wr_app_exist(server, ctl_msg->msg.app.app_name.str);
|
|
600
651
|
|
|
601
652
|
// Reset the error message
|
|
@@ -604,10 +655,9 @@ void wr_app_add_cb(wr_ctl_t *ctl, const wr_ctl_msg_t *ctl_msg) {
|
|
|
604
655
|
/* set application object in control, it would be used at time of freeing control object */
|
|
605
656
|
ctl->app = app;
|
|
606
657
|
sprintf(ctl->svr->err_msg, "Application '%s' is already running.", ctl_msg->msg.app.app_name.str);
|
|
607
|
-
}else if(ctl && server
|
|
608
|
-
app_conf = wr_conf_app_read(
|
|
609
|
-
|
|
610
|
-
ctl->svr->err_msg);
|
|
658
|
+
}else if(ctl && server) {
|
|
659
|
+
app_conf = wr_conf_app_read(ctl_msg->msg.app.app_name.str,
|
|
660
|
+
ctl->svr->err_msg, FALSE);
|
|
611
661
|
if(app_conf!=NULL) {
|
|
612
662
|
if(wr_app_insert(ctl->svr, app_conf, ctl) == TRUE) return;
|
|
613
663
|
} else if(ctl->svr->err_msg[0] == 0) {
|
|
@@ -635,64 +685,72 @@ void wr_app_remove_cb(wr_ctl_t *ctl, const wr_ctl_msg_t *ctl_msg) {
|
|
|
635
685
|
/** Allication reload callback */
|
|
636
686
|
void wr_app_reload_cb(wr_ctl_t *ctl, const wr_ctl_msg_t *ctl_msg){
|
|
637
687
|
LOG_FUNCTION
|
|
638
|
-
wr_app_conf_t* app_config = NULL;
|
|
639
688
|
wr_app_t *app = wr_app_exist(ctl->svr, ctl_msg->msg.app.app_name.str);
|
|
640
689
|
|
|
641
|
-
// Read new application configuration.
|
|
642
|
-
app_config = wr_conf_app_update(ctl->svr->conf,
|
|
643
|
-
ctl_msg->msg.app.app_name.str,
|
|
644
|
-
ctl->svr->err_msg);
|
|
645
|
-
|
|
646
|
-
LOG_INFO("Reload the application %s", ctl_msg->msg.app.app_name.str);
|
|
647
|
-
// Report error on not getting the application configuration.
|
|
648
|
-
if(app_config == NULL){
|
|
649
|
-
LOG_ERROR(WARN, "Error: %s",ctl->svr->err_msg);
|
|
650
|
-
scgi_body_add(ctl->scgi, ctl->svr->err_msg, strlen(ctl->svr->err_msg));
|
|
651
|
-
scgi_header_add(ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
652
|
-
wr_ctl_resp_write(ctl);
|
|
653
|
-
// Add old application configuration to server configuration.
|
|
654
|
-
if(app){
|
|
655
|
-
LOG_DEBUG(WARN,"Replace the application configuration with old one.");
|
|
656
|
-
wr_conf_app_replace(app->svr->conf, app->conf);
|
|
657
|
-
}
|
|
658
|
-
return;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
690
|
if(app){
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
//
|
|
665
|
-
|
|
666
|
-
app->
|
|
691
|
+
|
|
692
|
+
LOG_INFO("Reload the application %s", ctl_msg->msg.app.app_name.str);
|
|
693
|
+
// Read new application configuration.
|
|
694
|
+
// Report error on not getting the application configuration.
|
|
695
|
+
if(wr_conf_app_read(ctl_msg->msg.app.app_name.str, ctl->svr->err_msg, TRUE) == NULL){
|
|
696
|
+
LOG_ERROR(WARN, "Error: %s",ctl->svr->err_msg);
|
|
697
|
+
scgi_body_add(ctl->scgi, ctl->svr->err_msg, strlen(ctl->svr->err_msg));
|
|
698
|
+
scgi_header_add(ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
699
|
+
wr_ctl_resp_write(ctl);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
|
|
667
703
|
app->state = WR_APP_RESTART;
|
|
704
|
+
app->timeout_counter = 0;
|
|
668
705
|
while(WR_QUEUE_SIZE(app->q_pending_workers) > 0){
|
|
669
706
|
wr_pending_wkr_t* pending = wr_queue_fetch(app->q_pending_workers);
|
|
670
707
|
free(pending);
|
|
671
708
|
}
|
|
672
709
|
|
|
673
710
|
app->ctl = ctl;
|
|
674
|
-
LOG_DEBUG(4,"%s() Application Added:%s", __FUNCTION__, app->conf->name.str);
|
|
711
|
+
LOG_DEBUG(4,"%s() Application Added:%s", __FUNCTION__, app->conf->new->name.str);
|
|
675
712
|
|
|
676
713
|
// Add single worker with updated application.
|
|
677
714
|
LOG_DEBUG(DEBUG, "Add first worker on application restart.");
|
|
678
|
-
wr_app_wkr_add(app);
|
|
679
|
-
|
|
680
|
-
// Replace the application configuration with older configuration object.
|
|
681
|
-
wr_conf_app_replace(app->svr->conf, tmp_app_conf);
|
|
682
|
-
app->conf = tmp_app_conf;
|
|
715
|
+
wr_app_wkr_add(app);
|
|
683
716
|
return;
|
|
684
717
|
}else{
|
|
685
718
|
// If application didn't found, report an error and create new application.
|
|
686
719
|
LOG_ERROR(WARN,"Aapplication %s didn't found in list", ctl_msg->msg.app.app_name.str);
|
|
687
720
|
sprintf(ctl->svr->err_msg, "Application '%s' is not found.", ctl_msg->msg.app.app_name.str);
|
|
688
|
-
scgi_body_add(ctl->scgi,
|
|
689
|
-
"Couldn't remove application. But trying to start application.",
|
|
721
|
+
scgi_body_add(ctl->scgi, "Couldn't remove application. But trying to start application.",
|
|
690
722
|
strlen("Couldn't remove application. But trying to start application."));
|
|
691
|
-
|
|
723
|
+
|
|
724
|
+
config_application_list_t *app_config = wr_conf_app_read(ctl_msg->msg.app.app_name.str, ctl->svr->err_msg, FALSE);
|
|
725
|
+
if(app_config){
|
|
726
|
+
if(wr_app_insert(ctl->svr, app_config, ctl) == TRUE) return;
|
|
727
|
+
}else{
|
|
728
|
+
LOG_ERROR(WARN, "Error: %s",ctl->svr->err_msg);
|
|
729
|
+
scgi_body_add(ctl->scgi, ctl->svr->err_msg, strlen(ctl->svr->err_msg));
|
|
730
|
+
}
|
|
692
731
|
}
|
|
693
732
|
|
|
694
733
|
// Return ERROR status.
|
|
695
734
|
scgi_header_add(ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
696
735
|
wr_ctl_resp_write(ctl);
|
|
697
736
|
}
|
|
698
|
-
|
|
737
|
+
|
|
738
|
+
/** Application configuration requset */
|
|
739
|
+
void wr_app_conf_req_cb(wr_ctl_t *ctl, const wr_ctl_msg_t *ctl_msg){
|
|
740
|
+
config_application_list_t* app_conf = NULL;
|
|
741
|
+
wr_app_t* app = wr_app_exist(ctl->svr, ctl_msg->msg.app.app_name.str);
|
|
742
|
+
|
|
743
|
+
if(app && app->conf->scgi){
|
|
744
|
+
scgi_build(ctl->scgi);
|
|
745
|
+
scgi_free(ctl->scgi);
|
|
746
|
+
ctl->destroy_scgi = FALSE;
|
|
747
|
+
if(app->state == WR_APP_RESTART){
|
|
748
|
+
ctl->scgi = app->conf->new->scgi;
|
|
749
|
+
}else{
|
|
750
|
+
ctl->scgi = app->conf->scgi;
|
|
751
|
+
}
|
|
752
|
+
}else{
|
|
753
|
+
scgi_header_add(ctl->scgi, "STATUS", strlen("STATUS"), "ERROR", strlen("ERROR"));
|
|
754
|
+
}
|
|
755
|
+
wr_ctl_resp_write(ctl);
|
|
756
|
+
}
|