webroar 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|